Annotation of kupuMPIWG/doc/TEMPLATE-SYSTEM.txt, revision 1.1.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>