twig.js icon indicating copy to clipboard operation
twig.js copied to clipboard

# Feature Request: Compile template with subTemplates (includes) to allow execution in different environments

Open yaronuliel opened this issue 1 year ago • 0 comments

Hi, I'm trying to compile a twig template on server, and then use the compiled template on client

Everything works fine, until I encounter an include statement. When I have an {% include "./file.twig" %} statement - the precompiled script - contains a Twig.logic.type.include token, but it doesn't contain the contents of this template

I'd expect precompile to recursively compile all included templates, so that it is executable in contexts other than the one that compiled it (like in my case - compiled on server, run on client, where access to the source templates does not exist)

Example for my files:

// Filename: templates/main.twig

My name is: {{user_name}}
{% include "./address.twig" with { street: user_street, city: user_city } %}
My phone is: {{user_phone}}
// Filename: templates/address.twig

My Street: {{street}}
My City: {{city}}

Compilation script (running on server, node.js):

import Twig from "twig";

Twig.twig({
  path: "./templates/main.twig",
  load(template) {
    const compiled = template.compile();
    console.log(compiled);
  },
});

The result given:

twig({id:"./templates/main.twig", data:[{"type":"raw","value":"My name is: "},{"type":"output","stack":[{"type":"Twig.expression.type.variable","value":"user_name","match":["user_name"]}]},{"type":"raw","value":"\n"},{"type":"logic","token":{"type":"Twig.logic.type.include","only":false,"ignoreMissing":false,"stack":[{"type":"Twig.expression.type.string","value":"./address.twig"}],"withStack":[{"type":"Twig.expression.type.object.start","value":"{","match":["{"]},{"type":"Twig.expression.type.operator.binary","value":":","precidence":16,"associativity":"rightToLeft","operator":":","key":"street"},{"type":"Twig.expression.type.variable","value":"user_street","match":["user_street"]},{"type":"Twig.expression.type.comma"},{"type":"Twig.expression.type.operator.binary","value":":","precidence":16,"associativity":"rightToLeft","operator":":","key":"city"},{"type":"Twig.expression.type.variable","value":"user_city","match":["user_city"]},{"type":"Twig.expression.type.object.end","value":"}","match":["}"]}]}},{"type":"raw","value":"My phone is: "},{"type":"output","stack":[{"type":"Twig.expression.type.variable","value":"user_phone","match":["user_phone"]}]}], precompiled: true});

Actual Behavior:

In the result, you can see that the address.twig template is references, but it's content isn't - so in order to render this compiled template, it must run in an environment that has access to templates/address.twig (or precompiled version of it in the cache)

Expected Bahavior

The precompiled template should have no dependency on the environment on which it will run - it should traverse through all the includes in the files, and include then in a way that you are able to compile the template on the server, and than send it to somewhere else (different server, client) and run in it successfully

Note: It is technically possible to traverse over the Twig.logic.type.include token manually and precompile all of them, but it makes no sense

yaronuliel avatar May 05 '23 00:05 yaronuliel