Liquid template trigger
A function with the trigger Liquid template is a helper that your templates can call while a page renders. You pass it named arguments, it returns a string, a number or a boolean, and the template prints or tests the result. This page covers the call syntax, how arguments and return values are converted, and why errors show up as empty output.
A working example
Create a function with the trigger Liquid template, the developer name helpers, and mark it active. Each top-level function in the code is a method you can call by name:
// Trigger: Liquid template. Developer name: helpers
// {{ raytha_function("helpers", "greet", name="Ada") }}
function greet(args) {
return "Hello, " + (args.name || "friend") + "!";
}
// {% assign total = raytha_function("helpers", "post_count", type="posts") %}
function post_count(args) {
var res = API_V1.GetContentItems(args.type, "", "", "IsPublished eq 'true'", "", 1, 1);
return res.Success ? res.Result.TotalCount : 0;
}
// {{ raytha_function("helpers", "latest_links", type="posts", count=5) }}
function latest_links(args) {
var res = API_V1.GetContentItems(args.type, "", "", "IsPublished eq 'true'", "CreationTime desc", 1, args.count || 5);
if (!res.Success) {
return "";
}
var html = "<ul>";
for (var item of res.Result.Items) {
var title = item.PrimaryField.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
html += '<li><a href="/' + item.RoutePath + '">' + title + "</a></li>";
}
return html + "</ul>";
}
Call the methods from any template, including widget templates and email templates:
<p>{{ raytha_function("helpers", "greet", name="Ada") }}</p>
{% assign total = raytha_function("helpers", "post_count", type="posts") %}
<p>{{ total }} posts so far.</p>
{{ raytha_function("helpers", "latest_links", type="posts", count=5) }}
Syntax
raytha_function("developer_name", "methodName", argName=value, other=value2)
- The first argument is the function's developer name. The second is the name of the JavaScript function to run.
- Arguments after that are named with
=, as incount=5. A colon, as incount: 5, is a template syntax error. - Raytha collects the named arguments into one JavaScript object and calls
methodName({...}). Your function takes a single parameter and readsargs.count. - Strings, numbers and booleans keep their type. Lists and objects are passed as JSON arrays and objects.
- Positional arguments arrive as
arg1,arg2, in order. Do not mix positional and named arguments in one call: the names attach to the wrong values. Use only one style.
The function must be active and its trigger must be Liquid template. An HTTP request function cannot be called from Liquid, and a Liquid function cannot be called by URL.
Return values
The function's return value is converted before the template sees it. Async functions work: Raytha waits for the promise.
| JavaScript returns | Liquid receives |
|---|---|
| A string | A string. {{ value }} prints it without HTML escaping, so escape anything user-supplied inside the function. |
| An integer that fits in 32 bits | A number. You can compare it and use it in filters. |
true or false | A boolean. Use it in {% if %}. |
null or nothing | Empty (nil). |
| A fractional number, a very large number, an array or an object | A JSON value that prints as JSON text. You cannot read its properties or loop over it in Liquid. |
A result helper such as JsonResult | An object you should not use here. Return the plain value. |
Because lists and objects cannot be traversed in Liquid, do the looping in JavaScript and return the finished HTML, as latest_links does above. For data that the template should loop over, prefer the built-in get_content_items template function.
Errors show up as empty output
The call returns nothing, and the page still renders, in each of these cases:
- The function does not exist, is inactive, or has a different trigger type.
- The method name does not exist in the code, or the code has a syntax error.
- The function throws, or runs longer than
RAYTHA_FUNCTIONS_TIMEOUT. RAYTHA_FUNCTIONS_MAX_ACTIVEis0, which turns Liquid calls off.- Either the developer name or the method name is empty.
No message is written anywhere. To debug, run the same code as an HTTP request function and call it with curl, or wrap the body in try and catch and return the error text while you test.
Performance
The call runs every time the page renders, one after another, and waits for the result. Nothing is cached. A slow function slows the page, and a page with ten calls runs ten V8 engines in sequence. Keep helpers to one small query, keep pageSize low, and do not call a Liquid function inside a loop.
Unlike HTTP and content event functions, Liquid calls do not queue on RAYTHA_FUNCTIONS_MAX_ACTIVE. They run as the page renders, so a traffic spike runs many at once.
Gotchas
- Colons are a syntax error. Write
name="Ada", notname: "Ada". A template that fails to parse cannot be saved. - No HTML escaping. The result of
raytha_functionis printed as-is. Use| escapein the template for plain text, or escape inside the function when you return HTML. - Objects are not traversable. Return strings, integers and booleans.
- Silent failure. A typo in the method name looks the same as an empty result.
- The function runs as the visitor's request.
CurrentUserreflects the person viewing the page.API_V1still has no permission checks, so a helper can return data the visitor could not otherwise see. - Pass ids and scalars, not model objects. Passing a whole
Targetserializes it to JSON, which is large and slow.
Next steps
- Built-in objects:
API_V1and the others. - Functions and filters: the template functions that return lists you can loop over.
- Recipes: more complete functions.
- Raytha Functions: limits and security.