Revision [9128]

This is an old revision of AdvancedFormatter made by JavaWoman on 2005-06-11 09:22:08.


Advanced Formatting and code generation

This is the development page (or rather a hub for a number of separate development pages) for advanced Wikka formatting and other new or enhanced code "responsible" for generating valid XHTML in Wikka pages.

While the Formatter takes user-supplied source code in Wikka "markup" and turns it into XHTML, there are several actions and handlers also produce XHTML output directly: using core utility methods for this generation process helps to make such generated code structural, valid and consistent. This page deals with both aspects of Wikka since although they have different operation they are closely related in their purpose (and the Formatter also makes use of some of the core utility methods for its work).

The code written by JavaWoman (tested and ready to be installed on this server as a beta feature) addresses several issues of the current formatter and other code generation. In particular, it fixes a number of small formatting bugs, and adds new important features - like automatic generation of ids for headers and forms - required both for XHTML compliance and for (later) extensions such as the ability to link to page fragments (often implemented through anchors though we've chosen the XHTML-strict compliant method of using fragment ids), which in turn will enable TOC's. More consistent generated code and generated ids will also enable advanced styling through CSS.

What's new

Much of this really isn't visible on the "surface", and you can't suddenly do new things yet; what we get instead is a number of enabling features that (will) make other things (visible things) possible, as well as ways to generate code more consistently and reliably. Some of it really is "formatting" (given page source with Wikka formatting codes, generating valid XHTML from it), some of it is just utility methods that can be called upon by the formatter as well as other methods, actions and handlers to help generating valid XHTML that provides "hooks" for styling and other things.

These "enabling" features mostly take the form of new and enhanced methods in the WikkaCore Wikka core:

The core: WikkaCore wikka.php

This is new CompatibilityCode compatibility code (similar to mysql_real_escape_string()) to provide functionality used by wakka.php when generating ids for headings: the function html_entity_decode() is available as of PHP 4.3 but for older versions we provide a (near) equivalent alternative;

A more advanced version of the FormOpen() method (see AdvancedFormOpen) which uses the new makeId() method (see GenerateUniqueId); it also supports more types of forms, including forms that allow file uplaods. The FormOpen() method is already used by many actions and handlers but with the extensions all code generating a form really should use this method together with its FormClose() counterpart since all forms type are now provided for. This will ensure consistent and valid code and make it easier to style forms.

A new makeId() method with some supporting code (see GenerateUniqueId). From the docblock for the method:
Although - given Wikka accepts embedded HTML - it cannot be guaranteed that an id generated by this method is unique, it tries its best to make it unique:
    • ids are organized into groups, with the group name used as a prefix;
    • if an id is specified it is compared with other ids in the same group; if an identical id exists within the same group, a sequence suffix is added, otherwise the specified id is accepted and recorded as a member of the group
    • if no id is specified (or an invalid one) an id will be generated, and given a sequence suffix if needed
For headings, it is possible to derive an id from the heading content to support this, any embedded whitespace is replaced with underscores to generate a recognizable id that will remain (mostly) constant even if new headings are inserted in a page.
The method supports embedded HTML as well: as long as the formatter passes each id found in embedded HTML through this method it can take care that the id is valid and unique. This works as follows:
    • indicate an 'embedded' id with group 'embed'
    • NO prefix will be added for this reserved group
    • ids will be recorded and checked for uniqueness and validity
    • invalid ids are replaced
    • already-existing ids in the group are given a sequence suffix
The result is that as long as the already-defined id is valid and unique, it will be remain unchanged (but recorded to ensure uniqueness overall).

makeList() and makeMemberList()
Two new utility methods makeList() and makeMemberList() are so far only a draft form (see ArrayToList); they are able to generate a list from an array, with id and / or class attributes. Only 'flat' arrays supported for now; the intention is to enhance it with recursion to generate nested lists as well. From the docblock for the makeList() method:
Given an array, this method builds a simple unordered or ordered list with an id. Only a (simple) array is required which will generate an unordered list; optionally id, class, type of list and an indent level can be specified. For type 'menu' an unordered list is generated but with an id in group 'menu' instead of 'ul' or 'ol': this enables the list being styled as a menu.
Several existing actions could make use of these utilities, and work is in progress to adapt them to do this.
More on ArrayToList.

makeCols() and makeMemberCols()
Analogous to makeList() and makeMemberList(), two equally new utility methods makeCols() and makeMemberCols() provide a similar API to generate columns of data instead of a single list (see ArrayToColumns). The columns are implemented as floated divs instead of as a layout table, providing more structural and accessible code. From the docblock for the makeCols() method:
Given an array and number of columns, this method builds vertically-arranged columns (meaning they are read vertically, one by one) implemented as floated divs. Column width is derived from the specified number of columns, implemented as an embedded style because it's dynamically generated; left float is added to the style (hardcoded for now but alignment could become an option later).
Again several existing pieces of Wikka code could make use of these, with work in progress to implement this.
More on ArrayToColumns.

The Formatter: ./formatters/wakka.php

The Formatter has the responsibility to translate user-provided page code into valid XHTML. It's not perfect at this but it's getting a little better. Since some of the intended improvements required quite a bit of digging into the code, some work was also done to make that code a bit more readable, while the digging work also unearthed a few existing bugs (including unrecorded ones) that could now be solved.

All of this does not make an advanced Formatter but it does make our Formatter more advanced.
To make generating valid XHTML from Wikka code more reliable, a complete rewrite would actually be needed, but for now the following will at least get us closer, and help enable new features as well:

Heading ids
Creating ids for headings is (you guessed it) the first (and necessary) piece of the puzzle to enable generating TableofcontentsAction page TOCs, but other bits will be needed for that as well, such as actually gathering the references to headings (and their levels), and the ability to link to page fragments (something our WikkaCore current core does not support yet). So: we cannot generate TOCs - yet - but we are getting there; the code is also designed to make it possible to extend it to generate TOCs not just for headings, but also for things like images, tables and code blocks.

A method for generating a TOC has not been decided yet (we may even provide alternatives), but one thing we certainly need is ids for headings (see TableofcontentsAction for more background on this); and even if we do not (yet) generate a TOC, being able to link to a page fragment (the obvious next step) will be useful in itself.

Some thought went into the method of generating the ids: Ideally they should be 'recognizable' so creating links to a page fragment with a heading wil be easy, and they should be as 'constant' as possible so a link to a section remains a link to that section, even if that is moved to a different position on the page, or another is inserted before it. This implies that all methods that simply generate a sequential id will not fulfill our requirements. We also don't burden the writer with coming up with ids (or even needing to think about them): they should be able to just concentrate on the content. Instead, we use following approach:

The result is an id that is almost always derived directly from the heading content, giving a high chance that it will remain constant even if the page content is re-arranged: thus it provides a reliable target for a link.

The code


CategoryDevelopmentFormatters CategoryDevelopmentCore
There are no comments on this page.
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki