OK, I'll have to look at this in more detail, but to get a sense for what it's doing, a full example of the client code would help. I would just write it as JavaScript for now, and not worry about language-independent tests. If you can include an HTML page/template that would help too. I'd need to try it out and run it myself.
Off the bat, from your example, it seems odd to write into directly the page from the beforeSection callback. I would just include that in that data dictionary, and the template would have a substitution for it. I think the property that the template is *not* modified isn't a feature, but something that will obscure what's going on to template authors. Better to be explicit than implicit. Another consideration which I mentioned briefly in a bug is that the evaluation order in JSON Template isn't constrained by the language. It's a purely functional language. All the constructs can be evaluated in any order whatsoever, and then the final pieces assembled in sequence to produce the output. Adding these callbacks will constrain an implementation to sequential evaluation. For a path syntax, note that there is something called JsonPath, like XPath for JSON: http://goessner.net/articles/JsonPath/ It's not extremely common or standardized AFAICT, but worth looking at. thanks, Andy On Mon, May 25, 2009 at 11:31 AM, Martijn Faassen <[email protected]> wrote: > > Hi there, > > I've continued to mess around with json-template.js to see whether I > could get the DOM-node relative node lookup to work, as I want to use > it in a project. I got it working, and for future reference, here are > the relevant snippets. This code is assuming a version of > json-template with the hooks I proposed earlier built in. I also need > some way to generate a contex based on a path into the JSON structure > - since this uses the _ScopedContext interface to stay compatible and > since this is a private interface, the path to lookup function code > would need to be inside json-template.js, though the path parsing code > could be separated out. > > The logic to transform JSON structures so that they contain path > information. paths look like this: '.foo.bar|3, which would be > data_dict['foo']['bar'][3]. (the syntax could easily be altered) > > var _transform_paths_dict_helper = function(data_dict, path) { > var key; > var value; > > data_dict['_path'] = path; > > for (key in data_dict) { > value = data_dict[key]; > if (_is_array(value)) { > _transform_paths_array_helper(value, path + '.' + key); > } else if (typeof value === 'object') { > _transform_paths_dict_helper(value, path + '.' + key); > } > } > }; > > var _transform_paths_array_helper = function(data_array, path) { > var i; > var value; > for (i = 0; i < data_array.length; i++) { > value = data_array[i]; > if (_is_array(value)) { > _transform_paths_array_helper(value, path + '|' + i); > } else if (typeof value === 'object') { > _transform_paths_dict_helper(value, path + '|' + i); > } > } > }; > > var _is_array = function(obj) { > return Object.prototype.toString.apply(obj) === '[object Array]'; > }; > > Hooks to generate the hidden <div></div> sections into the HTML when > going into a {.section} and going into a {.repeated section}, so that > the code can later look up the path information in the generated HTML > DOM. It also sets up the JSON transformation logic to add in the _path > information, which the insertion logic neds. > > var HtmlIdHooks = function() { > return { > transformData: function(data_dict) { > _transform_paths_dict_helper(data_dict, ''); > return data_dict; > }, > beforeSection: function(lookup, write, name) { > write('<div class="json-template-path" style="display:none" > id="' + lookup('_path') + '"></div>'); > }, > afterSection: function(lookup, write, name) { > }, > beforeRepeatedSection: function(lookup, write, name, index) { > write('<div class="json-template-path" style="display:none" > id="' + lookup('_path') + '"></div>'); > }, > afterRepeatedSection: function(lookup, write, name, index) { > } > }; > }; > > Given a data_dict (the JSON structure), a path (of the structure > defined before), we create a function that returns a lookup function > appropriate to location in the JSON structure. This is the bit that > hooks into _ScopedContext, so cannot be a plugin unlike the rest. We > could however implement a simple path resolution algorithm that takes > a list of objects, and thus keep the path parsing logic out of the > core. > > var get_lookup = function(data_dict, path, undefined_str) { > var steps = path.split('.'); > var context = _ScopedContext(data_dict, {'undefined_str': undefined_str}); > for (var i = 0; i < steps.length; i++) { > var parts = steps[i].split('|'); > if (parts.length >= 2) { > var key = parts[0]; > var indexes = parts.slice(1); > } else { > var key = parts[0]; > var indexes = []; > } > if (key == '') { > continue; > } > context.PushSection(key); > for (var j = 0; j < indexes.length; j++) { > for (var x = 0; x < parseInt(indexes[j]) + 1; x++) { > context.next(); > } > } > } > return function(name) { > return context.Lookup(name); > }; > }; > > Given data_dict and a HTML DOM node, find a lookup function. This > builds on the previous logic, and sniffs the path from the HTML (which > got inserted previously). > > var get_node_lookup = function(data_dict, node, undefined_str) { > var parent = node; > while (parent !== null) { > var sibling = parent; > while (sibling !== null) { > if (sibling.getAttribute('class') == 'json-template-path') { > var path = sibling.getAttribute('id'); > return get_lookup(data_dict, path, undefined_str); > } > sibling = sibling.previousSibling; > } > parent = parent.parentNode; > } > return undefined_str; > }; > > So, to use this in javascript, you can write something like this: > > var lookup = get_node_lookup(data_dict, my_element) > > var a = lookup('a') > var b = lookup('b') > var c = lookup('b.c') > > The idea is that if you want to set up event handlers after expanding > a JSON template, you can easily retrieve information from the > underlying JSON without having to serialize it to HTML first, and > without having to embed javascript event handlers within the template. > > The only code proposed for inclusion in json-template.js are: > > * three hooks (or more): the data transformation one, and one hook for > {.section} and another for {.repeated section} > > * a way to turn path information into a lookup function that uses > _ScopedContext internally (but doesn't expose it). > > All the other code can be in an extension. > > The main thing missing are a lot of tests. I'd like to write tests for > this, but the verifier.py testing protocol lacks the infrastructure to > do this. I'd probably be easier to write these tests as javascript > only tests anyway, but we don't have infrastructure for that yet > either as far as I know. > > Regards, > > Martijn > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "JSON Template" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/json-template?hl=en -~----------~----~----~----~------~----~------~--~---
