Note: this is written by a complete beginner with Lenya. Some methods might be the most complex ways to solve a problem there are. Or even explode your computer and eat your cat.

Overview

This howto describes how you can modify the structure of the HTML pages your Lenya application produces. If you are looking for ways to change the look of your publication, please read the ApplicationLookandFeelHowto first - it describes much easier ways to reach your goal.

The default Lenya 1.2 application lays out pages with a pretty straightforward table-based structure defined in lenya/pubs/your-pub-name/xslt/page2xhtml.xsl, which is a HTML skeleton acting as a template page similar to JSP-based sites. Lenya navigational components are inserted by several <xsl:apply-template> blocks.

This pre-defined HTML-structure contains the Lenya logo and the welcome notice which you will most likely wish to remove. Furthermore, modifications to the structure are necessary if you:

There are three ways in which you can influence the page structure of the live pages (the user view):

  1. by modifying the overall page layout, ie. tables, divs and their ids/classes. By hacking page2xhtml.xsl, you can arrange the predefined navigational components like tabs, menus and search fields, you can introduce new divisions tables, and add images,
  2. changing the inner markup of the navigational components. This is slightly more complex since you need to edit lenya/pubs/publication-name/xslt/page2xhtml.xsl, lenya/pubs/publication-name/publication-sitemap.xmap, and one or more of the components' XSL files. On the other hand, it is the way to go if you need to influence the way a component works or need to influence the HTML chunk it produces,

  3. changing the wrapper div produced by one or more of the components. Each navigational component produces a wrapper div around the generated HTML chunk mentioned above with an id corresponding to the component's name.

Any modifications you perform are "live" - reloading the page in your browser will show you the effects.

If you are new to Cocoon and/or Lenya, it is advisable to read Lenya Documentation >> The Navigation Framework to get an idea on the way HTML chunks are produced and aggregated to yield the final output.

Modifying the live page structure

Changing the overall page layout

page2xhtml contains one template which is invoked by the pipeline in lenya/pubs/publication-name/xslt/page2xhtml.xsl. It matches <cmsbody> and produces the overall HTML page by defining head- and body-segments and applying templates for the navigation, tabs, bread-crumbs, search, and body-content.

You are free to replace the table-structure with any valid XHTML construct, but you should not re-use the ids assigned to the menu, tabs, and search components. Do not rename the parameters of {{{<xsl:apply-templates select="xhtml:foo[@bar = 'baz']"/> either. }}}

page2xhtml is called with three parameters you can use to include resources or give information:

  1. $root. This is the current servlet context and will resolve to /lenya/ by default,
  2. $document-id. This is the document id Lenya uses to identify the current page,
  3. $url. This is the request URL pointing to the current page.

For example, if you want to add the current URL to printouts of you page, insert:

   <div class="printonly">From: mydomain.org<xsl:value-of select="$root"/><xsl:value-of select="$url"/></div>

and define .printonly {display: none; } on screen in your CSS-files.

Modifying navigational components

Lenya cascades navigational component definitions in a way described in Lenya Documentation >> The Navigation Framework and the ApplicationLookandFeelHowto. In short, local versions take precedence over installation-wide versions.

To edit components, copy them to your publication as described in the look and feel howto. To ensure long-time maintainability, it is useful to rename your local versions to create a clear distinction between the Lenya default components and your modified ones. To do this, rename the copies in your file system, then open lenya/pubs/publication-name/publication-sitemap.xmap in your text editor and look for the following pipeline:

<!-- This is the pipeline that builds the page. It aggregates all
    the navigational elements (breadcrumb, tabs, menu) with the actual
    content of the document. -->
    <map:pipeline>
      <!-- /lenyabody-{rendertype}/{publication-id}/{area}/{doctype}/{url} -->
      <map:match pattern="lenyabody-*/*/*/*/**">
        <map:aggregate element="cmsbody">
          <map:part src="cocoon://navigation/{2}/{3}/breadcrumb/{5}.xml"/>
          <map:part src="cocoon://navigation/{2}/{3}/tabs/{5}.xml"/>
          <map:part src="cocoon://navigation/{2}/{3}/menu/{5}.xml"/>
          <map:part src="cocoon://navigation/{2}/{3}/search/{5}.xml"/>
          <map:part src="cocoon:/lenya-document-{1}/{3}/{4}/{page-envelope:document-path}"/>
        </map:aggregate>

The aggregate-part lists all components that should be called prior to assembling the pages.

For example, if you intend to modify the tabs component and your local file is lenya/pubs/your-pub-name/lenya/xslt/navigation/mytabs.xsl, change

          <map:part src="cocoon://navigation/{2}/{3}/tabs/{5}.xml"/>
to 
          <map:part src="cocoon://navigation/{2}/{3}/mytabs/{5}.xml"/>

Save the modified publication-sitemap.xmap and start hacking mytabls.xsl.

Changing a component's wrapper

WARNING: this is not for the faint of heart. If you are unexperienced, you should think twice before changing the IDs or replacing the generated divs by other tags. Hacking this mechanism is a rather large modification which could result in one of the editors to stop working.

Lenya matches the tag and id of a navigational component as defined in the respective .xsl file against the <xsl:apply-template> in page2xhtml. If you redefine it in one place, you must do so in the other or else the template will no longer be called (the component vanishes from the pages).

The special case of the body-div

Lenya renders the content of a page into <div id="body">. The content for this division is not derived from a navigational component, but from the file lenya/pubs/your-pub-name/xslt/xhtml2xhtml.xsl. Since some editors rely on the HTML structure provided by xhtml2xhtml, it is advisable not to touch it.

If you have compelling reasons to modify the body HTML chunk, you absolutely must not insert anything between the two lines:

<div id="body"> (or whatever your body wrapper is named)
  <xsl:if test="$rendertype ='edit'">

or else the bitflux editor will complain about a missing BXE_path definition.

Creating anchors for headers

You can automatically add anchors to any sectioning element (h1, h2, ...) by creating a template in page2xhtml.xsl so that an anchor is inserted just before each occurrence of the element of your choice. For h2 elements this would be:

<xsl:template match="xhtml:h2">
  <a name="{normalize-space( translate( text(), ' ', '_' ) )}"/>
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

Then if a section is entitled "Some example title" you can add an internal link pointing to it with the URL "#Some_example_title". For listing all the internal sections, usually on the top of the page, you can choose a keyword (in the code below "anchorListing") and add another template:

<xsl:template match="xhtml:h2[ normalize-space( text() ) = 'anchorListing' ]">
  <xsl:for-each select="//xhtml:h2[ normalize-space( text() ) != 'anchorListing' ]">
    <a href="#{normalize-space( translate( text(), ' ', '_' ) )}">
      <xsl:value-of select="normalize-space( text() )"/>
    </a><br/>
  </xsl:for-each>
</xsl:template>

Now if you insert a h2 element with "anchorListing" as the enclose text, the stylesheet will produce the list of all the sections in the document.

Modifying the authoring page structure

Adapting the login screen

The outer HTML comprising title, stylesheet and Lenya logo and "Open Source Content Management System" claim is defined by lenya/xslt/util/page2xhtml.xsl.

The inner HTML (lenya/levi password prompt, "login to the xxx publication" and copyright remark is derived from lenya/xslt/ac/login.xsl.

Changing the overall page layout

Contrary to the live pages, the HTML of the authoring page is not solely defined by page2xhtml, but lenya/xslt/menu/menu2xslt.xsl produces the outer structure. This file is in the global area, but a fallback-mechanism is in place that allows you to make publication-specific changes. To use a publication-specific authoring HTML, you need to create a publication-local version which can be picked up by the fallback mechanism:

  1. Create the directory lenya/pubs/publication-name/lenya/xslt/menu/

  2. copy lenya/xslt/menu/menu2xhtml.xsl to lenya/pubs/publication-name/lenya/xslt/menu/

  3. copy lenya/xslt/menu/menu2xslt.xsl to lenya/pubs/publication-name/lenya/xslt/menu/

If you rather would modify the authoring HTML for all your publications, you can edit lenya/xslt/menu/menu2xslt.xsl and include publication-specific resources like CSS-files if you adress them like <link href="{$contextprefix}/{$publicationid}/{$area}/css/yourpubauthstyle.css" type="text/css" />. This will reference an authoring CSS-file specific to one publication if you need to hide or override the placement of your HTML-structures in the authoring view (e.g. if they get in the way of the Lenya menu bar).

Modifying the Lenya menu bar

You find more information in The Lenya Menubar in the Lenya documentation.

The Lenya menu bar is a HTML chunk produced by lenya/xslt/menu/menu2xhtml.xsl and aggregated by menu2xslt.xsl. The HTML it produces is wrapped into a division <div id="lenya-menubar"> refererenced by the aggregation.

A fallback mechanism is in place so you can make publication-specific changes (see above).