javascriptpythonecmascript-6mako

JavaScript template literals in a Mako template


I have a Mako file (that my Python server converts to HTML) that contains a script element with a JavaScript ES6 template literal. As both Mako and JS recognise ${..}, I am forced to write ${'${..}'} to get JS templating to work —${{..}} akin to an f-string does nothing and I cannot find a | flag that would escape it. Say

<script>
//This is just an example
let entry = {title: '${some_py_value}'} //Mako templating
$('body').append(`${'${entry.title}'}`); //JS templating
</script>

This works but looks awkward, like something you'd see in Perl, to the point that I often revert to string concatenation —generally a sign that there is a more elegant solution lurking. Is there one?


Solution

  • The templating can be turned off using the tags <%text> and </%text> (ref). Anything in between will be rendered as text and not parsed.

    <script>
    //This is just an example
    let entry = {title: '${some_py_value}'} //Mako templating
    <%text>
    $('body').append(`${entry.title}`); //JS templating
    </%text>
    </script>
    

    This has the advantage over ${'${jsVariable}'} if the two are not intermixed, i.e. one is passing the Python variables in JS first all at once, which is what should be happening*. The catch is %if and %for will not work in %text blocks, but those ought to JS encoded.

    ∗) Okay, ideally, the HTML page served should be generic without with the main JS code externally as a single file with the user data filled by several ajax requests. Although there are always corner-cases (e.g. Huge Python non-JSON serialisable objects with a complicated and computationally heavy method that needs to be frequently called but cannot be run as series of ajax request as the data needs to initialized first but cannot be stored serverside etc.).