I have a tree structure of arbitrary depth that I want to display with Handlebars. I don't see any way to recurse. If I knew the depth, I could hard code it I suppose, but it can be arbitrarily deep.
Something like this, but it needs to recurse at the display children part.
{{#aNode}}
{{id}
{{name}}
{{description}}
...spew this same template with each member of {{#children}}...
{{/aNode}}
Handlebars has ways to iterate collections, but no way that I can see to recurse into the children
Found that you can do it with a delegation/embedded file technique. So, it'd look like this:
spew_a_node.mustache (I'm using the Mustache implementation):
{{#aNode}}
{{id}
{{name}}
{{description}}
{{#children}}
{{> spew_a_node}}
{{/children}}
{{/aNode}}
Here's a nice article and jsfiddle describing exactly how to do it (which is more or less what Chris Kessel has described in his answer):
http://www.boduch.ca/2014/03/recursive-list-building-with-handlebars.html
Related
I need to extract a number from an HTML page and convert it into a variable in my test case.
The problem is that there is no ID directly to this element, here is the HTML code, I want to get the 54 (that number can change that's why I need to identificate him with another way), I tried Get Text by using "resultat" but I get "54 ligne(s) trouvée(s)" but I only want "54":
<div class="tab-interpage> == $0
<div class="resultat">
<b>54</b>
ligne(s) trouvée(s)
</div>
...
You have other options how to locate an element, see Locating elements section in Selenium Library.
This might be a situation that requires xPath, I can imagine this one works (but I don't see the whole DOM, so I can't be 100 % sure):
//div[#class="resultat"]/b
combined with the keyword:
${var}= Get Text //div[#class="resultat"]/b
Obviously if there're more div elements with class "resultat", you might run into problems here. In this case, explore the DOM a bit more and see what are some other ways you can get to the element you need.
I think it'd be much more readable if the HTML elements had proper attributes like:
form with class attribute
unique ids usually work best
i wond if it's anyhow possible to solve this problem with Spacebars in Meteor:
{{TplVar placeholder="{{mf 'identifier' 'defaultval'}}"}}
This sytnax causes a syntax error.
If the placeholder would not contain spaces - as far as i know - just keeping it free of curly brackets would solve the solutions but this doesn't work here.
I'm a bit at a wall now - should there be really no way to solve it? I've already searched around for jagged handlebars/spacebars template tags but couldn't really find anything useful - especially not for the Meteor context.
Thanks in advance for helping!
Frank
I've never used the Messageformat package (which looks interesting), but from the docs it looks like there's a javascript API. So you can just do something like:
{{TplVar placeholder=thisPlaceholder}}
and
Template.yourTemplate.helpers({
thisPlaceholder: function() {
return mf(this.identifier, this.defaultval);
}
});
Note that I'm assuming identifier and defaultVal are in the data context here - if they're the results from helper functions, you need to replicate those functions within this new thisPlaceholder helper and replace this.identifier and this.defaultval with the results.
Is it possible to add variable and do loop in css like php:
for($a=6; $a<9; $a++) { "#divShow"+$a }
So, the result will be:
#divShow6 #divShow7 #divShow8
Any idea? Thanks in advance.
No. There are no 'variables' or 'loops' in CSS. It is not a Turing-complete language. This is what CSS classes are for, so you don't have to generate IDs.
You don't have loops in CSS, but if you want to match all the tags with an id that starts with divShow you can use (example http://jsfiddle.net/diegof79/mUGsj/):
div[id^="divShow"]
But I'll recommend to use a class instead.
Also your question shows a match of childrens: divShow8 inside a divShow7. You don't need that kind of selector, because probably the problem can be resolved in another way (by using classes or different id).
Take a look to http://www.w3schools.com/cssref/sel_nth-child.asp maybe it gives you other ideas.
I'm trying to modify my /portal_view_customizations/zope.interface.interface-plone.belowcontenttitle.documentbyline template with a tal expression, so that the document's author and the modification date do not show if the current portal type is a Document (Page). I don't mind if it shows for News Items, which are time sensitive, but not the Documents/Pages.
This is my failing Plone TAL expression:
<div class="documentByLine"
id="plone-document-byline"
i18n:domain="plone"
tal:condition="view/show and not:python:here.portal_type == 'Document'">
...
I've also tried:
<div class="documentByLine"
id="plone-document-byline"
i18n:domain="plone"
tal:condition="view/show and not:context/portal_type='Document'">
but still no luck. The tracebacks are pretty cryptic and don't relate to the TAL expression. However, if I get rid of my condition for portal_type, then it works again. Any thoughts are appreciated. A manual would be good, but I've looked at the official ones, and they don't mention this.
TAL's underlying TALES, the expression-engine of which TAL makes use of, doesn't support the mixing of expression-types in one expression. It's syntax allows only one expression-type to be specified (defaults to 'path', if omitted, btw), as no delimiter is provided (like a semicolon for chaining several TAL-statements in one element, e.g.).
But instead of mixing three expression-types you can use one python-expression, try:
python: view.show and context.portal_type()!='Document'
Update:
If you have customized a Plone's default-template via portal_view_customizations ('TTW'), now restricted python-methods cannot be accessed, that' why view/show throws an error.
It returns the allowAnonymousViewAbout-property of the site-properties, you can also check this condition yourself and your expression looks like:
tal:define="name user/getUserName"
tal:condition="python:test(name!='Anonymous User') and context.portal_type()!='Document';
Quick'n'dirty alternative:
Do it with CSS:
body.userrole-anonymous .documentByLine {display:none}
body:not(.template-document_view) .documentByLine {display:block}
This will render the hidden elements, but it's helpful for prototyping and such, or 'quickfixes' (no admin available, etc.).
I have a field in a mongodb collection with comma separated values such as...
{tags: 'Family friendly, Clean & tidy, Close to town centre, Good location, Friendly staff, Good breakfast, Book my next stay'}
In my template files I would normally call something like {{tags}}, or if I had an array might be able to use {{#each tags}} etc...
What I want to do though is wrap each item in additional HTML such as a span.
Any ideas?
UPDATE: Here's my helper function so far, it creates an array but I don't know the best way to use this in my HTML page so I can wrap spans around each item.
Template.tags.helpers({
getTags: function(input) {
var tagArray = [];
tagArray = input.split(',');
return tagArray;
}
})
You can use tags.split( ", " ), but storing the tags in an array is more flexible and makes more sense.
Using my helper getTags I could iterate over the array it returned with the following code:
{{#each getTags reviewTags}}
<span>{{this}}</span>
{{/each}}
The this keyword can be used to output each item.
I'm not sure if this is the most efficient way, but it keeps the HTML where I want it.