mde / ejs

Embedded JavaScript templates -- http://ejs.co
Apache License 2.0
7.79k stars 843 forks source link

Fetching Include from a database? #745

Closed kylecribbs closed 1 year ago

kylecribbs commented 1 year ago

Hello all, was hoping someone can help me understand how I can override or use client:true callback function to fetch the include from database.

To give context, we are using Kotlin and GraalVM to run its JavaScript interpreter with EJS 3.1.8.

Here is what I have tried thus far:

let data = {};
let str = "Hello <%= include('./src/main/resources/ejs_templates/imports/imports.ejs', {}); %>";

var fn = ejs.compile(str, {client:true});

fn(data, null, function(path, d){ // include callback

    print("HELLO WORLD!!!!!") // THIS PRINTS

    print(path) // THIS PRINTS

    var includedTemplate = fileReader.test3(path); // This is a custom we created that reads the data and we have printed this out, and is working

    return includedTemplate;

  }); // returns rendered string

var rendered = fn(data);

however, var rendered = fn(data); is stating: undefined is not a function.

if I print just fn, the content is:

function anonymous(locals, escapeFn, include, rethrow
) {
rethrow = rethrow || function rethrow(err,str,flnm,lineno,esc){var lines=str.split("\n");var start=Math.max(lineno-3,0);var end=Math.min(...<omitted>...
}

so it is a function...

We were thinking this could be an issue because we are technically doing this server side; however, we are specifying client: true so we have also tried this:

print("I'm here");
// tried overriding how it fetches for the include file
ejs.includeFile = function(path,d){

    print("Did we reach the mecca?")

    return fileReader.test3(path);

}
// also tried this override just in case
ejs.include = function(path,d){

    print("Did we reach the mecca?")

    return fileReader.test3(path);

}

let data = {};

let str = "<%= include('./src/main/resources/ejs_templates/imports/imports.ejs', {});%>";

var fn = ejs.compile(str);

var rendered = fn.apply(data);

When we execute this we get:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.graalvm.polyglot.PolyglotException: Error: Could not find the include file "./src/main/resources/ejs_templates/imports/imports.ejs"] with root cause

org.graalvm.polyglot.PolyglotException: Error: Could not find the include file "./src/main/resources/ejs_templates/imports/imports.ejs"

Which to me means, we are not overriding the include fetch appropriately and its using the EJS default include fetch.

Does anyone have any thoughts on how could accomplish this?

kylecribbs commented 1 year ago

I am a dummy, it ended up being because I am not setting fn to anything...

            let data = {}
            let str = "<%= include('./src/main/resources/ejs_templates/imports/imports.ejs');%>";
            var fn = ejs.compile(str, {client:true});

            var rendered = fn(data, null, function(path, d){
                // include callback logic
                var includedTemplate = fileReader.test3(path);
                print(includedTemplate)
                return includedTemplate;
            }, null);

that resolved it