templatesemail-templatesmarko

Rendering from strings instead of files with MarkoJS


I'm using markojs for my emails templates but now we are moving these templates inside our database to edit them online. We still need to use marko to keep our full HTML structure and variables behavior aswell.

I've found 2 ways to get templates as string like renderSync() method but it need the template to exist as file before or with compile() but I don't know how to make it work with variables handling.


Solution

  • You can use Marko's load method to compile templates and get back the template instance which you can then render to get the final HTML:

    const template = require("marko").load(templatePath, templateSource, compilerOptions);
    const html = template.renderSync(data);
    

    You probably don't need to pass any custom compilerOptions and can omit the last argument.

    Even though your template doesn't exist on disk, you still need to pass a templatePath to a real directory with a dummy .marko file. For instance you could do this:

    const templatePath = path.join(__dirname, `${database.id}.marko`);
    

    The templatePath is used for two purposes:

    1. As a key for node's require cache. If you request to compile the same filename multiple times, you will get the original compilation. This might mean you need to purge the require cache when a template is edited: delete require.cache[templatePath];
    2. To discover custom Marko tags. If you have custom tags/components that are intended to be used by the email templates, you should make sure that the path specified by templatePath allows those tags to be discovered.