File:  [Repository] / kupu / doc / TEMPLATE-SYSTEM.txt
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Thu Sep 15 13:06:00 2005 UTC (18 years, 9 months ago) by dwinter
Branches: first, MAIN
CVS tags: dwinter, HEAD
modifizierter kupu fuer webpages des instituts

    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>