samskivert / jmustache

A Java implementation of the Mustache templating language.
Other
834 stars 128 forks source link

Show all available variables at a specific template position #87

Closed jfiala closed 7 years ago

jfiala commented 7 years ago

Is it possible to print out all available variables at a specific position in the mustache template for debugging purposes / to explore the available variables if you don't want to check this in the sourcecode?

If not, do you think it makes sense to add this feature?

Best regards, Johannes

samskivert commented 7 years ago

You could do this with a Lambda. The actual enumeration depends on what you use to provide data to your templates. If you only use maps from keys to values, then you could just enumerate the contents of those maps, if you use Java objects and access fields via reflection, then you'd need to use reflection to enumerate all the fields of all the objects and subobjects. In both cases you'd have to take care to avoid infinite loops if there are loops in your graph of accessible values.

Anyway, here's a simple test that just prints out the context object (which is what contains all of the accessible values).

    @Test public void testLambdaDump () {
        Map<String,Object> data = new HashMap<String,Object>();
        data.put("k1", "v1");
        data.put("k2", "v2");
        data.put("s1", context("sk1", "sv1", "sk2", "sv2"));
        data.put("dump", new Mustache.Lambda() {
            public void execute (Template.Fragment frag, Writer out) throws IOException {
                Object ctx = frag.context();
                System.out.println("Context " + ctx);
            }
        });
        System.out.println("--- TOP ---");
        Mustache.compiler().compile("{{#dump}}{{/dump}}").execute(data);
        System.out.println("--- NESTED ---");
        Mustache.compiler().compile("{{#s1}}{{#dump}}{{/dump}}{{/s1}}").execute(data);
    }

If you add this to src/test/java/com/samskivert/mustache/MustacheTest.java and run the tests (or adapt it into a standalone program), you'll see that it prints the top-level context when the lambda is run from the top level:

--- TOP ---
Context {k1=v1, k2=v2, dump=com.samskivert.mustache.MustacheTest$28@5bf0d49, s1={sk1=sv1, sk2=sv2}}

and when it's run from inside {{#s1}} then it gets just that sub-context:

--- NESTED ---
Context {sk1=sv1, sk2=sv2}