php mustache conditional value like handlebars block helpers - php

In Handlebars, you can make conditionals, like:
{{#if isActive}}
<img src="star.gif" alt="Active">
{{/if}}
http://handlebarsjs.com/block_helpers.html
I've been trying for a while to do something like this in the PHP Mustache. But nowhere i can find anything allowing {{#something withvalue }}
Why not just use the {{#each }} to if something? If I want to Each over a list making lis, and I only want to wrap them in a ul when there are actually lis?
I would need an extra value that has prechecked the list, which I think is ugly.
{{#hasList }}
<ul>
{{# list }}
<li>{{ title }}</li>
{{/ list }}
</ul>
{{/hasList }}
There must be a way to handle this in Mustache, right?

Related

Configurable partial

I have a component in my templating engine (that works well so far) that kind of needs to take an argument.
The component is a navigation on a website. In the CMS there can be many navigations (main, footer, side) but I can't get the logic for Mustache right.
My template `top.mustache':
<div id="wrap-top">
<div id="top">
{{> #navigation }}
{{ main }}
{{> /navigation }}
</div>
</div>
And then navigation.mustache is just:
<div class="nav">
{{ #navigation }}
</div>
In PHP I'm rendering it as follows:
$mustache->render("top", [
"navigation" => [
"main" => "HTML HERE"
]
];
The thing is that I don't want to create multiple tags like navigation_main or navigation_footer because the code is the same. The links may be different but that's handled in PHP where HTML is being generated.
The key is to not have to create mustache files for the names of the navigations. How do I put this all together? Just for the purpose of the question, let's say I do this:
{{ #navigation }}
{{ main }}
{{ /navigation }}
<-- some other html -->
{{ #navigation }}
{{ footer }}
{{ /navigation }}
And the result would be:
<div class="nav"><-- links from main here --></div>
<-- some other html -->
<div class="nav"><-- links from footer here --></div>
The reason is that the names of navigations can vary. In PHP I can prepare the array with all available options but how to use only one partial template?

PyroCMS theme custom navigation structure

I've searched everywhere but can't seem to find anything in the documentation or anywhere else. I've created my own custom theme, copypasting stuff from the Starter theme which ships with PyroCMS. In my navigation partial there is this twig directive:
{{ structure()
.linkAttributesDropdown({'data-toggle': 'dropdown'})
.listClass('nav navbar-nav navbar-right')
.childListClass('dropdown-menu')
.render()|raw }}
This works when using the Bootstrap framework. I am using Purecss.io and I want to assign different classes and assign classes to more elements. My navigation should look like this:
<ul class="pure-menu-list">
<li class="pure-menu-item pure-menu-selected">
<a href="http://local.dev" class="pure-menu-link" >Home</a>
</li>
<li class="pure-menu-item pure-menu-has-children pure-menu-allow-hover">
Item with children
<ul class="pure-menu-children">
<li class="pure-menu-item">
Child 1
</li>
<li class="pure-menu-item">
Child 2
</li>
</ul>
</li>
</ul>
I've tried the folling in my partial:
{{ structure()
.linkAttributesDropdown({'class': 'pure-menu-item pure-menu-has-children pure-menu-allow-hover'})
.listClass('pure-menu-list')
.elementClass('pure-menu-item')
.childListClass('pure-menu-children')
.render() }}
But that doesn't do the trick.
How would I accomplish this? Where can I find documentation for the used functions structure(), listClass() etc.?
Thanks in advance!
Unfortunately this portion of the system is still being developed but I can show you the macro and how to interact with it:
https://github.com/anomalylabs/pages-module/blob/master/resources/views/macro.twig
The chaining you are seeing is how you set the options so structure().fooBar(value) set's the foo_bar option to value in the options collection.
For elementClass you are probably looking for linkClass. Also don't forget to escape with |raw!
Looks like this will give you your desired markup:
{{ structure()
.currentClass('pure-menu-selected')
.dropdownClass('pure-menu-has-children pure-menu-allow-hover')
.linkAttributesDropdown({'class': 'pure-menu-item pure-menu-has-children pure-menu-allow-hover'})
.listClass('pure-menu-list')
.itemClass('pure-menu-item')
.linkClass('pure-menu-link')
.childListClass('pure-menu-children')
.render()|raw }}
Here's some information:
The very basic default looks like the following and will create an unordered list with all your existing pages. If you have set/toggled a page to be NOT enabled, then it will not show up.
{{ structure()|raw }}
Change the class of the list element
{{ structure().list_class('navigation')|raw }}
Change the list tag to something else than unordered list:
{{ structure().list_tag('dl')|raw }}
Change list element
{{ structure().link_tag('dt')|raw }}
Show children of only a specific page
{{ structure().root('/my-page')|raw }} or page-id {{ structure().root('9')|raw }}
Set class for the element with children
{{ structure().dropdown_class('has-children')|raw }}
Set a class to every li item:
{{ structure().item_class('has-children')|raw }}
Set a class to the link
{{ structure().link_class('my-class')|raw }}
Add a title attribute to the link
{{ structure().link_attributes({'title':'Title attribute'})|raw }}

Applying twig filters in Drupal 8 Views Template

I'm building a themed view in Drupal 8 using twig. I'd like to use twig filters on the row.content variable in the views-view-unformatted.html.twig template.
It seems that row.content is an array so twig's string manipulation doesn't work. However, it prints onto the page as a string (view is just a list of taxonomy terms).
What I'd like to do is slugify the output so taxonomy terms with spaces can have valid hrefs. See the replace filter in the code below.
<ul class="nav nav-tabs" role="tablist">
{% for row in rows %}
<li role="presentation" class="{{loop.first ? 'active' : ''}}">
{{row.content}}
</li>
{% endfor %}
</ul>
This will just output <a href="#">. Does anyone know how to access the raw text value that is output during twigs interpolation?
Thanks!
I ran into this myself it was difficult because kint and dump crashes on views.
there is a quick workaround to get to the bits though, put this under {% for row in rows %} in your twig views style template.
<ol>
{% for key, value in row.content %}
<li>{{ key }}</li>
{% endfor %}
</ol>
load the page with that & gives you the keys to see, I checked them each with the following dump command, just added underneath to test.
{{ dump(row.content['#row']) }}
The above dump showed all the goods in #row, where I dug in and found the field I wanted inside _entity (may be different for you), then I wanted to replace spaces with dash and force lowercase.
Everything past row.content['#row'] is likely different for you, you'll need to dig in the array a bit with the dump command mentioned above.
Below is the line that got me what I wanted.
{{ row.content['#row']._entity.title[0].value|replace(' ', '-')|lower }}
Below is twig template example.
For filename change viewname and block-3 to your setup.
views-view-unformatted--viewname--block-3.html.twig
{% for row in rows %}
{%
set row_classes = [
default_row_class ? 'views-row',
'something',
'kint-cant',
]
%}
{# My field value unformatted #}
<!-- {{ row.content['#row']._entity.title[0].value }} -->
<section{{ row.attributes.addClass(row_classes) }} id="{{ row.content['#row']._entity.title[0].value|replace(' ', '-')|lower }}">
{{ row.content }}
</section>
{% endfor %}
Im sure there are plenty of other ways to do this, but it worked for me as a quick solution to print out views fields in the style template, which is really useful.

symfony twig html tags </div>

I'm fairly new with twig, so I'm having a little trouble. How add tag to end of variable name?
{{ item.description|raw'</div>' }}
is correct?
description is with html tags
I think the best way is to add your tag out from twig:
{{ item.description|raw }}</div>
However, you could use concatenation:
{{ (item.description ~ '</div>')|raw }}

Symfony2: collection form field type with data-prototype

I have a Team to which I would like to add players (objects of Player). I've set up the form "type" classes correctly. Here's the relevant part of my view:
{% for index, player in form.players %}
<div id="template" data-prototype="{{ form_widget(form.players.get('prototype')) | e }}">
<span class="title">{{ index }}</span>
{{ form_row(player.name) }}
</div>
{% endfor %}
My problem is that data-prototype attribute doesn't include the span tag; it only contains the output of {{ form_row(player.name) }}. Is there a way to include the whole content of div#template in the data-prototype attribute?
This was bugging me too. I customized a field type and even made simple form types with a reduced fieldset (for more complex objects), but it just didn't feel right. I've come up with a solution that should do the trick :)
First - I think your <div id="team" data-prototype="..."> should be outside your loop.
Next, your prototype is just a form view object, so if you pass it to a template you can render fields by hand and customize the output. Note: autoescape has no effect on included content, so use 'filter escape'.
<div id="playerFields" data-prototype="{% filter escape %}{% include 'AcmeTeamBundle:Team:prototypePlayer.html.twig' with {'form': form.players.get('prototype')} %}{% endfilter %}">
Then in your prototypePlayer.html.twig, just render each field as you normally would in a form view.
<div>
<span class="title">{{ form_label(form.name) }}</span>
{{ form_row(form.name) }}
<span class="age">{{ form_label(form.age) }}</span>
{{ form_row(form.age) }}
{# render whatever else you like from your Form/PlayerType class... #}
<div>
My template has a different data structure to your question, but it should help :)
Cheers,
Chris
Deprecation Warning:
As of Symfony 2.1, .get() is deprecated and the above will not work. Replace form.players.get('prototype') with form.players.vars.prototype to fix this in later versions of Symfony.

Categories