Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Handlebars

Quokka uses Handlebars for it's template engine, for it's simlplicity and flexibility.

Handlebars helper

The Handlebars engine in Quokka provides some additional helpers on top of the built-in helpers

Quokka helpers

  • version - Prints your crates version (for example to cache-invalidate resources when a new version in deployed)
  • concat - Concats any amount value that can be represented as a string
  • array - Allows to compose an array from it's parameters (eg. (array 1 2 3 ... ))
  • object - Allows to compose an objects from it's named parameters (eg. (object a=1 b=2 ... ))
  • add, sub, mul, div - Mathematical operations
  • len, is_empty - Operations to check the length (or length = 0) of strings or objects
  • debug - Debug-prints ("{:#?}") a statement to the console with the log level "Debug"
  • markdown - Renders markdown from a variable given in the markdown= key
  • safe_markdown - Does the same as the markdown helper, but does not escape the raw markdown input

Builtin blocks

  • if - Evaluates a condition and returns either the value if true or the default value if false.
  • unless - Evaluates a condition and returns the default value if the condition is true, otherwise returns the value.
  • each - Iterates over an array or object and applies a function to each item.
  • with - Wraps the current context with a new context, allowing you to reuse variables in your templates.
  • lookup - Looks up a variable in the context using its key.
  • raw - Outputs raw content directly to the HTML output.

Builtin helpers

  • eq - Checks if two values are equal.
  • ne - Checks if two values are not equal.
  • gt - Checks if a value is greater than another.
  • gte - Checks if a value is greater than or equal to another.
  • lt - Checks if a value is less than another.
  • lte - Checks if a value is less than or equal to another.
  • and, or, and not - Perform logical operations on conditions.
  • log - Logs information about the rendering process.

String Manipulation

  • lowerCamelCase, upperCamelCase, snakeCase, kebabCase, shoutySnakeCase, shoutyKebabCase, titleCase, and trainCase: Convert strings to different case formats.

About template paths

While the simplest method of registering a template set is by using the Templating::register_embedded_templates, there is also the Templating::register_embedded_templates_aliased_partials. If you follow a setup for your template/styling needs like described in the Structure chapter, this will be helpful for you.

The described structure suggests something like this:

web/templates/module_name/
└── partials
    └── component_name
        ├── component_name.html.hbs
        ├── component_name.scss
        └── component_name.js

Using this structure will force you to make your partial imports pretty messy, like this

{{>module_name/partials/component_name/component_name.html.hbs}}

But when using the Templating::register_embedded_templates_aliased_partials method for registering your template resource, you can skip the module_name part and the repetition for the component_name. This results in a way smaller path.

{{>partials/component_name}}

{{>module_name/partials/component_name}} {{! also valid and scoped to the module }}

A nice side effect of including partials from the partials directory is, that other modules can add on to your partials. Lets assume the following:

  • Module 1 has module_1/partials/my_component/my_component.html.hbs
  • It uses it as {{>partials/my_component}}

You can now go and register your template as my_module/partials/my_component/my_component.html.hbs and add on to the other template

Something before their partial

{{>module_1/partials/my_component}}

Something after their partial

Now this might depend on the loading order, but if everything is correct, the including template will see your my_module/* template and use that instead of the original one. If you want to prevent it from doing this, you can of cause always put your module name in the include {{>module_1/partials/my_component}} and circumvent this possibility.