GenericEditorAPI

This page describes the Lenya editor API as it slowly evolves into shape. It might eventually contain all the information you need to make an editor of your choice work with Lenya. Currently, it is incomplete, since it omits the Java usecase handler side of things.

Quick start: how to make your editor work with Lenya

  1. Create a module named after your editor (check our [WWW] modules documentation).

  2. Create a Java usecase handler, either by

    1. stealing the code from the editors module, putting it in $YOURMODULE/java and applying necessary changes (current practice, BAD!), or

    2. using it as it is (then you don't need to copy it) (good practice, not widely used - if you feel the existing stuff is not versatile enough, abstract your needs and put them upstream!).

    • (FIXME: is the code from the editors module the best one we have?)

      For inspiration, read our [WWW] usecase documentation.

  3. Create a usecase view: either steal it from the One-Form-Editor (JXTemplate-based, for an out-of-context form: [WWW] oneform.jx), or follow the TinyMCE approach for an in-place WYSIWYG editor (pipeline-based, check out the sitemap (<match pattern="tinymce.edit">) and the XSLT! See below under #WYSIWYG).

  4. Register your editor usecase by writing an xpatch file in $YOURMODULE/config/cocoon-xconf/usecase-edit.xconf:

  1. Make sure that your view adds the following javascript snippets:

  1. Create some hooks in your editor:

    1. "Insert Lenya Link",

    2. "Insert Lenya Image", and

    3. "Insert Lenya Asset",

Using server-side validation

Requirements:

Each editor should be able to handle validation errors from the server gracefully. It must receive the appropriate error messages from the server, display them to the user, and keep the file checked out!

This implies that the transmission of the document data and the receiving of result messages should happen via AJAX. thus it's a task for well after 2.0 is out.

FIXME!

Writing a usecase handler for your editor

FIXME!

Spiffing things up with AJAX

FIXME!

Writing in-place true WYSIWYG editors

If you're keen to provide true WYSIWYG editing, you must delegate the rendering of the page to the publication sitemap, since your editor module cannot know about the correct rendering. This can be accomplished by mounting the publication sitemap into the editor sitemap. You can then take the output of the publication pipeline and apply editor-specific pre-processing (such as adding javascript code or working around editor-specific quirks).

Under no circumstances should you hack any workarounds into global sitemaps or publication resources.

A possible approach (taken from the tinymce module) is this:

    <map:pipeline internal-only="yes">

      <!-- when editing, the page should look exactly like the original, and since
           we cannot know anything about the pipelines used for rendering, we must
           delegate the job to the publication's own sitemap. -->

      <map:match pattern="tinymce.delegateToPubSitemap/**">
        <map:mount src="{fallback:{page-envelope:publication-id}:sitemap.xmap}" uri-prefix="tinymce.delegateToPubSitemap"/>
      </map:match>

      <!-- the usecase framework provides error and info messages. since we bypass
           the jxtemplate view mechanism, we must include them by hand. -->

      <map:match pattern="tinymce.getUsecaseMessages">
        <map:generate type="jx" src="fallback://lenya/modules/usecase/templates/messages.jx"/>
        <map:transform type="i18n">
          <map:param name="locale" value="[request:locale}"/>
        </map:transform>
        <map:transform src="context://lenya/xslt/util/strip_namespaces.xsl"/>
        <map:serialize type="xml"/>
      </map:match>
    </map:pipeline>

    <map:pipeline>

      <!-- this is the view of the usecase (see config/cocoon-xconf/usecases.xconf) -->

      <map:match pattern="tinymce.edit">
        <!-- check if TinyMCE is installed -->
        <map:select type="resource-exists">
          <!-- render page with tinymce inserted -->
          <map:when test="fallback://lenya/modules/tinymce/resources/tinymce/jscripts/tiny_mce/tiny_mce.js">
            <map:aggregate element="tinymceWrapper">
              <map:part src="cocoon:/tinymce.delegateToPubSitemap/authoring{page-envelope:document-url}"/>
              <map:part src="cocoon:/tinymce.getUsecaseMessages"/>
            </map:aggregate>
            <map:transform src="fallback://lenya/modules/tinymce/xslt/page2edit.xsl">
              <map:parameter name="contextPath" value=""/>
              <map:parameter name="continuationId" value="{flow-continuation:id}"/>
              <map:parameter name="usecaseName" value="{request-param:lenya.usecase}"/>
              <map:parameter name="publicationid" value="{page-envelope:publication-id}"/>
            </map:transform>
          </map:when>
          <!-- TinyMCE is not installed - generate info page for the user -->
          <map:otherwise>
            <map:generate src="fallback://lenya/modules/tinymce/resources/misc/download.xml"/>
          </map:otherwise>
        </map:select>
        <map:call resource="style-cms-page"/>
        <map:serialize type="xhtml"/>
      </map:match>
 
    </map:pipeline>

FIXME: This sitemap duplicates the "style-cms-page" resource. It would be great if such resources could be provided just once by a global sitemap and then included, but resources of other sitemaps are not accessible. If anyone has an idea how to factor this out, let me know.

last edited 2007-07-28 22:45:57 by JörnNettingsmeier