Skip to content

Working with templates

Lukasz Sielski edited this page Apr 20, 2016 · 1 revision

Paths

Template paths

<APPLICATION>/<MODULE>/<...PATH>

  • cms maps to lackey default resources (cms/core/partials/header)
  • ~ maps to project (~/core/my-template)
  • . maps current module (./my-template) - this method has problems because DustJS and Adaro architecture

Consider your project, in sites/default/modules/core/server/views you have following templates

  • index.dust
  • partials
    • main.dust
    • header.dust

They may look as follows:

index.dust

{>"~/core/partials/main" title="Index"/}

{<content}
    Hello world
{/content}

main.dust

<html>
    <head>
        <title>{title}</title>
    </head>
    <body>
        {> "~/core/partials/header" /}
        <main>
            {+content}
                <h1>No content provided!</h1>
            {/content}
        </main>
    </body>
</html>

header.dust

<h1>{title}</h1>

Document Model

Each page, before passed to template engine is composed as obfuscated JSON document. You can preview this document, when you navigate to some page adding .json extendsion in the path.

Let's assume we created /mypage route. If you navigate to /mypage.json you would see:

{
    "data": {
        "route": "http://localhost:8888/mypage",
        "content": { ... }
    },
    "template": "~/core/dynamic",
    "stylesheets": [ ... ],
    "javascripts": [ ... ],
    "user": { ... },
    "admin" : { ... }

You can notice that data.content.$uri would be URL that you can access and get exactly the same content as in object data.content.

That is because in the system we have two sort of endpoints for the page:

  • /mypage or /mypage.json is view - data composed and prepared in context of viewing user with all third party content that should be added while rendering
  • /api/cms/content/123456 is API endpoint that will return RAW page definition.

Helpers

Editable

Uses ProseMirror to printout HTML content or WYSIWYM editor.

{@editable content=data.content path="title" editMode=edit type="heading"/}
Field Type Required Description
content object Y object to be scanned
path string Y path to walk as dot separated indexes
variant string N name of variant, if should be used
editMode boolean N if should be editable
type string N ProseMirror schema to be used, null for default or heading for simplified

Media

Printout media object (depending on type attribute)

  • Image or Video by default
  • Default media object source for url
  • Data attributes for media picker linking for hook
{@media content=data.content path="title" editMode=edit /}
Field Type Required Description
content object Y object to be scanned
path string Y path to walk as dot separated indexes
variant string N name of variant, if should be used
editMode boolean N if should be editable
type string N as defined above
attr-* string N any such attribute will be re-applied to output element

Example: background image

<article class="person" data-theme="{theme}"
         {@media content=data.content path="headshot" type="hook"/}
         style="background-image: url({@media content=data.content path="headshot" type="url"/}); background-size: cover;"
         >
</article>

Example: image with custom class

{@media content=data.content path="image" attr-class="myCSSClass"/}

Embed

Renders given template with content referred by route

Deprecated this helper will be fully replaced by Block.

{@embed template="~/core/partials/block/media-copy-cta" theme="green" route="/work/company" edit=edit/}
Field Type Required Description
template string Y DUST template to be used
route string Y Route to content object to be rendred
type string N Optional content object type
  • (any other) | mixed | N | Any extra attribute would be passed to new DustJS context created while rendering

Block

Renders given template with given or referred content (this helper is used by dynamic site builder).

{@block content=data.content path="myPath"/}

It expects content object to match example:

{
    "type" : "Block",
    "template" : "~/template/route",
    "fields" : { ... },
    "route" : "/some/route",
    "props" : { ... }
}

Example - hero widget as YAML

type: Block
template: ~/core/partials/hero
fields:
    title: My title
    subtitle:
        *: Main subtitle
        *:*:pl: Polski podtytuł

Example - embeded aticle as YAML

type: Block
template: ~/clore/partials/small
route: /embeded/article

List

Renders list of blocks. This helper is used by dynamic site builder.

{@list content=data.content path="myPath"/}

Attr

{@attr content=data.content path="title"/}
Field Type Required Description
content object Y object to be scanned
path string Y path to walk as dot separated indexes
variant string N name of variant, if should be used
state string N name of state, if should be used
editMode boolean N
type string N

Helpers data lookup

TreeParser.get

This method is used by all helpers to walk layout object and get most suitable value. Each value can be mapped by path and three optional parameters:

  1. Variant - i.e. to differ original title from version for hub page
  2. State - i.e. to vary content on data from custom controller logic
  3. Locale - to vary content by language and region
module.exports.get = function (root, path, variant, state, locale)
Field Type Required Description
root object Y object to be scanned
path string Y path to walk as dot separated indexes
variant string N name of variant, if should be used
state string N name of state, if should be used
locale string N name of locale, if should be used

Examples

let obj = {
    "abc" : {
        "def" : "Hello world",
        "ghi" : {
            "type": "Variants",
            "*" : "Hi there",
            "hero:*:*" : "Hi hero!",
            "*:*:pl" : "Cześć"
        }
    }
};

module.exports.get(obj, "abc.def"); // Hello world
module.exports.get(obj, "abc.ghi"); // Hi there
module.exports.get(obj, "abc.ghi", "hero"); // Hi hero!
module.exports.get(obj, "abc.def", "hero"); // Hello world
module.exports.get(obj, "abc.ghi", null, null, "pl"); // Cześć
module.exports.get(obj, "abc.ghi", "hero", null, "pl"); // Hi hero!
module.exports.get(obj, "abc.def", null, null, "pl"); // Hello world

editable.fromLayout

This method is used to stringify ProseMirror document format. At the moment is used in two cases:

  • Editable - to produce end user, non-editable ouput
  • Attr - to change formatted text to simple string values for HTML attributes
fromLayout(root, path, variant, locale, type, route, toFormat)
Field Type Required Description
root object Y object to be scanned
path string Y path to walk as dot separated indexes
variant string N name of variant, if should be used
locale string N name of locale, if should be used
type string N schema type to be used (heading or null)
route string N current page route - used for tweetable quotes (likely to be obsolete)
format string N text or null for HTML