slingsightlyhtl

Applying a master page template in Sling with HTL


Is there any simple way to apply a page template to multiple Apache Sling scripts?

I'm looking for something akin to the JSP 2.0 Tag option. However, I'm using HTL, which doesn't support such tags.

I could, of course, use HTL includes, such as data-sly-include="${'header.html'}, but these would then have to be manually included in every page I then create.

Ideally I'd like to be able to have a master page containing the layout, which is then automatically applied to all pages of specified resource types, leaving a customisable area for content specific to each resource. I'd then be able to limit my add.html, edit.html, html.html (etc) files to include only a block of code for the content section of the page, preventing unnecessary duplication of layout code across multiple files.

I thought I might be able to achieve this by creating a master page resource (e.g. "page"), then setting sling:resourceSuperType on the individual resources but since this acts as a fallback, it'll only kick in if there's no matching script for the sling:resourceType - and there will be such scripts.


Solution

  • I ended up using the following approach:

    1. Add a new resource type page
    2. Create a Sightly/HTL template file for the page resource type (/apps/page/html.html); this is the 'master' page template
    3. Include common elements in that template
    4. Within that template, call the 'child' templates by adding the view selector through the following HTL element: <div data-sly-resource="${request.pathInfo @ selectors='view', addSelectors=request.requestPathInfo.selectors, requestAttributes=request.requestParameterMap}">
    5. For each sling:resourceType that's to be rendered as a page, add a view subfolder (/apps/example_type/view) and place its HTL templates within that folder (e.g. add.html, html.html)
    6. On each resource that should be rendered with the master template, set sling:resourceSuperType to page

    When a request comes in to, for example, /content/example_type_instance.add.html, Sling resolution will therefore try to find a script in /apps/example_type/add.html; there isn't one, so it falls back to the resourceSuperType script in apps/page/html.html, which in turn will use the script in /apps/example_type/view/add.html.

    This seems to work for the moment. @Vlad's approach with a Sling ResourceDecorator may be more elegant.