Hot answers tagged

19

You can grab a specific block type in Matrix by doing this: {% for block in entry.myMatrixField.type('typeOne') %} {{ block.text | markdown }} {% endfor %} If you wanted to know the number of blocks of a certain type, you can do: {% set blocks = entry.myMatrixField.type('typeOne') %} {{ blocks | length }} If you want to search for multiple block ...


17

There's a couple of special variables available while for looping through an array. In your case I'd make use of loop.last. {{ tag }}{{ not loop.last ? ', ' }} This is the expression using the ternary operator to keep the syntax short.


15

Currently there is no special build-in command to do it (unless you want to use a plugin, as stated by Brandon Kelly). There is a workaround, however. The workaround is to check for additional condition. {% set break = 0 %} {# this variable we will set to 1 when we do not want code in our loop to run anymore #} {% for i in 20..100 if break == 0 %} ......


14

{% set entries = craft.entries.section('pages').type('blogPost') %} {% for entry in entries %} {{ entry.title }} {% endfor %} Is what I have cobbled together... any pointers on improvements would be welcome.


14

You're actually closer than you might think. All you need to do is add your field handles as parameters. I prefer to use the hash style of declaring parameters but either way will work, I just find this easier to read. {% set params = { section : 'events', order : 'eventDate asc', eventDate : '>=' ~ now, eventType : 'green', limit : '10' } %} {...


13

The for tag has an else clause by which you can render a replacement block if no iteration took place because the sequence was empty. <ul> {% for user in users %} <li>{{ user.username|e }}</li> {% else %} <li><em>no user found</em></li> {% endfor %} </ul> reference: http://twig....


11

To do math in twig, you will need to use the set tag to do assignments, and the + operator to do addition. When doing math inside a for loop, you will need to keep in mind that loops are scoped in Twig; therefore a variable declared inside a for loop is not accessible outside the loop itself. If you want to access the variable, just declare it before ...


10

This can be accomplished by creating an array of the entry years. Inside the loop that's building the array, a conditional checks if the year already exists in the array... if the year exists, a variable is set to TRUE which you can use in your conditional later down on the page. {% set files = craft.entries.section("downloads") %} {% set dropdown = 0 %} {%...


10

The array slice something you are looking for is Twig's batch filter. Here's how you'd set up the groups and use loop.index to generate the class name. {# Use the `find()` method to return an array of EntryModels #} {% set selectedWork = craft.entries.section('selectedWork').find() %} {# Group entries using the `batch` filter #} {% set selectedWorkGrouped =...


10

I suppose in your example codePoints is the actual Table field. In order to output the table rows, the template should look like this: {% if block.codePoints | length %} <ul> {% for row in block.codePoints %} {# Assuming 'text' is the column handle of the text field #} <li>{{ row.text }}</li> {% endfor %} ...


10

If I understood your question correctly then you should be able to do it as follows: {% set sizes = [] %} {% for productAttribute in entry.productAttributes %} {% set sizes = sizes|merge([productAttribute.size]) %} {% endfor %} {% set sizes = sizes|join('|') %} The sizes variable will then be a string containing the pipeline separated sizes, for ...


9

An alternative, if you are getting the tags from the Tag Field type, is the Join filter: {% if post.tags | length %} Tags: {{ post.tags | join(', ') }} {% endif %}


9

You can combine a for and if statement in twig, so you don't necessarily need to use search. Something like this might get you a bit closer: {% for entry in craft.entries.section('event') if entry.postDate < now %} {# output your event here #} {% endfor %} It'll just output what meets the criteria if your if statement. The bonus is it doesn't mess ...


8

I found the answer in the Twig documentation: http://twig.sensiolabs.org/doc/templates.html#variables You can use a dot (.) to access attributes of a variable (methods or properties of a PHP object, or items of a PHP array), or the so-called "subscript" syntax ([]): {{ foo.bar }} {{ foo['bar'] }} When using the subscript syntax, you can concatenate the ...


8

Marion Newlevant wrote a Craft plugin that adds {% break %} and {% continue %} tags to Twig: https://github.com/marionnewlevant/craft-mnbreakandcontinue The Craft 3 version is Twig Perversion


8

You can call the first() function to just get the first image: {% set image = block.backgroundImage.first() %} {{ image.getUrl() }} But this will fail if there is no image. So to be safe, you need: {% set image = block.backgroundImage.first() %} {% if image %} {{ image.getUrl() }} {% endif %}


8

I usually do this like so: {% for block in blocks %} {% if loop.index0 % 2 == 0 %} <div> {% endif %} {# other stuff #} {% if loop.index0 % 2 == 1 or loop.last %} </div> {% endif %} {% endfor %} Or, more generally, {% set cols = 2 %} {% for block in blocks %} {% if loop.index0 % cols == 0 %} <div> {% endif %} ...


7

This can also be done with a Twig macro, rather than creating a plugin: {% macro ordinal(number) %} {%- spaceless %} {% if ((number % 100) >= 11) and ((number % 100) <= 13) %} {{ number }}th {% else %} {% set ends = ['th','st','nd','rd','th','th','th','th','th','th'] %} {{ number ~ ends[number % 10] }} {% endif %...


6

You're exactly right: The advantage of using the variable is that you can re-use it throughout your template, which helps keep things DRY. When you use craft.entries in your template, Craft serves up an ElementCriteriaModel — This is an object that knows how to query the system for a set of entries... but it doesn't actually perform that query until you ...


5

It looks like you're pretty close, but those field names need to be called as attributes on block: {% for block in entry.threeHomepageImages.type('images') %} {% if block.image|length %} {{ block.image.first }} {% endif %} {{ block.alt }} {{ block.imageTitle }} {% endfor %} I'm assuming your image field is an Assets Field here, so you ...


5

You're almost there. Every block returns a MatrixBlockModel, so you have to reference your block when getting the attributes: {% for block in entry.threeHomepageImages.type('images') %} <h2>{{ block.imageTitle }}</h2> {# Save images to variable for reuse #} {% set image = block.image %} {# Check if there is any images #} {% ...


5

Something like this should work: {% set reviews = craft.entries.section('reviews').relatedto(entry) %} {% set value = 0 %} {% set condition = 0 %} {% set reception = 0 %} {% set count = 0 %} {% for review in reviews %} {% set value = value + review.value %} {% set condition = condition + review.condition %} {% set reception = reception + review....


5

I think batch that @Alec Ritson mentioned is definitely the way to go. However, here's another approach for fun. You can use cycle. {{ cycle('<div>', '') }} {{ foo }} {{ cycle('</div>', '') }} But let me repeat: I really think batch is the way to go.


5

You'd want to write a plugin that added an |ordinal Twig filter. Then from your template, you would do: loop.index|ordinal. The logic in the plugin would look something like: public function ordinal($number) { $ends = array('th','st','nd','rd','th','th','th','th','th','th'); if ((($number % 100) >= 11) && (($number % 100) <= 13)) ...


5

You should close your for-tag pair within the {% if ... %}. So: {% if craft.request.isMobileBrowser %} {% for batch in craft.entries.section('afval')|batch(2) %} ... {% endfor %} {% else %} {% for batch in craft.entries.section('afval')|batch(3) %} ... {% endfor %} {% endif %} Or, even better: {% set batch = craft.request....


5

I'd probably try to filter those out in your initial query, but if you've already got them, something like this should work: {% set existingIds = [] %} {% for event in events %} {% if event.id not in existingIds %} {{ event.title }} {% set existingIds = existingIds|merge([event.id]) %} {% endif %} {% endfor %}


5

There is certainly a lot of repeated code here so we can definitely improve on that! There are so many ways you could handle your Twig templates but this is how I would do it: <div id="slider-with-blocks-1" class="royalSlider rsMinW"> {% for block in entry.slideitemtop %} {% set Bild = block.ImageSlideTop.first() %} <div class="...


4

Craft adds those extra elements to each array of table cells only if there's column handles defined in your Table Field. This allows you to not only access a cell's value via row.col1, row.col2, etc. but also using the columns handle, e.g. row.price. If you don't want to use this feature or programatically loop the cells, don't define column handles!


4

You could use the folderId-parameter in craft.assets: {% for image in craft.assets.folderId(1) %} <li><img src="{{ image.getUrl('thumb') }}" alt="{{ image.title }}"></li> {% endfor %} You can get the folderId by inspecting the folder-name in the CP.


4

You'd further filter your returned artist entries down like this: {% set artists = craft.entries.section('artists').intoCollection('1') %} Then remove all the unnecessary "intoCollection" conditionals in your loop.


Only top voted, non community-wiki answers of a minimum length are eligible