Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add Template Introspection

Signed-off-by: Matthias Schmeißer <mjs@grin.com>
  • Loading branch information...
commit 7cfa66c9c76104490cd8f294a0eca7ee0d88be42 1 parent f372761
Matthias Schmeißer authored
18 lib/gtpl.js
View
@@ -51,6 +51,7 @@ gtpl.DEFAULT_CONFIG = {
keep_containers: true,
use_yield_root: false,
add_metaobject: true,
+ introspection_mode: 'names',
empty_template_name: 'noop',
string_builder_function_name: 'StringBuilder'
};
@@ -1175,6 +1176,7 @@ gtpl.tokenizer = tokenizer;
TemplateNode.prototype.build = function() {
this.nodes = [];
this.meta_nodes = [];
+ this.namespace = S.namespace;
this.contains_param_node=false;
this.contains_container_node=false;
@@ -1203,6 +1205,9 @@ gtpl.tokenizer = tokenizer;
next();
}
+ //add end of closing template token position
+ this.last_pos = S.token.pos + S.token.full.length;
+
return this;
};
@@ -1397,6 +1402,15 @@ gtpl.tokenizer = tokenizer;
}
}
+ if(config.introspection_mode == 'names') {
+ res += TAB(d) + format('{0}.__self__ = {name: "{1}", namespace: "{2}"};',
+ function_name, this.template_name.join('.'), this.namespace.join('.')) + LB;
+ }
+ else if(config.introspection_mode == 'full') {
+ res += TAB(d) + format('{0}.__self__ = {name: "{1}", namespace: "{2}", source: "{3}", pos_start: {4}, pos_end: {5}};',
+ function_name, this.template_name.join('.'), this.namespace.join('.'), this.source, this.pos, this.last_pos) + LB;
+ }
+
return res;
};
@@ -1897,9 +1911,9 @@ TemplateManager.prototype.create_import_external_namespaces_code = function(exte
return eval_string;
}
-TemplateManager.prototype.add = function(template_string,source) {
+TemplateManager.prototype.add = function(input_string,source) {
//Step 1: Build all ASTs
- var ASTs = gtpl.buildTemplate(template_string, this.__config__, source);
+ var ASTs = gtpl.buildTemplate(input_string, this.__config__, source);
for(var i = 0; i<ASTs.length; ++i) {
var AST = ASTs[i];
1  test/test.html
View
@@ -21,5 +21,6 @@
<script type="text/javascript" src="test_multitemplate.js"></script>
<script type="text/javascript" src="test_export.js"></script>
<script type="text/javascript" src="test_meta.js"></script>
+ <script type="text/javascript" src="test_introspection.js"></script>
</body>
</html>
4 test/test.js
View
@@ -6,4 +6,6 @@ require('./test_cycle.js');
require('./test_literal.js');
require('./test_call.js');
require('./test_multitemplate.js');
-require('./test_export.js');
+require('./test_export.js');
+require('./test_meta.js');
+require('./test_introspection.js');
56 test/test_introspection.js
View
@@ -0,0 +1,56 @@
+var assert= assert || require('assert');
+var gtpl= gtpl || require('../lib/gtpl');
+var test_suite = test_suite || require('./test_suite.js');
+
+var deepCopy = gtpl.deepCopy;
+var esc = gtpl.escapeHTML;
+global.keys = Object.keys || function(obj) {var res = []; for(var i in obj) res.push(i); return res;};
+
+
+e_test = this.e_test || test_suite.e_test;
+e_throw = this.e_throw || test_suite.e_throw;
+s_test = this.s_test || test_suite.s_test;
+t_test = this.t_test || test_suite.t_test;
+m_test = this.m_test || test_suite.m_test;
+t_throw = this.t_throw || test_suite.t_throw;
+print_heading = this.print_heading || test_suite.print_heading;
+
+print_heading('Testing: Introspection');
+
+//Real Basics
+var t1,t2,t3,t4,t5,json,html;
+
+t1 = '{template T1}Hello{/template}';
+html = 'Hello';
+t_test('names introspection 1', {T1:t1},'T1',null,html, {introspection_mode:'names'});
+m_test('names introspection 2', {T1:t1}, function(tm) {
+ assert.equal(tm.T1.__self__.name, 'T1');
+ assert.equal(tm.T1.__self__.namespace, '');
+ assert.equal(keys(tm.T1.__self__).length, 2);
+}, {introspection_mode:'names'});
+
+t1 = '{namespace N1.N2}{template .T1.T2}Hello{/template}';
+html = 'Hello';
+t_test('names introspection 3', {T1:t1},'N1.N2.T1.T2',null,html, {introspection_mode:'names'});
+m_test('names introspection 4', {T1:t1}, function(tm) {
+ assert.equal(tm.N1.N2.T1.T2.__self__.name, 'N1.N2.T1.T2');
+ assert.equal(tm.N1.N2.T1.T2.__self__.namespace, 'N1.N2');
+ assert.equal(keys(tm.N1.N2.T1.T2.__self__).length, 2);
+}, {introspection_mode:'names'});
+
+t1 = '{namespace N1}{template .T1}name: "{__manager__.N1.T1.__self__.name}", namespace: "{__manager__.N1.T1.__self__.namespace}"{/template}';
+html = 'name: "N1.T1", namespace: "N1"';
+t_test('inside accessor', {T1:t1},'N1.T1',null,html, {introspection_mode:'names'});
+
+
+t1 = '{namespace N1} {template .T1}Hello{/template} ';
+html = 'Hello';
+t_test('full introspection 1', {T1:t1},'N1.T1',null,html, {introspection_mode:'full'});
+m_test('full introspection 2', {T1:t1}, function(tm) {
+ assert.equal(tm.N1.T1.__self__.name, 'N1.T1');
+ assert.equal(tm.N1.T1.__self__.namespace, 'N1');
+ assert.equal(tm.N1.T1.__self__.source, 'T1');
+ assert.equal(tm.N1.T1.__self__.pos_start, 15);
+ assert.equal(tm.N1.T1.__self__.pos_end, 45);
+ assert.equal(keys(tm.N1.T1.__self__).length, 5);
+}, {introspection_mode:'full'});
Please sign in to comment.
Something went wrong with that request. Please try again.