Last active
December 27, 2015 12:48
-
-
Save adamblank/7328089 to your computer and use it in GitHub Desktop.
_.reverseTemplate() attempts to reverse engineer the original object used to generate a rendered underscore.js template output by comparing the output string to the template string.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Extend the underscore global object with the following method: | |
| * | |
| * https://gist.github.com/adamblank/7328089 | |
| * | |
| * reverseTemplate attempts to reverse engineer the original object used to generate | |
| * the rendered output by comparing the output string to the underscore template string. | |
| * | |
| * Paramaters | |
| * - renderedOutput - the string that was generated from the template | |
| * - template - the template string used to generate the compiled underscore template (not the compiled template function.) | |
| * | |
| * Dependencies | |
| * - underscore.js | |
| * | |
| * Limitations | |
| * - This method can only reverse engineer templates that only use interpolation | |
| * - Values used in template must be top-level properties only (i.e. { prop: 'value' } NOT { obj: { prop: 'value }} ) | |
| * - Interpolation values cannot be right next to each other (e.g. <%= name %><%= age %>) | |
| */ | |
| _.reverseTemplate = function(renderedOutput, template) { | |
| function extractValue(renderedOutput, template, resultObj) { | |
| //get underscore's template interpolation regular expression (remove global flag) | |
| var regex = _.templateSettings.interpolate instanceof RegExp ? new RegExp(_.templateSettings.interpolate.source) : _.templateSettings.interpolate, | |
| match = template.match(regex), | |
| prop, | |
| templateSplit, | |
| secondSplitPivot, | |
| value; | |
| if (!match) { | |
| return resultObj; | |
| } | |
| //get the specifc template interpolation property | |
| prop = match[1].replace(/ /g,''); | |
| templateSplit = template.split(match[0]); | |
| //grab subsection between this interpolation placeholder and the next (if any) | |
| secondSplitPivot = templateSplit[1].split(regex)[0]; | |
| //slice off everything before interpolation value | |
| value = renderedOutput.replace(templateSplit[0], ''); | |
| //if theres more after the value, slice it off also | |
| if (secondSplitPivot) { | |
| value = value.split(secondSplitPivot)[0]; | |
| } | |
| resultObj[prop] = value; | |
| return extractValue(renderedOutput, template.replace(regex, value), resultObj); | |
| } | |
| return extractValue(renderedOutput, template, {}); | |
| } | |
| /* | |
| * Test | |
| */ | |
| //change underscore's templating interpolation delimiter to something nicer (not required) | |
| _.templateSettings = { | |
| interpolate: /\{\{(.+?)\}\}/g | |
| }; | |
| _.reverseTemplate('this is a test to make sure extractTemplateValues works', 'this is a {{ activity }} to make sure {{ plugin }} {{ status }}'); | |
| //outputs: Object {activity: "test", plugin: "extractTemplateValues", status: "works"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment