========================== The kupu Templating System ========================== Problem ======= kupu is an editor with many features, many of them optional or specific to certain integration implementations. While it is fairly easy to maintain the JavaScript side of features through separate files, the HTML template has to be custom constructed for every feature combination. Kupu 1.0 thus comes with five different templates. Zope-based applications would just require one template because they could turn certain parts of the template on and off by filling ZPT slots. However, applications not using Zope Page Templates (ZPTs) have to customize one of the provided templates. That not only means manual editing of the templates in order to configure the feature set, it also means the lack of an automatic update when a new kupu version is released. Goals ----- We want to... * involve as few files as possible when adding a new feature to kupu. We preferrably only want to add a file for the JavaScript part of the feature and a file for the template part of the feature. * be able to disable a feature whenever we want under any circumstance. * allow and encourage third party developers to develop plugins (i.e. new features) for kupu that can be distributed outside the main kupu integration and yet be included without manual adjustments. * be able to include platform specific markup when necessary. * rely on templating standards (XML, XSLT, XInclude, etc.) It is clear, that a system-indepentend templating system is needed to ease kupu's integration into other systems and any customization that is required by such a process. Definitions ----------- Slot A position in a template, at which markup can be inserted. Example: the HTML header, the HTML body. Feature A bundle of code and markup providing a certain set of functionality. Examples for basic features are: the editor frame, toolbar with buttons, colorchooser, synchronous form-based or asynchronous document-centric editing support. Examples for more advanced and optional features are: save on part, autosave, context menu, source editing, library drawer. Part A part of a Feature. While order usually does not matter when writing JavaScript prototypes (or including them from a file), order in a template *does* matter. Therefore, a Feature can consist of different parts which are distributed throughout the template at the appropriate places (Slots). Example: The parts of the source edit feature are the button in the toolbar that enables source editing and the function that is called when the button is clicked. Implementation Combination of target platform specific Features or Parts of Features. The way Features are implemented might vary througout different integration layers, due to the requirements of the target platforms. Examples of Implementations are: Default (the default set of Features), Zope (re-implementation of certain features for Zope integration), Plone, Silva, Apache Lenya, MMBase, etc. Distribution Set of Feature definitions or Feature disablings in the context of a certain Implementation or order of Implementations. Distributions can not only differ from integration layer to integration layer, but also be customized for every application or system Kupu is part of. Kupu thus only provides *default* distributions, e.g.: Distribution for default Features, Distribution for Plone, Distribution for Silva, Distributon for Silva, etc. Web Developer XYZ might choose to make a custom distribution for the application (s)he's building for customer ABC. Whenever the above defined words appear in the text below, their first letter is capitalized. Otherwise, the term is used in its conventional meaning. Perceptions ----------- * An Implementation overrides one or more features defined by default Implementations or defines new features * Wiring Parts to Slots is Distribution-specific. * Implementation Order is Distribution-specific. * Feature enabling/disabling is Distribution-specific, but usually more specific to the target application than to the pre-packaged Distribution. Proposal ======== File system structure --------------------- kupu's former main template (kupumacros.html) is split into logical chunks resembling Features and Parts as defined above. Each Feature and all its parts resides in an XML file with the file ending '.kupu'. All features of an Implementation reside in the same directory. The main kupu distribution includes a directory named 'default'. It contains a default set of Features in their default Implementation. Platform specific markup resides in other Implementation directories. A Distribution is represented in an XML file typically named 'dist.kupu'. It defines an order in which Features are looked up in Implementations and can optionally disable Features. A system consisting of XSLT templates is used to parse a Distribution configuration file and construct markup custom to that particular Distribution. The XInclude standard is used to combine all .kupu XML files to one large tree that can be fed to an XSLT processor. Overview: ~~~~~~~~~ =============================== ================================================ kupu/ (the root directory of the kupu distribution) kupu/dist.kupu (kupu's default Distribution file) kupu/default/ ('default' Implementation of Features) kupu/default/feature1.kupu kupu/default/feature2.kupu kupu/default/wire.kupu (wires Parts to Slots) kupu/default/include.kupu (imports all Features and the wiring from the 'default' Implementation for convenience) kupu/foo/ ('Foo' Implementation) kupu/foo/feature1.kupu kupu/foo/feature2.kupu kupu/foo/wire.kupu ([re-]wires [additional] Parts to Slots) kupu/foo/include.kupu (imports all Features and the wiring from the 'default' Implementation for convenience) kupu/foo/foo.py (some additional platform specific files) kupu/foo/Foo.class kupu/foo/fooicon.png =============================== ================================================ XML format ---------- :: Example markup: --------------- dist.kupu ~~~~~~~~~ :: some_impl/include.kupu ~~~~~~~~~~~~~~~~~~~~~~ :: some_impl/feature1.kupu ~~~~~~~~~~~~~~~~~~~~~~~ ::

Part 1 of Feature 1

This part defines a slot that can be filled with more markup by other features:

some_impl/wire.kupu ~~~~~~~~~~~~~~~~~~~ :: Questions/Problems ================== - Yet to be solved: How to handle i18n in templates? Temporary solution: use ZPT's i18n markup so that we have at least a declaration of what is to be i18n'd. Futures ======= - Feature/Part dependencies