Wikka Code Structure
A few days ago I had a little discussion with JsnX in TheLounge (the #wikka channel on irc.reenode.net) about "external" type programs (not part of Wikka but providing important functionality), actions, plugins... and how to organize it all better into a directory structure. I'd been thinking about the same things myself, but somehow didn't quite pick up on what JsnX was proposing (I was probably "multitasking" and doing other things while talking to JsnX on #wikka, sorry).
So, I'll now try to take it from there and give a worked example of what I had in mind (and possibly JsnX as well).
Rationale
My rationale for this proposal is as follows:- Keep "third-party" (external) code together in a directory that indicates it's not part of Wikka's source code but "bundled software".
- Maybe make a distinction here between "core" (needed for basic functionality) and "optional" (may be turned off in configuration); while we have only a few packages of third-party code now, this could increase, so I think this is a good moment to make the distinction to avoid another restructuring down the road.
- Separate actions into "core" (actual "wiki" type of functionality) and "plugins" (nice optional extras, but not necessary to run a wiki site).
- Actions may need functions and different actions may need to share functions. In order to avoid duplication and allow such actions to be included in a page multiple times, the functions they use should be put together in a file which can then be used with include_once() or require_once(). But such an external file should then not be placed in the actions directory (nor a subdirectory) since this will 1) suggest it is and action and can be included in a page (it cannot), and 2) it will break the (coming) automatic documentation routines that will go through the actions directory to find the files to be documented as actions. As long as the (sub)directories are named consistently, actons should be able to "find" their own functions.
So here is how I'd structure the directory (some comments included in PHP-style):
Proposal
[wikka]/ [wikka]/3rdparty/ [wikka]/3rdparty/core/ [wikka]/3rdparty/core/safehtml/ #HTML can be turned off globally [wikka]/3rdparty/plugins/ [wikka]/3rdparty/plugins/freemind/ #cannot be turned off yet but is not needed functionality [wikka]/3rdparty/plugins/geshi/ [wikka]/3rdparty/plugins/onyx-rss/ #replaces [wikka]/xml/ [wikka]/3rdparty/plugins/wikiedit2/ #can be turned off globally [wikka]/actions/ [wikka]/actions/core/ # "overall management" actions (referring to other pages than the current one) [wikka]/actions/core/category.php [wikka]/actions/core/highscores.php [wikka]/actions/core/interwikilist.php [wikka]/actions/core/lastusers.php [wikka]/actions/core/mychanges.php [wikka]/actions/core/orphanedpages.php [wikka]/actions/core/ownedpages.php [wikka]/actions/core/pageindex.php [wikka]/actions/core/recentchanges.php [wikka]/actions/core/recentcomments.php [wikka]/actions/core/recentlycommented.php [wikka]/actions/core/textsearch.php [wikka]/actions/core/textsearchexpanded.php [wikka]/actions/core/nocomments.php # page content (or referring to/changing the current page only) [wikka]/actions/core/backlinks.php [wikka]/actions/core/color.php [wikka]/actions/core/colour.php #only does an include of color.php so don't have duplicated code! [wikka]/actions/core/include.php [wikka]/actions/core/image.php #and disallow dynamic image inclusion via url: not valid html [wikka]/actions/core/lastedit.php [wikka]/actions/core/table.php [wikka]/actions/plugins/ # system management [wikka]/actions/plugins/emailpassword.php #access control may not be desired/implemented [wikka]/actions/plugins/usersettings.php #access control may not be desired/implemented [wikka]/actions/plugins/feedback.php # page content [wikka]/actions/plugins/calendar.php [wikka]/actions/plugins/files.php [wikka]/actions/plugins/flash.php [wikka]/actions/plugins/googleform.php [wikka]/actions/plugins/iframe.php #now in intranet dir for security reasons: it's really an action! [wikka]/actions/plugins/mindmap.php [wikka]/actions/plugins/rss.php # ... more actions added in version 1.1.6.0 [wikka]/library/ # library files with code to be included and called [wikka]/library/common/ [wikka]/library/actions/ [wikka]/library/handlers/ [wikka]/templates/ # page structure rather than content (not for actions and handlers) [wikka]/templates/footer.php #not an "action"! [wikka]/templates/header.php #not an "action"! # page content blocks and templates [wikka]/templates/common/ [wikka]/templates/actions/ [wikka]/templates/handlers/ [wikka]/css/ [wikka]/docs/ [wikka]/formatters/ [wikka]/handlers/ [wikka]/images/ [wikka]/setup/
Notes
- Apart from separating actions into "core" and "plugin" I've grouped them by general functionality (embedded comments)
- Since "plugins" would be optional elements in a working Wikka implementation, WikiAdmins will need a way to activate or deactivate them. This suggests a kind of "plugin registry" (a new database table) with some admin-only functionality to register, activate, deactivate and unregister a plugin.
- This would be very welcome -- DarTar
"Core" actions could be in the same registry, but with a marker that makes it impossible to deactivate or unregister them: that way the registry function could also display which "core" functions are available. A registration mechanism like this would also solve the problem of the (insecure) iframe action which is now hidden away in an intranet directory: it could be delivered with the file placed in the actions directory but unregistered in the registry.
- To execute an action, existence of the action should be checked (in the defined path) as well as whether a plugin is registered and activated (no action if these criteria are not met)
- WikiEdit2 and SafeHtml "activation" are now done via the config file; this should be implemented via the proposed plugins registry instead. (In addition, if WikiEdit2 is activated, it would be nice if a user could choose to turn it off in their own profile).
- Freemind cannot now be (de)activated; this can be accomplished by a registry entry for the mindmap action which implements Freemind in Wikka.
- The directory intranet which now contains iframe.php should disappear: it really is an (optional) action.
- I think the (buggy) newpage action should disappear as well: apart from buggy it's redundant, there are already two other methods to create a new page. (See also TestActionNewpage outlining some -not all-of the bugs.)
- The configuration should define the paths where all types of actions can be found.
- Since the third-party applications we bundle may already exist on a WikiMaster's system, paths and implementation parameters for these should not be hard-coded in the Wikka source code but instead be defined via parameters in the configuration file. This will give the WikiAdmin the option of using the already-installed (and maybe modified!) program to maintain consistency on her system.
- header and footer are not really actions in that they generate something in the page content (and including {{header}} in a page would result in totally invalid HTML - something an action should never do or even be able to do; they should either be in the root directory, or in a separate subdirectory. It would also be better if they (both) were split up in the part that generates body content (the visible page header and footer) and the part(s) that generate surrounding HTML. Also, they are "unbalanced": while header produces the DOCTYPE declaration and the opening <html> tag, footer does not produce the closing </html> tag (or even a closing </body> tag). We need some serious refactoring here.
Structure adapted now by placing header and footer into a new directory templates that better describes their purpose. In case we do move to some templating system for Wikka, we'll need a place to store the templates anyway.
- A new directory in the list above is what I've provisionally called library. The idea is to provide a central place where supporting code for actions and handlers (and other things like "wrappers" for 3rd-party code) can be placed - see the last point in rationale above. So that's what the library directory is intended for; for clarity and to avoid conflicts, it would be useful to create a subdirectory here for the action that needs supporting files, named after the action itself. That way it's easily recognizable what belongs to what, and it's also possible to have multiple files, if necessary, grouped together in the subdirectory. Example:
So, if someone writes a "letterfun" action that needs two files named "foo.php" and "bar.php", we'd end up with the following structure:[wikka]/actions/plugins/letterfun.php [wikka]/library/actions/letterfun/ [wikka]/library/actions/letterfun/foo.php [wikka]/library/actions/letterfun/bar.php
Adapted for the new (proposed) structure of the library directory. The subdivision in common/actions/handlers is intended to facilitate some (future) automatic processes to find to-be-included code and to describe (in CVS) which files belong together.
The name "library" is (still) only preliminary, I'm open to better suggestions; the idea is to have a name that expresses its purpose as described here.
- Hiya JW. The only reason I suggested "scripts" (at BannerMaker) is because that's what Costal uses in ComaWiki for "extras" like the bannermaker.php and java files and keeping some consistencies amongst wakka forks has some advantages for sharing/moving actions amongst the different forks (and I think there's some advantages to that). I have no objection to other names or directory structures. --GmBowen
- How about libs? Or pluginlibs? --NilsLindenberg
- Took your idea but changed it to "library" (my original idea "aux" seems to be a reserved name under Windows so could not be used). --JavaWoman
- Worked out the "templates" idea with subdirectories for actions and handlers; this will let us have library to include files with code from, and templates to include files with content from. With some API support actions and handlers will be able to "find" their include files automatically, provided files are located strictly according to this scheme. header.php and footer.php are not in a "common" subdirectory since actions and handlers are not supposed to use these!
If we move to a 'real' template system, this may need to be revised of course (depending on that system's requirements for locating templates) but if we don't this will still be a "half-way" template solution that would make interface design for Wikka much easier.. --JW
Comments?
Comments and better ideas welcome, of course.- The idea is very welcome. I was also thinking of a possible overhaul for the Wikka directory but finally never posted it: I'm glad to see that someone else has come up with a similar idea :) I like your general sketch, I only find the idea of separating 3rd party contributions in core vs. plugins not that convincing. And what about a better name for 3dparty/? Maybe libs/ ? --DarTar
- Actually, JsnX came up with:
external, include, 3rdparty, ??
and I thought both "external" and "include" rather vague, and 3rdparty quite descriptive (something we also used in a company I worked for for the same purpose) - so that's what I picked here. Your "libs" might also work, or maybe "bundled"? As long as it's a reasonably descriptive name...
- I'm expecting that at one point we'd bundle both "essential" (core) and "would be nice" (optional) apps, so
- preparing the directory structure now would save another round of restructuring later. Do you see any problem with that structure (even if we leave one empty now), DarTar?
- I think the advantage of 3rd party versus libs is this....if I download and use a package I assume that it's reasonably well tested by a team of developers. If I install a "3rd party" add-on I expect (i) poorer documentation & (ii) more possible conflicts. If a 3rd party add-on doesn't work, I "blame" the developers...well, not really....but you get my drift. If something says "libs" tho', that carries the cachet OF the main developers. I'd say leave it as "3rd party" so that the source of the add-ins is abundantly clear and their developers will be contacted for help and not the wikka developers. -- GmBowen (somebody who keeps dumping "inessential" 3rd party add-ons onto the wikka site...wait'll you see the latest ;) )
- I think it's a matter of trust, really. Do you trust the Wikka developers?
- For me, "3rd party" signifies clearly something that's not made by Wikka developers, but if you trust the Wikka developers you'd know they wouldn't include a 3rd party library or application that's not at least useful and reasonably bug free - as well as Open Source (so if you do find a bug you can repair it!); and you'll also know that for support for that program you shouldn't look at the Wikka developers but go to the developers of the bundled app. Essentially "3rd party" means: "it's not ours but it's good enough that we use (and recommend) it!". (And in open source we try to avoid re-inventing wheels.) "Libs" does not have that connotation. So I think we agree on that - but I could live with "libs" if that gets a majority vote :). --JavaWoman
- I'm not sure that I trust the Wikka developers. They seem a bit shady to me. But, JavaWoman, your last comment above is right on target. When I see the word "libs", I think of library files that are tied to the application. "3rdparty" sounds more like software that was developed by a 3rd party--weird, huh? :). JW, thank you for adding this page, it nicely documents the fuzzy idea that I had in mind. Excellent work. -- JsnX
- I like it too. The only thing I would change is putting usersettings in the core. I think them to important to be just a Plugin! NilsLindenberg
- Nils, I put them in plugins like I put everything to do with user accounts in plugins; my reasoning was that you can use a Wiki (including Wikka) by having it open to everyone, and not have user accounts at all, so in that sense it's optional. OTH, we could emphasize the fact that Wikka has access control by classifying them as core. Which message do we want to give out? --JavaWoman
- Seems to make sense :-) Nils
- We shouldn't forget some sort of language-directory. --NilsLindenberg
Function names
- Somehow connected to this is the naming of functions used in actions. I think a naming convention would be good here too. Imagine 2 different actions having a function doit() and both trying to be used on the same page. What I have in mind here is something like TimoK_doit() for a function used in an action I have written. In case the action becomes part of an official wikka release it could be renamed to Wikka_doit(). (Sorry if this has been discussed elsewhere already). -- TimoK
- You mention an important point, but there are other solution(s): A function should either be stored in a library and included with include_once or require_once, or you should use something like if(!exists...) (see the formatters/wakka.php for example). Why? You shouldn't forget that every function can appear more then one time in the page (or in the history!). So you have to make every function that you write "multiple-save". And you should use a name that is unlikely to be used by other functions, yes. --NilsLindenberg
- include_once as well as require_once is a good method to prevent problems, but it is not 100% safe. One page could still include 2 different files containing declarations of functions with the same name, so you still need the if(!function_exists())-control. And even then you will run into problems when the names are the same. A general naming convention helps prevent trouble here, because the author of an action only has to worry about his own 'namespace'. Of course there might still be actions published elsewhere which do not follow this convention, but in my opinion at least for all actions published here interoperability should be 'guaranteed'. -- TimoK
CategoryWikkaArchitecture