Smarty - same template different content - foreach

What is the strategy in smarty for using different variables each time a template is included in another template?
Here is what I mean.
I have a smarty template that creates a simple navigation list.
<ul class='linkList'>
<li>
<h3>{$title}</h3>
<ul>
{foreach $links as $d}
<li><a title='{$d...}' href='{$d....}'>{$d.text}</a></li>
{/foreach}
</ul>
</li>
</ul>
I want to include it a number of times in my main template and each time pass it different values. Im not sure what strategy to use to do this.
If I assign variables in my php file like this
$smarty->assign('links',array(.....);
$smarty->assign('title','My first link list');
$smarty->assign('links',array(different values);
$smarty->assign('title','My second link list');
and then include the template twice i will just get the same list twice with the second lot of values.

The {include} tag allows you to pass variables in the call:
{include 'linklist.tpl' title="Sample Links 1" links=$link_array1}
{include 'linklist.tpl' title="Sample Links 2" links=$link_array2}
Otherwise, I'm pretty sure you can use either {assign} or the short form of assign ({$var=value}) before including the template.

Related

Thymeleaf editing th:field before action

I have a simple pagination that looks like
<ul class="pagination justify-content-end" th:field="*{page}">
<li class="page-item page-item disabled">
<a class="page-link" href="action">1</a>
</li>
</ul>
I would get the following behaviour with Thymeleaf. Clicking on the page and before submitting the action, the value of the th:field associated with the pagination should be changed by setting it to the th:value of the selected page. In other words, clicking on the page number should change the value of "*{page}" and then call the method. Is there any way to do that, for example, combining th:onclick with th:action?
Thymeleaf is a rendering engine, as such it can do nothing once the page is served to the end user. At best u can fill variables into javascript when rendering to achieve the desired result.
As for your described functionality the given code is far to limited or faulty to give a suggestion for a javascript solution, for one th:field on a non-input element doesn't do much. Also the shown href is just a simple href that doesnt interact in any way with the encapsulating th:field.

jQuery-UI Accordion with link in the header

I am using Dotclear blog software, which provide a widget for the blog categories with a resulting code looking like this:
<div class="widget categories ">
<h3>Catégories</h3>
<ul>
<li>Cat1</li>
<li>Cat2
<ul>
<li>Subcat1</li>
</ul>
</li>
<li>Cat3
<ul>
<li>Subcat2</li>
</ul>
</li>
<li>Cat4</li>
</ul>
</div>
What I am trying to achieve here is using the <a> tag (for Cat2 or Cat3) as header (or a dynamically added <h4> around it) and fold the subcategory list. If I call the accordion like this :
$(".categories").accordion({
header: "li:has(ul) > a",
});
the accordion does work, but when I click on the link it just folds/unfolds the item and doesn’t let me go to the link target (the category page, that is).
I tried wrapping the <a> in an <h4> tag and use that tag as header, but it doesn’t seem to make a difference. Is there a way to do what I seek or should I abandon the idea of collapsing subcategories and have functioning links within the header ?
Thanks for your time.
Well, after reading your comments, I realized I was using the wrong tool to achieve my objective. I have replaced jquery-ui’s accordion with a treemenu jQuery plugin which is actually made for my use. Sorry to have wasted your time and thanks for your kind answers.

Thymeleaf th:if with th:each on the same html element

I am generating all menu link dynamically using Thymeleaf. I have written code which is working fine.
<ul>
<li th:each="menu : ${menus}">Home</span></li>
</ul>
My question is, how can I add a class (activeMenu) on li element if menu's value is equal to Home.
Usually you would insert this part in the element that you want to insert specific class, in your case span element:
th:class="${menu}=='Home' ? activeMenu"
or:
th:class="${menu}=='Home' ? activeMenu:''"
it should work like this:
<ul>
<li th:each="menu : ${menus}">th:text="${menu}">Home</span></li>
</ul>
I have not tried this specific condition, but it should work.
Hope this helps.

Should I store markup in resource files?

I read this article: Using HTML inside resource files but didn't find a satisfactory answer.
Basically, if I wanted to store:
<h2>Some heading</h2>
<p>An introduction for a series of steps</p>
<ol>
<li>Do x and y</li>
<li>Do y and z</li>
<li>Final step</li>
</ol>
would I put the whole thing into a resource entry or would I create a view that retrieved these values and marked them up?
<h2>#MyPage.Header</h2>
<p>#MyPage.Intro</p>
<ol>
<li>#MyPage.Step1</li>
<li>#MyPage.Step2</li>
<li>#MyPage.Step3</li>
</ol>
and then, if the final step contained markup like:
Make sure to read our disclaimers before continuing...
then would I have to write?
<li>
#MyPage.Step3MakeSure
#MyPage.Step3Read
#MyPage.Step3Before
</li>
the problem with embedding markup in the resource files is that now a translator needs to know to not touch the markup and if they do you're in trouble... but I can't think of a good structure?
Personally, I would use a templating for javascript such as Mustache or UnderScoreJs... then just load up the data based on a call to a controller action, see demo here for Mustache.
Mustache Demo

ASP.NET MVC Razor Concatenation

I'm trying the render an HTML list that looks like the following, using the Razor view engine:
<ul>
<li id="item_1">Item 1</li>
<li id="item_2">Item 2</li>
</ul>
The code that I am attempting to use to render this list is:
<ul>
#foreach (var item in Model.TheItems)
{
<li id="item_#item.TheItemId">Item #item.TheItemId</li>
}
</ul>
The parser is choking, because it thinks that that everything to the right of the underscore in the id attribute is plain text and should not be parsed. I'm uncertain of how to instruct the parser to render TheItemId.
I don't want to but a property on the model object that includes the item_ prefix.
I also have to keep this syntax as I am using the list with JQuery Sortable and with the serialize function that requires the id attribute to be formatted in this syntax.
You should wrap the inner part of the call with ( ):
<li id="item_#(item.TheItemId)">
How about using String.Format? like this:
<li id="#String.Format("item_{0}", item.TheItemId)">
I prefer:
<li id="#String.Concat("item_", item.TheItemId)">
The verbosity tells the support developers exactly what is happening, so it's clear and easy to understand.
You can even use this way to concat more strings:
<li id="#("item-"+item.Order + "item_"+item.ShopID)" class="ui-state-default"></li>
Here is another post.
Hope helps someone.
You can so this in a simpler way:
id="item_#item.TheItemId"
This post seems to be older but now this does works now in latest MVC:
id="item_#item.TheItemId"

Resources