Annotation of kupuMPIWG/doc/TEMPLATE-SYSTEM.txt, revision 1.1
1.1 ! dwinter 1: ==========================
! 2: The kupu Templating System
! 3: ==========================
! 4:
! 5: Problem
! 6: =======
! 7:
! 8: kupu is an editor with many features, many of them optional or
! 9: specific to certain integration implementations. While it is fairly
! 10: easy to maintain the JavaScript side of features through separate
! 11: files, the HTML template has to be custom constructed for every
! 12: feature combination.
! 13:
! 14: Kupu 1.0 thus comes with five different templates. Zope-based
! 15: applications would just require one template because they could turn
! 16: certain parts of the template on and off by filling ZPT
! 17: slots. However, applications not using Zope Page Templates (ZPTs) have
! 18: to customize one of the provided templates. That not only means manual
! 19: editing of the templates in order to configure the feature set, it
! 20: also means the lack of an automatic update when a new kupu version is
! 21: released.
! 22:
! 23:
! 24: Goals
! 25: -----
! 26:
! 27: We want to...
! 28:
! 29: * involve as few files as possible when adding a new feature to
! 30: kupu. We preferrably only want to add a file for the JavaScript
! 31: part of the feature and a file for the template part of the
! 32: feature.
! 33:
! 34: * be able to disable a feature whenever we want under any
! 35: circumstance.
! 36:
! 37: * allow and encourage third party developers to develop plugins
! 38: (i.e. new features) for kupu that can be distributed outside the
! 39: main kupu integration and yet be included without manual
! 40: adjustments.
! 41:
! 42: * be able to include platform specific markup when necessary.
! 43:
! 44: * rely on templating standards (XML, XSLT, XInclude, etc.)
! 45:
! 46: It is clear, that a system-indepentend templating system is needed to
! 47: ease kupu's integration into other systems and any customization that
! 48: is required by such a process.
! 49:
! 50:
! 51: Definitions
! 52: -----------
! 53:
! 54: Slot
! 55:
! 56: A position in a template, at which markup can be inserted. Example:
! 57: the HTML header, the HTML body.
! 58:
! 59: Feature
! 60:
! 61: A bundle of code and markup providing a certain set of
! 62: functionality. Examples for basic features are: the editor frame,
! 63: toolbar with buttons, colorchooser, synchronous form-based or
! 64: asynchronous document-centric editing support. Examples for more
! 65: advanced and optional features are: save on part, autosave, context
! 66: menu, source editing, library drawer.
! 67:
! 68: Part
! 69:
! 70: A part of a Feature. While order usually does not matter when
! 71: writing JavaScript prototypes (or including them from a file), order
! 72: in a template *does* matter. Therefore, a Feature can consist of
! 73: different parts which are distributed throughout the template at the
! 74: appropriate places (Slots). Example: The parts of the source edit
! 75: feature are the button in the toolbar that enables source editing
! 76: and the function that is called when the button is clicked.
! 77:
! 78: Implementation
! 79:
! 80: Combination of target platform specific Features or Parts of
! 81: Features. The way Features are implemented might vary througout
! 82: different integration layers, due to the requirements of the target
! 83: platforms. Examples of Implementations are: Default (the default set
! 84: of Features), Zope (re-implementation of certain features for Zope
! 85: integration), Plone, Silva, Apache Lenya, MMBase, etc.
! 86:
! 87: Distribution
! 88:
! 89: Set of Feature definitions or Feature disablings in the context of a
! 90: certain Implementation or order of Implementations. Distributions
! 91: can not only differ from integration layer to integration layer, but
! 92: also be customized for every application or system Kupu is part
! 93: of. Kupu thus only provides *default* distributions, e.g.:
! 94: Distribution for default Features, Distribution for Plone,
! 95: Distribution for Silva, Distributon for Silva, etc. Web Developer
! 96: XYZ might choose to make a custom distribution for the application
! 97: (s)he's building for customer ABC.
! 98:
! 99:
! 100: Whenever the above defined words appear in the text below, their first
! 101: letter is capitalized. Otherwise, the term is used in its conventional
! 102: meaning.
! 103:
! 104:
! 105: Perceptions
! 106: -----------
! 107:
! 108: * An Implementation overrides one or more features defined by default
! 109: Implementations or defines new features
! 110:
! 111: * Wiring Parts to Slots is Distribution-specific.
! 112:
! 113: * Implementation Order is Distribution-specific.
! 114:
! 115: * Feature enabling/disabling is Distribution-specific, but usually
! 116: more specific to the target application than to the pre-packaged
! 117: Distribution.
! 118:
! 119:
! 120: Proposal
! 121: ========
! 122:
! 123:
! 124: File system structure
! 125: ---------------------
! 126:
! 127: kupu's former main template (kupumacros.html) is split into logical
! 128: chunks resembling Features and Parts as defined above. Each Feature
! 129: and all its parts resides in an XML file with the file ending '.kupu'.
! 130: All features of an Implementation reside in the same directory. The
! 131: main kupu distribution includes a directory named 'default'. It
! 132: contains a default set of Features in their default Implementation.
! 133: Platform specific markup resides in other Implementation directories.
! 134:
! 135: A Distribution is represented in an XML file typically named
! 136: 'dist.kupu'. It defines an order in which Features are looked up in
! 137: Implementations and can optionally disable Features.
! 138:
! 139: A system consisting of XSLT templates is used to parse a Distribution
! 140: configuration file and construct markup custom to that particular
! 141: Distribution. The XInclude standard is used to combine all .kupu XML
! 142: files to one large tree that can be fed to an XSLT processor.
! 143:
! 144: Overview:
! 145: ~~~~~~~~~
! 146:
! 147: =============================== ================================================
! 148: kupu/ (the root directory of the kupu distribution)
! 149: kupu/dist.kupu (kupu's default Distribution file)
! 150: kupu/default/ ('default' Implementation of Features)
! 151: kupu/default/feature1.kupu
! 152: kupu/default/feature2.kupu
! 153: kupu/default/wire.kupu (wires Parts to Slots)
! 154: kupu/default/include.kupu (imports all Features and the wiring from the
! 155: 'default' Implementation for convenience)
! 156: kupu/foo/ ('Foo' Implementation)
! 157: kupu/foo/feature1.kupu
! 158: kupu/foo/feature2.kupu
! 159: kupu/foo/wire.kupu ([re-]wires [additional] Parts to Slots)
! 160: kupu/foo/include.kupu (imports all Features and the wiring from the
! 161: 'default' Implementation for convenience)
! 162: kupu/foo/foo.py (some additional platform specific files)
! 163: kupu/foo/Foo.class
! 164: kupu/foo/fooicon.png
! 165: =============================== ================================================
! 166:
! 167: XML format
! 168: ----------
! 169:
! 170: ::
! 171:
! 172: <grammar xmlns="http://relaxng.org/ns/structure/1.0">
! 173:
! 174: <start>
! 175: <ref name="dist" />
! 176: </start>
! 177:
! 178: <define name="dist">
! 179: <element name="dist">
! 180: <interleave>
! 181: <ref name="featureOrInclude" />
! 182: <ref name="implementationOrder" />
! 183: <ref name="expand" />
! 184: </interleave>
! 185: </element>
! 186: </define>
! 187:
! 188: <define name="feature">
! 189: <element name="feature">
! 190: <attribute name="name">
! 191: <text />
! 192: </attribute>
! 193: <attribute name="implementation">
! 194: <text />
! 195: </attribute>
! 196: <element name="part">
! 197: <attribute name="name">
! 198: <text />
! 199: </attribute>
! 200: <ref name="partContents" />
! 201: <element>
! 202: </element>
! 203: </define>
! 204:
! 205: <define name="featureOrInclude">
! 206: <zeroOrMore>
! 207: <choice>
! 208: <!-- we can either include more features from elsewhere -->
! 209: <element name="include">
! 210: <ref name="featureOrInclude" />
! 211: </element>
! 212:
! 213: <!-- or provide actual features -->
! 214: <ref name="feature" />
! 215: </choice>
! 216: </zeroOrMore>
! 217: </define>
! 218:
! 219: <define name="wire">
! 220: <element name="wire">
! 221: <attribute name="implementation">
! 222: <text />
! 223: </attribute>
! 224: <zeroOrMore>
! 225: <ref name="fillSlot" />
! 226: </zeroOrMore>
! 227: </element>
! 228: </define>
! 229:
! 230: <define name="fillSlot">
! 231: <element name="fill-slot">
! 232: <attribute name="name">
! 233: <text />
! 234: </attribute>
! 235: <zeroOrMore>
! 236: <choice>
! 237: <ref name="arbitraryMarkup" />
! 238: <ref name="insertPart" />
! 239: </choice>
! 240: </zeroOrMore>
! 241: </element>
! 242: </define>
! 243:
! 244: <define name="expand">
! 245: <oneOrMore>
! 246: <element name="expand">
! 247: <zeroOrMore>
! 248: <ref name="defineSlot" />
! 249: </zeroOrMore>
! 250: </element>
! 251: </oneOrMore>
! 252: </define>
! 253:
! 254: <define name="defineSlot">
! 255: <element name="define-slot">
! 256: <attribute name="name">
! 257: <text />
! 258: </attribute>
! 259: </element>
! 260: </define>
! 261:
! 262: <define name="implementationOrder">
! 263: <element name="implementation-order>
! 264: <oneOrMore>
! 265: <element name="implementation">
! 266: <attribute name="name">
! 267: <text />
! 268: </attribute>
! 269: </element>
! 270: </oneOrMore>
! 271: </element>
! 272: </define>
! 273:
! 274: <define name="arbitraryMarkup">
! 275: <element name=""> <!-- XXX arbitrary markup -->
! 276: <ref name="partContents" />
! 277: </element>
! 278: </define>
! 279:
! 280: <define name="insertPart">
! 281: <element name="insert-part">
! 282: <attribute name="name">
! 283: <text />
! 284: </attribute>
! 285: <attribute name="part">
! 286: <text />
! 287: </attribute>
! 288: </element>
! 289: </define>
! 290:
! 291: <define name="partContents">
! 292: <zeroOrMore>
! 293: <choice>
! 294: <ref name="arbitraryMarkup" />
! 295: <ref name="defineSlot" />
! 296: </choice>
! 297: </zeroOrMore>
! 298: </define>
! 299:
! 300: </grammar>
! 301:
! 302:
! 303: Example markup:
! 304: ---------------
! 305:
! 306: dist.kupu
! 307: ~~~~~~~~~
! 308:
! 309: ::
! 310:
! 311: <kupu:dist
! 312: xmlns:kupu="http://kupu.oscom.org/namespaces/dist"
! 313: xmlns:xi="http://www.w3.org/2001/XInclude"
! 314: >
! 315:
! 316: <!-- Include implementations -->
! 317: <xi:include href="default/include.kupu" />
! 318: <xi:include href="zope2/include.kupu" />
! 319: <xi:include href="zope3/include.kupu" />
! 320: <xi:include href="silva/include.kupu" />
! 321: <xi:include href="plone/include.kupu" />
! 322: <xi:include href="apache-lenya/include.kupu" />
! 323: <xi:include href="roundup/include.kupu" />
! 324: <!-- ... -->
! 325:
! 326: <!-- Define the default slot to start with -->
! 327: <kupu:expand>
! 328: <kupu:define-slot name="start" />
! 329: </kupu:expand>
! 330:
! 331: <!-- Define an order for the implementations that are to be used. The
! 332: most specific one is located at the top, the last one should
! 333: always be 'default'. -->
! 334: <kupu:implementation-order>
! 335: <!-- most specific one at top -->
! 336: <kupu:implementation name="plone" />
! 337: <kupu:implementation name="default" />
! 338: </kupu:implementation-order>
! 339:
! 340: <!-- Plone does not want to use certain features -->
! 341: <kupu:disable-feature name="toolboxes" />
! 342: <kupu:disable-feature name="save" />
! 343: <kupu:disable-feature name="colorchooser" />
! 344:
! 345: </kupu:dist>
! 346:
! 347:
! 348: some_impl/include.kupu
! 349: ~~~~~~~~~~~~~~~~~~~~~~
! 350:
! 351: ::
! 352:
! 353: <kupu:include
! 354: xmlns:kupu="http://kupu.oscom.org/namespaces/dist"
! 355: xmlns:xi="http://www.w3.org/2001/XInclude"
! 356: >
! 357:
! 358: <!-- Include features -->
! 359: <xi:include href="feature1.kupu" />
! 360: <xi:include href="feature2.kupu" />
! 361:
! 362: </kupu:include>
! 363:
! 364: some_impl/feature1.kupu
! 365: ~~~~~~~~~~~~~~~~~~~~~~~
! 366:
! 367: ::
! 368:
! 369: <kupu:feature
! 370: name="feature1"
! 371: implementation="some_impl"
! 372: >
! 373:
! 374: <kupu:part name="part1">
! 375: <div>
! 376: <p>Part 1 of Feature 1</p>
! 377: </div>
! 378: </kupu:part>
! 379:
! 380: <kupu:part name="part2">
! 381: <p>
! 382:
! 383: This part defines a slot that can be filled with more markup by
! 384: other features:
! 385:
! 386: <div id="foobar">
! 387: <kupu:define-slot name="foobar" />
! 388: </div>
! 389:
! 390: </p>
! 391: </kupu:part>
! 392:
! 393: </kupu:feature>
! 394:
! 395: some_impl/wire.kupu
! 396: ~~~~~~~~~~~~~~~~~~~
! 397:
! 398: ::
! 399:
! 400: <kupu:wire
! 401: implementation="some_impl"
! 402: xmlns:kupu="http://kupu.oscom.org/namespaces/dist"
! 403: >
! 404:
! 405: <kupu:fill-slot name="foobar">
! 406: <kupu:insert-part feature="some_feature" part="some_part" />
! 407: <kupu:insert-part feature="another_feature" part="a_part" />
! 408: </kupu:fill-slot>
! 409:
! 410: </kupu:wire>
! 411:
! 412:
! 413: Questions/Problems
! 414: ==================
! 415:
! 416: - Yet to be solved: How to handle i18n in templates? Temporary
! 417: solution: use ZPT's i18n markup so that we have at least a declaration
! 418: of what is to be i18n'd.
! 419:
! 420:
! 421: Futures
! 422: =======
! 423:
! 424: - Feature/Part dependencies
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>