4

Say I have a json object with nested arrays to unknown depths. I want to feed each array into a _.template function. For Example, my json object might look like:

$start_elements = array (
        array(
            "elementTag"=>"li",
            "elementClass"=>"dashboard",
            "elementContent"=>array(
                "elementTag"=>"a",
                "elementContent"=>"Dashboard",
                "href"=>"#home"
                ) 
        ),
        array(
            "elementTag"=>"li", 
            "elementClass"=>"count indicator", 
            "elementContent"=>array(
                array(
                    "elementTag"=>"span", 
                    "elementClass"=>"data-count='8'", 
                    "elementContent"=>"Notifications"
                ), 
                array(
                    "elementTag"=>"ul", 
                    "elementClass"=>" ",
                    "elementContent"=>array(
                        "elementTag"=>"li", 
                        "elementContent"=>array(
                            "elementTag"=>"a",
                            "href"=>"#", 
                            "elementExtra"=>"data-modal",
                            "elementContent"=>array(
                                array(
                                    "elementTag"=>"h4",
                                    "elementContent"=>"Lorem Ipsum"
                                    ), 
                                array(
                                    "elementTag"=>"<p>",
                                    "elementContent"=>"Lorem ipsum dolor sit imet smd ddm lksdm lkdsm"
                                )
                            )
                        )
                    )
                )
            )
        )
);
json_encode($start_elements);

_.template:

_.template('<<%= elementTag %> class="<%= elementClass %>" href="<%= href %>"><%= elementContent %></<%= elementTag %>')

The nested structure of the arrays is significant because I want to output the html in the same nested structure. For example, the above object would output an li object with an anchor tag inside of it. How do I go about applying the template to each nested array, while preserving this structure?

1
  • That's no JSON, and I don't see any arrays. Commented Jan 14, 2013 at 4:39

2 Answers 2

1

I'd make a wrapper function around your template to keep your template logicless. Then you can use underscore's utility methods to check if you have an array, object (or string) (_.isArray and _.isObject) in your hands.

You'll need to pass in your wrapper function into the template so you can use it. You can just _.extend your data with {tmpl: tmpl}.

Here's a working, though simplified, example:

    var data = {
    elementTag: "li",
    elementContent: [{
        elementTag: "a",
        elementContent: "Dashboard"
    }, {
        elementTag: "div",
        elementContent: "Hello"
    }]
};

var tmpl = _.template('<<%= elementTag %>><%= template(elementContent) %></<%= elementTag %>>');

function template(elData) {
    var html = "";
    if (_.isArray(elData)) {
        _.each(elData, function (el) {
            html += template(el);
        });
    } else if (_.isObject(elData)) {
        html = tmpl(_.extend({
            template: template
        }, elData));
    } else {
        html = elData;
    }
    return html;
}

console.log(template(data));
Sign up to request clarification or add additional context in comments.

1 Comment

What happens if the child elements in elementContent are arrays and not objects? (See edited answer above). Should some sort of _.each iteration happen in the case of arrays?
0

You can do the following:

function applyTemplate(obj){
  if _.has(obj, "elementContent"){
     obj.elementContent = applyTemplate(obj.elementContent)
  }
  return _.template("templateString", obj)
}

Basically you go through the whole tree and replace the elementContent with its template value going bottom to up.

4 Comments

Will this loop? I can't seem to get it working but I think it may be just trying to return the deepest object in template...
I should work, I didn't test it but it would go through the all tree and then replace all elementContent and replace them in the object. Please also note that your example doesn't represent a tree but a stack.
What happens if the child elements in elementContent are arrays and not objects? (See edited answer above). Should some sort of _.each iteration happen in the case of arrays?
Then you replace obj.elementContent = applyTemplate(obj.elementContent) by obj.elementContent = obj.elementContent.map(function(obj1){ return applyTemplate(obj1.elementContent)})

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.