Hot answers tagged

13

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 ...


9

If I understand your example correctly, a simple hyphen would do the trick — "YYYY-MM" is a format the date filter recognizes. {% set entries = ... %} {% set entriesByMonth = entries|group('postDate|date("Y-m")') %} {% for month, entries in entriesByMonth %} <li> <a href="{{ month|date("Y") }}/{{ month|date("m") }}"> {{ ...


6

You can do this with the twigPCRE filter. Once you have your allTags, group them like this: {% set allTagsGrouped = allTags|group('name|first|upper|preg_replace("/[A-M]/", "A-M", 1)|preg_replace("/[N-Z]/", "N-Z", 1)') %} This takes the tag name, gets the first character, converts it to uppercase (so 'a' and 'A' are grouped together), and then maps all ...


6

What Brad says, plus an example of grouping by selected checkbox: {% set entries = craft.entries.section('my_entries') %} {# get all checkbox options #} {% set options = entries.first().checkbox.options %} {% for option in options %} <h2>{{ option }}</h2> <ul> {% for entry in entries if entry.checkbox.contains(option) %} ...


6

This is a great chance to use the group filter. First, get all your matrix blocks as an array: {% set talkBlocks = entry.talks.find() %} Then group them by type: {% set talksByCategories = talkBlocks|group('type') %} At this point, you have an associative array where the keys are the block types, and the values are arrays of the blocks with that type. ...


5

The probably most easy way to do this is to sort the grouped array by key, which unfortunatelly is only possible with a plugin, as Twig's sort filter only allows to sort by value. Here I'm using Michael Rog's Supersort, but there are also other plugins that do this. {% set allProfiles = craft.entries.section('members').order('profileLastname').limit(null) %...


5

You should be able to do this with Craft's handy group filter. {% set players = entry.myPlayersMatrix %} {% set playersGrouped = players|group('myPositionDropdown.label') %} {% for position, playersInPosition in playersGrouped %} <h2>{{ position }}</h2> <ul> {% for player in playersInPosition %} {% set playerData = ...


5

To group by the first letter you would simply use the slice filter within Craft's group filter. For all non letter characters you can now use Craft's replace filter (it does regex since Craft 2.2) and replace them with whatever you want these entries to be sorted by. {% set entriesGrouped = entries|group('title|slice(0, 1)|upper|replace("/[^A-Z]/", "0-9")')...


5

You can use the Twig group filter. {% set entries = allowedSearchableEntries.search(query).order('score').limit(100) %} {% set entriesBySection = entries|group('section') %} {% for section, entriesInSection in entriesBySection %} <h2>{{ section }}</h2> <ul> {% for entry in entriesInSection %} <li><a ...


5

One improvement I think could be made is to fetch only the ID's of your hotTubs entries at the start of your code. You're only using this to get the related categories and fetching ID's is faster than fetching the actual elements. The relatedTo parameter works perfectly with ID's. So that could speed up things. You can drop the orderBy parameter also as this ...


4

When you specifically group on dateField.day (in your case, the |group('datum.day') part), the group filter won't care about the month or year for the date field – only the day. This means that any entry posted on the 22nd of any month in any year will be grouped together, which is probably not what you want. In this case, the solution is simply to group on ...


4

You're currently grouping on the myDate field, which essentially creates a new array index for each date (e.g. 2016-01-01) which is why you're getting your current output. To group by year, this should do the trick: {% for year, entries in entries|group('myDate.year') %} <h4>{{ year }}</h4> <ul> {% for entry in entries %} ...


4

You can get the categories to display hierarchically pretty efficiently using the {% nav %} tag: {% set categories = craft.categories.group('myGroup').find() %} <ul> {% nav category in categories %} <li class="category"> {{ category.title }} {% ifchildren %} <ul> {% children %} </ul> ...


4

Try something like: {% set breadGroups = entry.breads | group('bread.first.id') %} {% for breadId, blocks in breadGroups %} {% set sum = 0 %} {% for block in blocks %} {% set sum = sum + block.quantity %} {% endfor %} Total qty for Bread ID {{ breadId }}: {{ sum }} {% endfor %} The group filter consumes a list — in ...


4

For generating the nav, this should work. {% set allEntriesByWeek = allEntries|group("postDate|date('Y-W')") %} {% for week, entry in allEntriesByWeek %} <li><a href="events/{{ week|replace('-','/') }}">{{ week }}</a></li> {% endfor %} For grabbing entries (using the 'week' and 'year' variables passed via the route). {% set ...


4

Not exactly what you're looking for, but it gets you closer. This should display the order you want, but it doesn't have any pagination (and honestly I'm not sure if that's possible using Craft's {% paginate %} tag along with your other requirements. IMO, you're probably going to be better off doing this in PHP either using a Template Hook or a custom ...


4

The year and month variables are not defined, so you'd first have to get these from the 'date' variable. You could do this by using Twig's split function and splitting date by the space in between: {% set dateParts = date | split(' ') %} {% set month = dateParts[1] %} {% set year = dateParts[0] %} <a href="{{ year }}/{{ month }}">{{ date }}</a&...


4

Instead of using pagination, you might try creating a custom route using tags for year/month/day. Those tags will be available as variables in the template that you can use to load that days entries and generate the nav for next/previous day, etc. Using ajax the uri won't be visible to the user anyway. {% set postDate = year ~ '-' ~ month ~ '-' ~ day %} {% ...


4

You could use the group filter to group your tags by tag groups: {% set entries = craft.entries.section('gallery').limit(null) %} <ul> {# Get all the tags related to our gallery entries and group them by tag group #} {% set allGalleryTags = craft.tags.relatedTo(entries)|group('group') %} {# Loop the tag groups #} {% for tagGroup, ...


4

Depending on your needs, you may be able to ditch the group() filter and sort your list however you need. Get all your entries and categories. Then use the relatedTo functions to filter those lists. {% set categories = craft.categories.group('projectCategories') %} {% set projects = craft.entries.section('projects').order('title').limit(null) %} {% for ...


3

I'm not seeing any obvious ways to access groups directly in Twig. There may be a more direct way, idk — but this should work. {% set categoryGroupNames = [] %} {% for category in craft.categories %} {% set groupName = category.getGroup.name %} {% if groupName not in categoryGroupNames %} {% set categoryGroupNames = categoryGroupNames|merge([...


3

Twig is a templating language, and in my opinion this is pushing what it's comfortably meant to do. You might want to consider handling the heavy lifting w/ PHP by writing a small business logic plugin, or take a look at third party plugins like Micheal Rog's SuperSort to help out. That being said, if you want to go plugin-less the following should work (...


3

You set the variable that your are passing in to your include to a string. And in your include you try to access it like an object. The variable which you’re passing in to your include is set to a string 'businessIntelCategories'. And in your include you try access a object property dynamically using that string which doesn’t work. Use this code instead. {...


3

You are getting this error because the "entries" fields are always considered to be a query (ElementCriteriaModel) that can return more than one element. Therefore, if you know for sure that you will always have one and only one town linked to a business, you could do something like that: {% set businessesByTown = businesses|group('bizTown[0].title') %} If ...


2

That error is occurring at entries.limit(10), because at that point entries is already an array of fetched entries, rather than an ElementCriteriaModel. (The entries will get fetched as soon as the ElementCriteriaModel is passed to your |group filter.) The only way to grab just 10 entries per section (per page) will be to loop through each of your sections, ...


2

You could use some twig math, found at the bottom of the page here: Twig Templating Not sure without seeing the rest of your code, but you could do something like this: {% set totals = [3,4]%} {% for total in totals %} {{ total }} {% set sum = total + sum ?? 0 %} {% if loop.last %}{{ sum }}{% endif %} {% endfor %} Should output 34 and lastly 7 Or ...


2

Your actual code is pretty effective – the problem is that it's potentially going to result in a lot of queries. This is a good example of the so-called N+1 query problem, where each iteration over the result set of a single query generates an additional number of queries. Depending on the number of elements involved, this issue can easily result in ...


2

You could do this in a few steps (warning: this is untested code): 1) Define an array of the sections you cited, in the correct order: {# Define a list of the sections you want to display in the correct order #} {% set sections = ['news', 'products', 'reports'] %} 2) Identify the entries that do not belong in any of these sections: {# Create an array of ...


2

First, based on your example code I don't think you actually need to loop on the entries – you could simply group them on the brand name, and then loop on the keys for the grouped array (the keys would be your brand names): {% set brands = allEntries|group('brand')|keys %} {% for brand in brands %} <option value="{{ brand }}">{{ brand }}</...


2

Your postDate.day will output the number of the day in the month so if your entries postdate is 02.dd.yyyy your output is 2. Your array index will be something like [2, 3, 5, 12, 31] thus these values will be converted from the timestamp into a readable day with<h2>{{ day | date('Y-m-d') }}</h2>. The first timestamp (0) is 01.01.1970 because of ...


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