Annotation of kupu/doc/LIBRARIES.txt, revision 1.1

1.1     ! dwinter     1: ================================
        !             2: Image and Link Libraries in Kupu
        !             3: ================================
        !             4: 
        !             5: Abstract
        !             6: --------
        !             7: 
        !             8: This document describes the Library feature of the Kupu WYSIWYG
        !             9: editor. It defines the behaviour on both the client and the server and
        !            10: serves as a specification for the XML protocol that is used for their
        !            11: interaction.
        !            12: 
        !            13: 
        !            14: Motivation
        !            15: ----------
        !            16: 
        !            17: Kupu is a visual editor for content management systems, with a target
        !            18: audience of regular users without a high technical profile.  For this
        !            19: audience, Word is the incumbent.
        !            20: 
        !            21: In addition to text, Kupu users need a simple, usable, and
        !            22: high-performance system for getting images and hyperlinks into their
        !            23: pages.  Sometimes they want to *browse* to find these assets.
        !            24: Sometimes they want to *search*, particularly for large collections.
        !            25: 
        !            26: Regarding usability, open source CMS projects don't have many
        !            27: browser-side developers with good usability backgrounds.  Since Kupu
        !            28: is an oscom.org project, it is a goal to move the UI rendering from
        !            29: the server (where talent would be dispersed among projects) to the
        !            30: client (where one UI can work for many servers).  Therefore, the Kupu
        !            31: Library only requests XML from the CMS, not HTML.
        !            32: 
        !            33: Note: Though Kupu will work with IE 5.5 sans service packs, Kupu
        !            34: requires MS XML 3.0 or higher.  Any IE 5.5 that is up-to-date on
        !            35: security updates, and any IE 6 or Mozilla 1.3+ can use the Kupu
        !            36: Library.
        !            37: 
        !            38: 
        !            39: Definitions
        !            40: -----------
        !            41: 
        !            42: Library
        !            43: 
        !            44:   A static or dynamic collection of resources and collections defined
        !            45:   at a top level. Libraries have no parents from a UI perspective,
        !            46:   where as the collection they represent might have a parent
        !            47:   collection.
        !            48: 
        !            49: Collection
        !            50: 
        !            51:   A static or dynamic collection of resources and collections,
        !            52:   modelled after WebDAV collections.
        !            53: 
        !            54: Resource
        !            55: 
        !            56:   A named and URI-locatable object with associated metadata, such as
        !            57:   title, description, preview, size, etc.
        !            58: 
        !            59: 
        !            60: Process overview 
        !            61: ----------------
        !            62: 
        !            63: 1. The user opens a drawer in Kupu. Kupu requests a list of available
        !            64:    libraries. The server answers with a list of libraries possibly
        !            65:    containing URIs at which to get the content listing of each library.
        !            66: 
        !            67: 2. Upon user request, Kupu loads the contents of a library and present
        !            68:    it to the user. Already opened libraries are not reloaded from the
        !            69:    server
        !            70: 
        !            71: 3. A user selects a resource at which point Kupu presents the
        !            72:    associated metadata and may optionally load a preview image.
        !            73: 
        !            74: 4. Double clicking on a collection or selecting a new library triggers
        !            75:    step 2 again.
        !            76: 
        !            77: 5. Clicking on a resource and clicking "Insert" (for an image) or
        !            78:    "Link" (for links) updates the document and closes the drawer.
        !            79: 
        !            80: 6. If the cursor is on a link or image, the drawer allows editing the
        !            81:    image/link attributes.
        !            82: 
        !            83: 
        !            84: List of libraries
        !            85: -----------------
        !            86: 
        !            87: Kupu issues a simple HTTP GET request to a URL defined in the
        !            88: 'libraries' attribute of the iframe. The server returns XML conforming
        !            89: to the following schema::
        !            90: 
        !            91:  <grammar xmlns="http://relaxng.org/ns/structure/1.0">
        !            92: 
        !            93:    <start>
        !            94:      <ref name="librariesDocumentElement" />
        !            95:    </start>
        !            96: 
        !            97:    <define name="librariesDocumentElement">
        !            98:      <element name="libraries">
        !            99:        <zeroOrMore>
        !           100:          <ref name="library" />
        !           101:        </zeroOrMore>
        !           102:      </element>
        !           103:    </define>
        !           104: 
        !           105:    <define name="library"
        !           106:      <element name="library">
        !           107:        <interleave>
        !           108:          <ref name="commonToAllItems" />
        !           109:          <choice>
        !           110:            <ref name="collectionItems" />
        !           111:            <ref name="itemsSource" />
        !           112:          </choice>
        !           113:        </interleave>
        !           114:        </element>
        !           115:    </define>
        !           116: 
        !           117:    <define name="commonToAllItems">
        !           118:      <attribute name="id">
        !           119:        <!-- Must be unique among all libraries, resources and collections. -->
        !           120:        <text />
        !           121:      </attribute>
        !           122: 
        !           123:      <interleave>
        !           124:        <element name="uri">
        !           125:          <text />
        !           126:        </element>
        !           127: 
        !           128:        <optional>
        !           129:          <element name="label">
        !           130:            <text />
        !           131:          </element>
        !           132:        </optional>
        !           133: 
        !           134:        <element name="title">
        !           135:          <text />
        !           136:        </element>
        !           137: 
        !           138:        <optional>
        !           139:          <element name="icon">
        !           140:            <text />
        !           141:          </element>
        !           142:        </optional>
        !           143:      </interleave>
        !           144:    </define>
        !           145: 
        !           146:    <define name="collectionItems">
        !           147:      <element name="items">
        !           148:        <zeroOrMore>
        !           149:          <ref name="collectionItem" />
        !           150:        </zeroOrMore>
        !           151:        <optional>
        !           152:          <element name="uploadbutton" />
        !           153:        </optional>
        !           154:      </element>
        !           155:    </define>
        !           156: 
        !           157:    <define name="itemsSource">
        !           158:      <element name="src">
        !           159:        <text />
        !           160:      </element>
        !           161:    </define>
        !           162: 
        !           163:    <define name="collectionItem">
        !           164:      <choice>
        !           165:        <element name="resource">
        !           166:          <ref name="commonToAllItems" />
        !           167:          <ref name="extraResourceInfo" />
        !           168:        </element>
        !           169:        <element name="collection">
        !           170:          <ref name="commonToAllItems" />
        !           171:          <ref name="itemsSource" />
        !           172:        </element>
        !           173:      </choice>
        !           174:    <define>
        !           175: 
        !           176:    <define name="extraResourceInfo">
        !           177:      <interleave>
        !           178:        <optional>
        !           179:          <element name="preview">
        !           180:            <text />
        !           181:          </element>
        !           182:        </optional>
        !           183: 
        !           184:        <optional>
        !           185:          <element name="size">
        !           186:            <text />
        !           187:          </element>
        !           188:        </optional>
        !           189: 
        !           190:        <optional>
        !           191:          <element name="type">
        !           192:            <text />
        !           193:          </element>
        !           194:        </optional>
        !           195:      </interleave>
        !           196:    </define>
        !           197: 
        !           198:  </grammar>
        !           199: 
        !           200: 
        !           201: For example::
        !           202: 
        !           203:  <libraries>
        !           204: 
        !           205:    <library id="http://path/to/folder">
        !           206:      <title>Current Folder</title>
        !           207:      <icon>http://path/to/icon.jpg</icon>
        !           208:      <src>http://server/current/folder/resources.kupu</src>
        !           209:    </library>
        !           210: 
        !           211:    <library id="http://path/to/other/someotherfolder">
        !           212:      <title>Some Other Folder</title>
        !           213:      <icon>http://path/to/icon.jpg</icon>
        !           214:      <src>http:/server/other/folder/resources.kupu</src>
        !           215:    </library>
        !           216: 
        !           217:    <library id="recentitems">
        !           218:      <title>Recent Items</title>
        !           219:      <icon>http://path/to/icon.jpg</icon>
        !           220:      <items />
        !           221:    </library>
        !           222: 
        !           223:  </libraries>
        !           224: 
        !           225: 
        !           226: Kupu parses this XML to a DOM managed in JavaScript and displays it
        !           227: using an XSLT stylesheet. The DOM tree is stored throughout the whole
        !           228: Kupu session.
        !           229: 
        !           230: 
        !           231: Browser-side architecture
        !           232: ------------------------------------
        !           233: 
        !           234: When the drawer is opened, Kupu loads the XML data about the libraries
        !           235: into a JS property that holds an XML DOM.  The Sarissa cross-browser
        !           236: abstraction for XML (http://sarissa.sf.net) is used.
        !           237: 
        !           238: As the user clicks, more XML data are loaded if that collection hasn't
        !           239: been visited yet.  The loaded XML is then appended into the XML DOM.
        !           240: The node that was clicked on has an attribute set to mark it as
        !           241: selected.  Kupu then runs an XSLT on the XML DOM to re-generate the
        !           242: drawer contents (as HTML), and updates the HTML node with the output.
        !           243: The use of XSLT and XPath give increased performance, lower line
        !           244: count, and better IE/Mozilla compatibility.
        !           245: 
        !           246: As an implementation note, XML is extremely compressible.  With
        !           247: mod_deflate and other server-compression approaches, at least a
        !           248: thousand entries can be encoded in 100 Kb.
        !           249: 
        !           250: User opens on a library
        !           251: -----------------------
        !           252: 
        !           253: In case a collection or library has been active before, it is
        !           254: deselected (by removing the 'selected' attribute on the DOM node). The
        !           255: DOM node of the library the user has chosen is selected (by setting
        !           256: the 'selected' attribute). Also, visually deselect the before selected
        !           257: library (by unsetting a CSS class) and mark the newly selected library
        !           258: (with a CSS class).
        !           259: 
        !           260: In case its <library> element provides the <src> subelement, an HTTP
        !           261: GET to that URI is made, the returned XML retrieved, turned into a DOM
        !           262: tree and the resulting <items> node of the result appended to the
        !           263: library DOM node. That step is not made in case the <library> node
        !           264: directly provides the <items> node.
        !           265: 
        !           266: Now, the XSLT is executed again, presenting the newly selected node
        !           267: (by querying for the node with the 'selected' attribute) and its
        !           268: contents.
        !           269: 
        !           270: When a library's contents has to be retrieved with an extra request,
        !           271: it is returned according to the following schema (using definitions
        !           272: from above)::
        !           273: 
        !           274:  <grammar xmlns="http://relaxng.org/ns/structure/1.0">
        !           275: 
        !           276:    <start>
        !           277:      <ref name="libraryDocumentElement" />
        !           278:    </start>
        !           279: 
        !           280:    <define name="libraryDocumentElement">
        !           281:      <element name="library">
        !           282:        <ref name="commonToAllItems" />
        !           283:        <ref name="collectionItems" />
        !           284:      </element>
        !           285:    </define>
        !           286: 
        !           287:  </grammar>
        !           288: 
        !           289: 
        !           290: For example::
        !           291: 
        !           292:  <library id="some_unique_id">
        !           293:    <title>Current folder</title>
        !           294:    <uri>http://server/current/folder</uri>
        !           295:    <icon>http://server/folder.ico</icon>
        !           296:    <items>
        !           297:      <resource id="another_unique_id">
        !           298:        <title>Foo img</title>
        !           299:        <uri>http://server/current/folder/foo.jpg</uri>
        !           300:        <icon>http://server/image.ico</icon>
        !           301:      </resource>
        !           302:      <collection id="a_collections_unique_id">
        !           303:        <title>Some collection</title>
        !           304:        <uri>http://server/current/folder/collection</uri>
        !           305:        <icon>http://server/folder.ico</icon>
        !           306:      </collection>
        !           307:    </items>
        !           308:  </library>
        !           309: 
        !           310: 
        !           311: User opens a collection
        !           312: -----------------------
        !           313: 
        !           314: Unselect the previously selected collection and try to execute one of
        !           315: three cases in order:
        !           316: 
        !           317:   * The node of selected collection is queried for an attribute
        !           318:     'loadedInNode'. If it exists, it refers to an id of a node which
        !           319:     already contains that collection's items. Select that node and
        !           320:     execute the XSLT to present changes.
        !           321: 
        !           322:   * The selected collection node does not have a 'loadedInNode'
        !           323:     attribute. Therefore, the selected collection's URI is read and the
        !           324:     document element's children are queried with an XPath to check
        !           325:     whether the collection with that URI was already loaded before and
        !           326:     attached to the document element. If so, the selected collection
        !           327:     node receives an attribute 'loadedInNode' with the value of the
        !           328:     corresponding collection node below the document element, which is
        !           329:     selected (by setting the 'selected' attribute). The XSLT is executed
        !           330:     to present the changes.
        !           331: 
        !           332:   * The selected collection node has no 'loadedInNode' attribute and
        !           333:     there is no preloaded collection node of that URI. The selected
        !           334:     node's <src> subelement is read. An HTTP GET request is made to that
        !           335:     URI and the items XML data retrieved and turned into a DOM tree. The
        !           336:     <collection> node of that resulting tree is given a new unique ID,
        !           337:     appended to the document element of the library DOM tree and
        !           338:     selected (by setting the 'selected' attribute). The selected
        !           339:     collection node receives an attribute 'loadedInNode' with the value
        !           340:     that newly generated id. The XSLT is executed to present the
        !           341:     changes.
        !           342: 
        !           343: When a collection's contents has to be retrieved with an extra
        !           344: request, it is returned according to the following schema (using
        !           345: definitions from above)::
        !           346: 
        !           347:   <grammar xmlns="http://relaxng.org/ns/structure/1.0">
        !           348: 
        !           349:     <start>
        !           350:       <ref name="collectionDocumentElement" />
        !           351:     </start>
        !           352: 
        !           353:     <define name="collectionDocumentElement">
        !           354:       <element name="collection">
        !           355:         <ref name="commonToAllItems" />
        !           356:         <ref name="collectionItems" />
        !           357:       </element>
        !           358:     </define>
        !           359: 
        !           360:   </grammar>
        !           361: 
        !           362: This grammar is modeled after the WebDAV response grammar, without
        !           363: using the namespace parts of WebDAV. For example::
        !           364: 
        !           365:   <collection id="some_unique_id">
        !           366:     <title>Some folder</title>
        !           367:     <uri>http://server/some/folder</uri>
        !           368:     <icon>http://server/folder.ico</icon>
        !           369: 
        !           370:     <items>
        !           371:       <resource id="another_unique_id">
        !           372:         <title>Foo img</title>
        !           373:         <uri>http://server/some/folder/foo.jpg</uri>
        !           374:         <icon>http://server/image.ico</icon>
        !           375:       </resource>
        !           376: 
        !           377:       <collection id="a_subfolders_unique_id">
        !           378:         <title>Some subfolder</title>
        !           379:         <uri>http://server/some/folder/subfolder</uri>
        !           380:         <icon>http://server/folder.ico</icon>
        !           381:         <src>http://server/some/folder/resources.kupu</src>
        !           382:       </collection>
        !           383:     </items>
        !           384: 
        !           385:   </library>
        !           386: 
        !           387: 
        !           388: If a collection's parent collection shall be accessible, then the
        !           389: server has to return an entry for it explicitly.
        !           390: 
        !           391: 
        !           392: Searching
        !           393: ---------
        !           394: 
        !           395: For searching, Kupu sends an HTTP POST request to the server (to a
        !           396: configurable URI). The server does the search based on the POST form
        !           397: values and return the results as if they were the contents of a
        !           398: library. The document element of the returned XML, <library>, does not
        !           399: have to have a unique id nor an icon subelement.
        !           400: 
        !           401: The POST request can contain an optional parameter for the size of the
        !           402: result set. The server can enforce an upper limit itself, and if the
        !           403: request parameter is higher, ignore it. By default, this value is 500.
        !           404: 
        !           405: Kupu treats the search result as a library, with the exception of
        !           406: generating a unique id and icon for it. The search result library is
        !           407: attached to the root node of the DOM tree and thus visible and later
        !           408: accessible via the library list.
        !           409: 
        !           410: 
        !           411: Implementation on the Plone side
        !           412: --------------------------------
        !           413: 
        !           414: On the Plone side, a set of Page Templates is responsible for
        !           415: generating the XML. They are aided by a special tool, KupuLibraryTool.
        !           416: 
        !           417: In order to use the XML generation for inclusion of media objects,
        !           418: such as images and photos, as well as for searching documents that one
        !           419: can link to from Kupu, the library tool keeps a mapping from resource
        !           420: types to portal types. It provides a management interface in which the
        !           421: site administrator can define, which portal types are to be treated as
        !           422: collections, as linkable documents, as insertable media objects, etc.
        !           423: 
        !           424: The library tool also keeps a list of available libraries on the
        !           425: site. The site administrator can add, modify, delete and reorder
        !           426: libraries in the tool's management interface. The searching aspect of
        !           427: Kupu Libraries is handled by the portal catalog.
        !           428: 
        !           429: Permissions used by the library tool:
        !           430: 
        !           431: - Kupu: Query libraries
        !           432: 
        !           433:   This permission is required for all users who want to query
        !           434:   libraries from the library tool.
        !           435: 
        !           436: - Kupu: Manage libraries
        !           437: 
        !           438:   This permissions is required for all administrators who need to add,
        !           439:   edit and delete existing libraries.
        !           440: 
        !           441: In order to be able to present special previews for resources without
        !           442: having to load the resource itself in Kupu, a portal type can provide
        !           443: an action called 'kupupreview', pointing to the URL where the object's
        !           444: preview can be retrieved. If a portal_type does not provide that
        !           445: action, preview is disabled for it.
        !           446: 
        !           447: Example: Preview action for CMFPhoto showing each photo's thumbnail
        !           448: version:
        !           449: 
        !           450:   - Go to the portal_types tool and click on the 'Photo' portal
        !           451:     type. Then click on its 'Actions' tab.
        !           452: 
        !           453:   - Down below enter information for a new action:
        !           454: 
        !           455:     Name:       Kupu Preview
        !           456:     Id:         kupupreview
        !           457:     Action:     string:${object_url}/variant/thumbnail
        !           458:     Condition:  [empty]
        !           459:     Permission: View
        !           460:     Category:   object
        !           461:     Visible?    False
        !           462: 
        !           463:   - Hit the 'Add' button.
        !           464: 
        !           465: 
        !           466: Futures
        !           467: -------
        !           468: 
        !           469:   * Cached XSLT (need Sarissa support for this)
        !           470: 
        !           471:   * Deeper standards support (WebDAV/DASL)
        !           472: 
        !           473: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>