Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript templating language in reverse

Is there anything like a templating engine (a la Mustache.js) that can do templating in "reverse"?

That means that I provide rendered html and a template file, run it through the engine, and get data from it (say a JSON structure).

I realize this is the sort of thing that could be done with a "screen scraping library", but I have never seen a screen-scraping library that uses mustache-style templates (whatever those are called).

like image 927
themirror Avatar asked Aug 11 '13 04:08

themirror


1 Answers

A generic solution doesn't exist. E.g. you can never reverse the following template: {{foo}}{{bar}}, since it is impossible to find where the first mustache stops and the second one starts.

For example:

html: 'hello world!'
template: '{{foo}}{{bar}}'
model: {
    foo: '',
    bar: 'hello world!'
}
model2: {
    foo: 'hello world!',
    bar: ''
}

model and model2 both render the exact same html from the template, so they are both valid reverses.

But if you make some rules for the templates, it is possible to do this without ambiguities.

Rules:

  1. Two mustaches can never touch (explained above).
  2. The beginning of the content of a mustache can never be the same as the first text part after the mustache (or we cannot find the end of the mustache).
  3. The first text part in a section can not be the same as the first text part after a section (or we cannot find the end of the section).
  4. It is better to not use the richtext {{{}}} mustache (it is allowed to contain anything, so reverse matching means it can match the rest of the document).

These rules seem to be very restrictive for plaintext, but for xml and html they work pretty well (if you are only interested in element and attribute contents). Rule two is never a problem if you only use plaintext {{}} mustaches for instance.

The following template can be reversed without any ambiguities for instance:

<div>
    <p>{{title}}</p>
    <ul>
        {{#list}}
            <li>{{item}}</li>
        {{/list}}
    </ul>
</div>

But adding another <li> just before the </ul> will make the template ambiguous (rule 3).

I haven't found any code online that does this, so I have started writing a library for this. But it isn't finished by far, and every time I work on it, I find new limitations. Only for really simple templates this works ok (the only mustaches I allow are {{}}, {{#}} and {{/}}).


I found a solution using another templating system: https://github.com/fabiomcosta/mootools-meio-template/tree/master. It seems to have the same limitations.

like image 127
blerik Avatar answered Oct 06 '22 00:10

blerik