Wiki module - new architecture
I'm a recent convert to Drupal after running my site based upon JSPWiki for about a year. I'm currently running a fairly simple site (groupedia.com) using the wiki module.
To cut to the end of my story, I've got a re-architected version of the wiki module partially working that implements a new node->format. I would like some help in fixing some bugs and investigating core changes to support an elegant implementation. But first, let me start the story from the beginning:
After a bit of investigation, here's what I've been able to deduce about the architecture as it relates to the wiki module. The wiki module intercepts the module_filter hook and transforms the written wiki-text into HTML. So to write a page using wiki-text, you set the $node->format to be HTML, even though it isn't, but since the wiki module is activated, the wiki-text is transformed into HTML before being rendered to the screen.
The drawback to this approach is that once the wiki module is activated you can no longer write nodes using HTML since they are always filtered through the wiki module.
It seemed to me that what we wanted to do was to add another entry into the dropdown list indicating the format of the node. Currently the only choices are HTML and PHP and these choices are hardcoded in the source code. What I mean is that there is no hook (that I could find) to add a new node format.
So I hacked the code a bit. I've listed the changes here in text but I can post diffs if desired.
1) I added a new entry ( 3 => "Wiki" ) into the node->format dropdown menus in page.module and book.module. That allows me to set the node->format but of course nothing changes in the rendering yet.
2) I edited the wiki.module to remove the module_filter hook -- I just commented it out for now. At this point my pages, which are written in wiki-text, are rendered as raw wiki-text (not transformed into HTML).
3) I added a new clause to page.module::page_content. It already checked for node->format of 0 and 1, corresponding to HTML and PHP. I added another check for type 2, now corresponding to wikitext.
For wikitext, it invokes the _wiki_transform() function from the wiki.module.
4) I edited a page whose format was set to be HTML; I set the format to be Wikitext. Now, when viewing this page, the source text is transformed through _wiki_transform() into HTML and rendered correctly.
What's good about my hacking:
- My site can have wiki text in some places and HTML / PHP in others.
- New modules could be written for other node->formats. For example, there are numerous competing wikitext dialects. When converting my old wiki site to Drupal I had to hand edit over a hundred pages. I can imagine a number of wiki modules that implement different wikitext dialects. Other source formatting possibilites are wide open.
- Less interference with other filters. I've seen that this is already a discussion item. Note however that another filter that is expecting to filter HTML is unlikely to work on wikitext.
- It's conceptually cleaner. (OK, this is opinion). I think that the existing filtering hook is great for modules like the swearing filter or the link creation filter. When the node format just isn't HTML, it seems wrong to say that it is then use a filter to make it HTML later. If this is the preferred mechanism, then why make the PHP and HTML distinction -- you could use a filter to transform PHP into HTML.
What's bad about my hacking:
- The node->format dropdown menus are hardcoded.
- Transformation of wiki text is hardcoded in the page_content function.
- There's still no defined hook to add a new node->format.
- There is a namespace problem. My wiki module just grabbed node->format "2" (HTML is 0, PHP is 1). Using a text string (maybe the name of the module) would be more resilient against collisions.
- More stuff I haven't thought of yet.
I'd appreciate any feedback on this idea. It seems to me that adding a new hook point for format isn't so difficult (though I haven't done it yet). Changing the node->format datatype from int to string is a bigger problem because of data migration and may need to be postponed.