Action Descriptor
One of the next steps for providing a comprehensive documentation is to add some clear information on all the actions shipped with the Wikka package (how to use them, what parameters they accept etc.).
I've written a simple "metaction" that retrieves automatically the list of actions stored in the actions/ folder and displays their description. This might save a lot of future work to keep infos updated since the action generates on-the-fly all the existing descriptions.
Here's the two-step implementation:
1. Add descriptions to action files
The idea came from JavaWoman's use of phpDocumentor headers in her code.
To make action infos retrievable we just need to add a basic header like the following in every action:
<?php
/*
* Title:
* COFFEE
*
* Source:
* actions/coffee.php
*
* Description:
* This action prepares a cup of great coffee every morning at 7:00 am
*
* Usage:
* {{coffee sugar="value"}}
*
* Parameters:
* sugar (int): specifies the number of spoonfuls of sugar. No value produces black coffee without sugar
*/
// action code follows
echo blablabla;
echo blablabla;
echo blablabla;
echo blablabla;
echo blablabla;
?>
/*
* Title:
* COFFEE
*
* Source:
* actions/coffee.php
*
* Description:
* This action prepares a cup of great coffee every morning at 7:00 am
*
* Usage:
* {{coffee sugar="value"}}
*
* Parameters:
* sugar (int): specifies the number of spoonfuls of sugar. No value produces black coffee without sugar
*/
// action code follows
echo blablabla;
echo blablabla;
echo blablabla;
echo blablabla;
echo blablabla;
?>
We might consider allowing some basic phpDocumentor tags.
2. Create a parser to retrieve and print descriptions
The following action get the files stored in the actions/ folder, extracts action descriptions and prints them. I've set the character limit to 600, but this can be changed.
Save the following code as actions/actionlist.php and use it as {{actionlist}}
<?php
/*
* Title:
* ACTION LIST
*
* Source:
* actions/actionlist.php
*
* Description:
* Displays a list of available actions with their description
*
* Usage:
* {{actionlist}}
*
* Parameters:
* none
*/
echo $this->Format("=== List of available actions === --- ");
$handle = opendir('actions/');
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo $this->Format("**".substr($file, 0, -4)."** --- ");
$fd = fopen("actions/".$file, "r");
$contents = fread ($fd, "600");
if (ereg( "(/\*)(.+)(\*/)", $contents, $desc)) {
$desc[0] = preg_replace("((/\*)|(\*/)|(\n\*))", "\n", $desc[0]);
echo $this->Format("@@".$contents."@@ --- ");
// Please replace in the previous line @@ with two % signs.
// Couldn't do it in a wikka highlighted code block!
}
fclose($file);
}
}
closedir($handle);
?>
/*
* Title:
* ACTION LIST
*
* Source:
* actions/actionlist.php
*
* Description:
* Displays a list of available actions with their description
*
* Usage:
* {{actionlist}}
*
* Parameters:
* none
*/
echo $this->Format("=== List of available actions === --- ");
$handle = opendir('actions/');
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo $this->Format("**".substr($file, 0, -4)."** --- ");
$fd = fopen("actions/".$file, "r");
$contents = fread ($fd, "600");
if (ereg( "(/\*)(.+)(\*/)", $contents, $desc)) {
$desc[0] = preg_replace("((/\*)|(\*/)|(\n\*))", "\n", $desc[0]);
echo $this->Format("@@".$contents."@@ --- ");
// Please replace in the previous line @@ with two % signs.
// Couldn't do it in a wikka highlighted code block!
}
fclose($file);
}
}
closedir($handle);
?>
The output will look like the following:
actionlist
Title: ACTION LIST Source: actions/actionlist.php Description: Displays a list of available actions with their description Usage: {{actionlist}} Parameters: none
(...)
coffee
Title: COFFEE Source: actions/coffee.php Description: This action prepares a cup of great coffee every morning at 7:00 am Usage: {{coffee sugar="value"}} Parameters: sugar (int): specifies the number of spoonfuls of sugar. No value produces black coffee without sugar
color
Title: COLOR ...
(...)
-- DarTar
DarTar, thanks for stealing my idea! :)
When releasing my WikkaEmailToolkit code, I wanted to make sure it was "properly" documented. I was aware of the existence of "phpDoc", had come across examples, and they looked familiar. Guess why? Consider my alias here, JavaWoman. Although I don't do Java anymore, I did once. I also did quite a bit of Smalltalk, later, in a previous life. And occasionally I did, and do, Perl. Anyway, I know phpDoc (and the phpDocumentor implementation) was based on JavaDoc. Which itself was based on .... well, a few days ago I was discussing the idea of documenting PHP code with a colleague over IM, both of us Googling while we talked. Both of us coming up with JavaDoc (of course). And then he mentioned AutoDoc ... ah, yes, now where did I come across that before? Google a bit and you'll see.
Anyway, this way of making "self-documenting code" is really very old already; its basic syntax is familiar to many programmers, and many tools exist that can make (some) sense of it.
So yes, I also thought that actions should be documented in a similar way. But not in a different way!
My reaction is simply: thanks for coming up with the idea - think about it and it's self-evident - but why reinvent the wheel?The wheel has been invented already and it's quite efficient and mature.
You say: "We might consider allowing some basic phpDocumentor tags."
I'd say: Just write standard phpDocumentor code, and use some of its basic tags for a limited version.
That has two advantages:
- The idea and even the syntax is already familiar to many programmers
- The documentation blocks can be used by both a "local" Wikka "documentor" and phpDocumentor (which could put things in a larger context than merely a list of action descriptions).
- It might actually interfere with phpDocumentor.
The difference between your docblocks and the phpDoc syntax is subtle, and might easily be overlooked. In actual phpDoc syntax a block starts with /** (note there are two stars), then has a number of lines each starting with a single star, and is ended by */. Such a block would be handled by your little parser - but merely reproduce the phpDoc descriptions and tags. On the other hand, just adding that single star to the first line of the block (no problem for your proposed parser) would cause it to be parsed by phpDoc as well - but producing nothing but "description", not structured documentation.
Instead, I would propose a "little parser" that makes use of a basic subset of phpDoc tags (while igonring others!), so that a local documentation set could be produced quickly, while the same documentation block for phpDoc (with optionally a longer description and more tags) would produce structured and cross-referenced documentation when run through phpDocumentor.
I haven't tried this yet (though I intended to do that already)... But as I understand it, a separate file for phpDocumentor is a "package"; while an action in Wikka is sort of a "procedure": something you tell to "do" something, possibly with a set of parameters. (A "procedure" is a somewhat different concept than a "function"; some programming languages treat them as the same thing, but not all do - PHP doesn't but I grew up with languages that did.) So for phpDocumentor to process documentation for an action, you'd have at least a @package tag which names the thing; you'd also have a short description; and you'd have a number of @param tags (where you specify type, name, required/optional and purpose of each). I think that would work - and it would essentially cover all you propose. You can (with phpDocumentor) even "invent" your own tags, so you could add, say, a @usage tag.
I'd want a little time to play with this (using phpDocumentor for actions)... but essentially my reaction is:
Great idea - but don't reinvent the wheel: reuse it!
-- JavaWoman
Challenge taken up - and actually these few lines of code were just meant to be an example, not a real proposal for yet-another-documentation-syntax. I personally welcome the possibility of phpdoc compliant headers in wikka, but keep in mind that one of the priorities of this wiki engine is its lightness. I'm not sure Jason would be happy to see a phpdoc class larger than the rest of the wiki engine ;p If there is a way to adapt a subset of phpdoc scripts as a light wikka action, why not give it a try...
Jason, your opinion?
-- DarTar
I think you could easily parse out just a small subset of phpDoc tags (plus the short description which should be at the start anyway) and maintain the Wikka "lightness" that, without necessarily forbidding other phpDoc documentation or hindering phpDocumentor from coming up with its highly useful cross-referenced documentation. (But I think you should forget about re-using phpDocumentor code, it's doing a *lot* that you don't want anyway.)
Comments by themselves do add (marginally) to execution speed (PHP has to read in the code) but there are solutions for that - while the fact that the Wikka code is already well-documented was one of the reasons for me to try this over other Wiki flavors. Open source without any documentation is just a guessing game.
I'll try to make a docblock tomorrow (oops.. later today!) for one action file I'm working on anyway, and see what would be needed at minimum for both parsers to come up with useful docs from that (and in combination with what phpDocumentor does now with my version of wikka.php). More later...
Much later...
That took more time than I had anticipated since I'm still learning how to work with phpDocumentor. My initial idea of simply specifying @package and @param tags turned out not to work work: @param is for function parameters only and in a docBlock for a procedural page it's simply ignored. As I mentioned, you can tell phpDocumentor to parse your own tags as well - which works, but only as long as those user-defined tagnames do not begin with an already-existing tagname. I tried @parameter and it didn't work. What I came up with was using @input and @output; then for @input use the same syntax as for @param (type, name, description) and for @output just a description.
Here's a sample (for my version of feedback.php - a complete rewrite I'm still working on in combination with the email toolkit) that should work with both phpDocumentor and a "WikkaDocumentor" you might come up with:
<?php
/**
* Displays a form to send feedback to the site administrator, as specified in wakka.config.php.
*
* This action first validates the form; then re-displays the form if an error was found
* or emails the content to the Admin using the WikkaMail() wrapper for PHP's mail().
*
* @package Actions
* @name feedback
*
* @author {@link http://wikka.jsnx.com/JavaWoman JavaWoman}
* @copyright Copyright © 2004, Marjolein Katsma
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @version 0.5
*
* @input boolean $disp
* optional: determines whether input will be shown after mail was successfully sent;
* default: FALSE
* @input string $fb
* optional: name of a WikiPage set up specifically to allow feedback;
* default: Wakka::$config['feedback_page']
* @input integer $format
* optional: email format to be used for validation;
* default: Wakka::$config['email_format']
* @output email form or result of sending email
*
* @uses Wakka::$config ['wiki_master_name'] the name of the "WikiMaster' or Admin (optional)
* @uses Wakka::$config ['feedback_page'] the name of a "FeedBack" page (optional)
* @uses Wakka::$config ['email_format'] specifies an email format (optional)
* @uses Wakka::WikkaMail() to send the mail
* @todo Lots...
*/
>?
/**
* Displays a form to send feedback to the site administrator, as specified in wakka.config.php.
*
* This action first validates the form; then re-displays the form if an error was found
* or emails the content to the Admin using the WikkaMail() wrapper for PHP's mail().
*
* @package Actions
* @name feedback
*
* @author {@link http://wikka.jsnx.com/JavaWoman JavaWoman}
* @copyright Copyright © 2004, Marjolein Katsma
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @version 0.5
*
* @input boolean $disp
* optional: determines whether input will be shown after mail was successfully sent;
* default: FALSE
* @input string $fb
* optional: name of a WikiPage set up specifically to allow feedback;
* default: Wakka::$config['feedback_page']
* @input integer $format
* optional: email format to be used for validation;
* default: Wakka::$config['email_format']
* @output email form or result of sending email
*
* @uses Wakka::$config ['wiki_master_name'] the name of the "WikiMaster' or Admin (optional)
* @uses Wakka::$config ['feedback_page'] the name of a "FeedBack" page (optional)
* @uses Wakka::$config ['email_format'] specifies an email format (optional)
* @uses Wakka::WikkaMail() to send the mail
* @todo Lots...
*/
>?
Description:
- the first line is the short description; I'd suggest you use that
- the next lines until the first tag are the long description - use if you like
- @package Action groups procedural files that have this defined together in a "package" named Actions; you could do similar for Formatters, etc.; not sure if you could use it
- @name serves as an alias for the procedural file so you'd see "feedback" in phpDocumentor's output, rather than "feedback.php"; you might be able to use this, but when you're parsing a file you have teh file path and name already anyway.
- the next block with @author, copyright, @license and @version can probably be igored in this context (phpDocumentor will use them, of course)
- @input describes an input parameter: type, name, description; where description should mention:
- optional or required
- function
- default in the case of an optional parameter
- @output is just a description of what kind of output the action produces (calling it type "string" seems futile so I departed from the @return syntax here)
- the user-defined tags @input and @output are displayed as simple text by phpDocumentor, but should both be parsed by teh WikkaDocumentor; for @input tags a little table (type, name, required, description, default) would probably be nice; I imagine one could use multiple @ouput tags to describe what would be produced under different conditions
- @uses is used by phpDocumentor to create a two-way crossreference link between elements: extremely useful but your parser should ignore it
- @todo - what it says (phpDocumentor uses this to create a nice Todo list); can also be ignored
How does that sound?
-- JavaWoman
Taking it from a partly off-topic comment and adding it here, so it won't get lost in the heat of discussion:
Part of the documentation for each action needs to be whether it can occur multiple times on a page - and under which conditions; this will probably (partly) depend on action parameters but I haven't quite thought this through yet. (Possibly actions that *can* occur multiple times will need to have a required attribute that enables a unique id to be generated. Or something...)
Definitely there are some actions that can occur only once (e.g., the "form handler" actions!) so this will need to be documented.
I'll have to think about whether that would require an extra @tag - ideas?
--JavaWoman
@JW
A late commentary (apologies) on your proposal. My opinion? The sample description you gave above is excellent for a developer, but it's totally ununderstandable (I guess) for the average user.
Remember that users that might be interested to understand how actions work are not restricted to wiki administrators.
Imagine I've read somewhere that I can use an action to display a Google form in wikka pages. "That'd be great, it's something I've always dreamt of seeing in my wiki pages". Now, I check the documentation to see how to use this action and I find a phpdoc-compliant description like yours. See the point? :-)
I guess a rigorous and phpdoc-compliant documentation should be written for portions of code relevant for developers (the wikka core, formatters and handlers, system modules etc.), but this is a totally different issue from what I had in mind when I first wrote this page, which was a way to provide the average user a plain documentation on actions and how to use them.
-- DarTar
I guess the long time lag (NP, I know you're busy) caused you to miss what I was trying to do here.
My idea was:
- write phpDoc compliant documentation so that (ultimately complete) browsable documentation can be generated for use by developers: the documentation block is input for phpDoc; and
- use that same documentation block as input for a tool along the lines you proposed to generate endusers' documentation.
Writing two pieces of docunentation is counterproductive (it would be a lot of extra effort to make sure that they are consistent not only with the actual code, but also with each other); much better to write a single documentation block that serves as in input for two different documentation generating tools: one targeted at the developer (phpDocumentor), the other targeted at the end user (DarTarDoc ;-)).
The documentation block I used as illustration would never be seen in that form by an end user; like I said above: "Just write standard phpDocumentor code, and use some of its basic tags for a limited version." Your DarTarDoc would merely extract the tags that are meaningful for end users: basically @name, short description, @input and @output, possibly also @version and @todo as long as an action is still in beta stage (version < 1.0); all the other tags are for developers (via phpDocumentor) only! But the point is: write documentation once, and in a format familiar to (many) developers.
Also, since (with 'action' code) we're not dealing with a function or a class while we are dealing with parameters, and output, none of the standard phpDocumentor tags can be used to document these - so I came up with the dual-purpose @input and @output.
Does that make it any clearer?
-- JavaWoman
JavaWoman, it was clear from the beginning that the documentation code was meant to be processed by a "documentation generating tool" and not displayed as such to the end user ;-)
My only concern was and remains the following. Could a subset of phpdoc tags be used to produce a plain, human-readable documentation without too many technicalities and - last but not least - without much work?
As you say, "we are not documenting a function nor a class". New, non-standard phpdoc tags must be introduced to make the documentation of actions phpdoc-compliant? My question is then: do we really need phpdoc syntax for a couple of lines of documentation of Wikka actions?
Although I understand ideally your point, I still don't see the pratical need of so much work.
I insisted that we should adopt a convention to produce some basic and internally consistent documentation for end users (mainly, people who are not already familiar with wiki syntax), not developers. If someone is willing to write a full-fledged documentation from which both newbie-readable and developer-readable documentation might be extracted, I welcome the effort.
But I remind you that the biggest weakness of Wikka, as many have pointed out, is (or I hope was) its lack of a basic documentation, not the lack of a standardly formatted developer documentation. I'm not criticizing your proposal as such, but its impact on a relatively small project as Wikka. Please take these considerations as the pragmatic point of view of a nonprofessional and anticartesian Wikka contributor ;-p
-- DarTar
If I could toss in a couple of cents worth of comment. One of the original things that was appealing about wakkawiki compared to others was its accessibility to somebody who was a non-programmer at the time (a year ago I hadn't programmed since doing basic basic stuff 15 years ago (apart from learning html).....I've worked at learning php as part of learning to work with wakka/wikka). Although I'll admit that the scant documentation was problematic from a developing perspective, that's more true with understanding the use of the formatters and functions etc etc, than with the functioning of the actions themselves. As a learning programmer if I'd opened an action and saw the first dozen lines of code such as proposed by JW above I would have been intimidated like heck and might well not have worked on it like I have. So, I guess in all of this I'd side more with DarTar that some basic commentary at the head of the actions would have been useful to me, but more extensive (and complexly structured) commentary would have been quite off-putting. It was the complexity of TikiWiki that drove me away from it (wisely I'm still convinced) and the reasonable structural simplicity of wakka that had me work with it. I installed and tried almost a dozen wiki's before settling on this one for development, so I guess what I'd encourage is improving things to appeal to newcomers (such as myself) and make their learning curves less steep but without discouraging them. A fine line to follow I'll agree. -- Mike B (GmBowen)
@GmBowen:
As a learning developer I'd propose you'd learn faster from properly documented code. Wikka is a lot better in this respect than a lot of other open-source projects, which is one reason I chose it(!), but all the same a lot could be improved.
Don't be intimidated by the format my code sample takes - it is not for human consumption, but serves as input for a documentation processor like phpDoumentor that produces fully integrated and cross-referenced documentation in HTML format. It's that documentation a developer would use to understand how an application works, what happens where, what the dependencies in the code are - and in order to be able to modify or extend the code, you need to know these things, and preferably not by reading code!
While the documentation block I've shown is what would be written by a developer to document the code in such a way that such integrated and cross-referenced documentation can be generated, it's not the format that would be read by anyone getting familiar with the code; what one would use would be the integrated documentation that is produced from all the little bits taken together. This goes way beyond the little bit that's documented - it enables documentation of the code as part of a system.
Fully integrated and cross-referenced documentation would make your learning curve a lot less steep than it currently is!
I document this way as I go, and re-generate the documentation regularly ... and gradually the system becomes easier to understand for me, too. (Partly this is because on its own phpDocumentor can produce basic documentation even without documentation blocks in the code - it just gets better when these documentation blocks are added which also enable the cross-referencing).
And when you write your own extensions - don't worry, the documentation format is easily learned; and time spent documenting your code is time well-spent: not only will it make it easier for others to use and extend, it will make it easier for yourself to understand a few months from now. Don't believe your undocumented code will be easy to understand in half a year - it won't be: that's a painful lesson I learned many years ago!
--JavaWoman
@Dartar:
> My question is then: do we really need phpdoc syntax for a couple of lines of documentation of Wikka actions?
In my opinion, yes. An "action" is functionally a function (an isolated bit of code with parameter input which gets processed to produce output) even though syntactically it isn't (which is why standard phpDocumentor tags like @param and @return won't work). The problem is not that my new tags are "non standard" but that the mechanism of "actions" is itself non-standard because syntactically they aren't true function and the the standard tags to document what's needed (inputs and output) simply won't work.
> But I remind you that the biggest weakness of Wikka, as many have pointed out, is (or I hope was) its lack of a basic documentation, not the lack of a standardly formatted documentation.
I think it's both. Many open source projects ultimately flounder because of a lack of (standard) documentation - leading to buggy code, bad integration, a house of cards that will sooner of later collapse. Yes, we certainly need clear documentation for end users, but we also need clear developer's documentation; and "clear" in the latter context at least implies some form of standardization (which the phpDoc format is (more or less) because it builds on well-known formats like JavaDoc and others).
My argument is that (for actions) we should adopt a format that will serve both purposes - since actions are both created and maintained by developers and directly used by end users.
> I'm not criticizing your proposal as such, but its impact on a relatively small project as Wikka.
The "impact" as I see it would be that we'd gain both end-user documentation and developer documentation, making Wikka easier to use as well as easier to develop further. Wikka may be "small" ("lightweight") now, but inevitably it will grow. If, that is, it's documented well enough to allow it to grow - and that means both end user documentation (so people will feel confident in using it, and possibly getting involved), as well as developer documentation enabling those who do get involved to get up to speed quickly. Currently, a lot of actions badly need developer documentation, not just end user documentation.
> New, non-standard phpdoc tags must be introduced to make the documentation of actions phpdoc-compliant?
Unfortunately, yes. Because the mechanism of "actions" as implemented in Wikka is itself "non-standard". In order to get proper documentation for both developers and end users, at least inputs (parameters) and output (what does the code "produce") must be documented. phpDoc actually is set up so that that it's extensible, so it enables documenting even non-standard constructs such as "actions" by making a few simple extensions.
While that doesn't sound ideal, the alternative is, in my opinion, much worse:
- an action must be documented some way (there we agree); it must be documented for end users (there we also agree); and it must be documented for developers as well (it seems you don't agree with that);
- if we only wanted to have end-user documentation, we could adopt a non-standard documentation format (as in your original proposal) - but in practice this is still bad since it would force developers to use two different documentation formats: a non-standard one for actions, and a standard, generally known format for everything else;
- it's also bad because the developer's effort in producing documentation in the first place would result only in end-user documentation, while "hiding" the documentation from phpDocumentor; and at worst, it might even interfere with phpDocumentor - unless the format is carefully designed to be sufficiently different not to interfere with it;
- and the more different the documentation format is, the harder it is on the developer to produce good documentation - this will inevitably lead to less documentation rather than more;
- if on the other hand we agree that developer's documentation is also needed, the burden on the developer would be even larger, since then (assuming your "sufficiently different" format so as not to interfere with phpDocumentor) the developer would have to write documentation twice; much of it overlapping, with essentially the same content, only in two different formats.
Look at it another way:
You proposed a format which could be parsed to produce end-user documentation (only); I propose a different format for essentially the same information, which could still be parsed to produce end-user documentation. The difference is that the format I'm proposiing will also be able to be parsed by phpDocumentor to produce developers' documentation. Nothing lost, a lot gained.
> If someone is willing to write a full-fledged documentation from which both newbie-readable and developer-readable documentation might be extracted, I welcome the effort.
I'm willing. I document (extensively) all code I write (I've already started to use the format I proposed for actions), and with any code I even "touch", I normally start by adding a lot of comments. Just don't expect me to do it all in one big fell swoop... (and I'm rather busy at the moment writing some other non-action code which I want to finish first).
In fact, I'm even willing to write a parser for the format I proposed (I'll eat my own dog food). But not tomorrow. ;-)
But I'm definitely not willing to write two pieces of documentation for document the same things only for different audiences. I've already proved that my format will work for developer's documentation (the sample I gave above is lifted directly from the code I have on my development machine, and is processed by phpDocumentor to create documentation that integrates with the rest). All that's needed from that point on is a "little parser" that extracts the bits that are relevant to end users from the same documentation.
-- JavaWoman
> I'm willing.
Fine ;-) But consider that many of us (including me) are not familiar at all with phpdoc syntax, which shouldn't discourage to document action proposals and code hacks .
I personally have no time to learn phpdoc syntax in this moment, maybe in the future...
-- DarTar
CategoryDevelopmentDocumentation