Hot answers tagged

27

Craft documentation describes how to exclude entries with a given value. In this case, we want a string that looks like: 'and, not id1, not id2, not id3, not id4' So we need a string that is all of the featured article ids separated by , not. First, get them as an array using ids(): {% set featuredArticleIds = craft.entries.section('articles').featured(1)....


14

You can do this using the twig attribute function: {% set data = [ {'column':'1','title':'Quick Facts'}, {'column':'2','title':'Inspiration'}, {'column':'1','title':'Agencies'}, {'column':'2','title':'Industry Experience'} ] %} {% set cols = {} %} {% for item in data %} {# create a dynamic property if one doesn't exist #} {% if ...


12

Solution This won't work in Twig as presented in the question (see why below). Instead, users would need to be changed to an associative array (or "hash" in Twig terminology) with keys that aren't integers, and you'd have to insert a merge inside a merge to change the value: {% set users = { person0: {name: 'Bill', age: 25}, person1: {name: 'Tim', ...


8

You could do it in the twig template But a template isn't really the best place for something that is this codey, it gets pretty unreadable pretty quick. Notes: I start by building arrays of models and afterwards I convert those arrays to the comma seperated strings you require. It is case-sensitive, you probably have models or makes likes HILUX, hilux, ...


7

Like you said, to test if a value exists in a Twig array you'd do: {% if myValue in ['apples', 'oranges'] %} {# do something... #} {% endif %} To check whether the value is an array or object you could use the iterable test: {% if myValue is iterable %} {# myValue is an array or object #} {% else %} {# myValue is probably a string #} {% endif %...


6

The accepted answer here should hopefully help you out. Basically: {% set newArray = [] %} {% for name in array %} {% if name not in newArray %} My name is {{name}} {% set newArray = newArray|merge([name]) %} {% endif %} {% endfor %}


6

The merge filter only works with 2 arrays (or 2 hashes), not with an array and an object. I think that the event you are trying to add is not an array, it is a single event (Entry Model). You might try adding the event using [ event ]. {% set todaysEvents = todaysEvents|merge([event]) %}


6

Try adding find() to your ElementCriteriaModel, I think without that function you're not actually saving your entries as an array in your variable todaysOneOffEvents yet. Here's what I found in the Docs: You don’t actually need to call find() yourself though: It will be called automatically as soon as the ElementCriteriaModel is treated like an array (...


6

Unlike in PHP, it's not actually possible to break a for loop in Twig. To work around that fact, you can use the for loop to set a flag, and then put the conditional outside the loop: {% set isUserOnMobile = false %} {% for item in browserValues %} {% set isUserOnMobile = not isUserOnMobile ? item.agent in userAgent : isUserOnMobile %} {% endfor %} {%...


6

First, sort all entries by multiple criteria: {# get our entries and order by firstname, lastname #} {% set allEntries = craft.entries.section('entries').orderBy('lastname asc, firstname asc').all() %} Then use craft's custom "group" filter (lastname[:1] picks the first letter): {# group them by the first letter of the last name https://docs.craftcms.com/...


5

I base my example on the assumption that all people are Users (Element type User). If users are entries, you'd have to replace users by entries ;) I don't think there's a way to do this without iterating through all users first, creating some sort of ordering attribute (if lastName != '' ? lastName : firstName). Then, you'd be able to group your array by ...


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

I finally got this working, here is how, I'm sure there is a better way or ways I can improve, but for now it works. First, we need to create an empty array like so... {% set posts = [] %} Then we need to loop through the entries, and for each entry create an array containing the entry.postDate and the entry data. We then need to push that entry array ...


5

I think it'll be easier and more efficient to achieve that if you use the loop functionality instead of querying the actual tags. I think this code does what you want: {% set topics = '' %} {% for topic in entry.topics %} {% set topics = topics ~ topic ~ (loop.index < loop.length-1 ? ', ' : loop.index < loop.length ? ' and ') %} {% endfor %} <...


5

project.images is an array because you are eager-loading the images. Since you’re only loading one project entry, you’re not actually gaining anything by eager-loading the images (or category), though. In fact, you’re actually slowing things down a bit. Eager-loading does come with a little bit of overhead, so you should only use it when you’ve got an “n+1” ...


4

You can get all entries regardless of status with .status(null): {% set allEntries = craft.entries.section('sectionName').relatedTo(category).status(null).find() %}


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

You can accomplish this with slice and merge, although it's not very pretty: {% set myArray = ['a', 'b', 'd' ] %} {% set myArray = myArray|slice(0,2)|merge(['c'])|merge(myArray|slice(2,myArray|length)) %} {{ myArray|join(', ') }} To explain what's happening above: {% set myArray = ['a', 'b', 'd' ] %} This just sets an array we can work with. |slice(0,...


4

Take a look at the shuffle function provided by Craft: https://craftcms.com/docs/templating/functions#shuffle This will shuffle the complete array and output them all in the new order: {% set img = [ { bildli: 'http://i.giphy.com/I0xDz0htjsiME.gif' }, { bildli: 'https://i.giphy.com/fA3JALhIi5YVa.gif' } ] %} {% set shuffledImages = shuffle(img) %} ...


4

Building off of Brad's answer, you might consider using a for loop to render your markup, instead of setting all of those variables: {% set range = range(10, 90) %} {% set totalDivs = 5 %} <div class="sandbox"> {% for i in 1..totalDivs %} <div style="left: {{ random(range) }}%; top: {{ random(range) }}%;"></div> {% endfor %} </...


4

Your plugin should be able to handle PHP arrays just fine. craft/plugins/myplugin/variables/MyPluginVariable.php function getArray() { return array('hi', 'there'); } craft/templates/template.twig {% set result = craft.myPlugin.getArray() %} {% for item in result %} {{ item }} {% endfor %} The error you're seeing is likely because output itself ...


4

I figured it out! I ditched the macro and just included the following in my template: {% for field in courseFields %} <section class="col-xl mb-3"> <h2 id="{{ field.handle }}">{{ field.title }}</h2> {{ entry[field.handle] }} </section> {% endfor %}


4

I'm not calling .all(), so this is still an object, right? Nope. When you execute the for loop, it will explicitly run the database query and return the array of results. You're probably getting a deprecation error logged using that syntax as well since Craft wants you to use {% for album in albums.all() %} See here in the docs: https://docs.craftcms....


4

You can only access the parent's variable, not modify it. You could however simply add another block specifically for the body class, like so: Layout template: <body class="{% block body_class %}default-class-1 default-class-2{% endblock %}"> {{ block('pageBody') }} </body> Template that extends it: {% extends 'layout' %} {% block ...


3

Holy moly! I've solved it already, Batman. Check the array before adding the event to it, like so: {% if event not in categoryEvents %} {% set categoryEvents = categoryEvents | merge([event]) %} {% endif %}


3

Try to set both states in single/double quotes: {% set allEntries = craft.entries.status('live', 'pending').section('sectionName').relatedTo(category).find() %}


3

I can think of two ways to accomplish this: The without filter: Fetch all entries and all featured entries. Then remove the latter from the first: {% set all = craft.entries.section('news').find() %} {% set featured = craft.entries.section('news').featured(1).find() %} {% set not_featured = all|without(featured) %} Pro: You can set the ...


3

According to the docs for the Icons plugin, icon is actually an object. Try this instead... <i class="fa {{ block.icon.class }}"></i> In both scenarios, I'd take another look at your rendered HTML... your first example may actually be rendering the word Array instead of the class name that you are looking for. You can also leave off the leading ...


3

Two options here ... {% set transformParams = { width: 1250, height: 1250 * aspectRatioSetting[entry.aspectRatio] } %} Or just give the select field a value that represents the number, not the word. So set a value of 0.75 instead of four_three, and let the label be Four/Three (or whatever seems fit).


3

It looks like you have a typo in your merge, and the structure of the merge is incorrect. {% set merged = specialisms|merge(specialisms) %} This is saying set merged to the array specialisms merged with itself. What I am guessing you want to do is merge each specialism into the merged array, which looks like this: {% set merged = merged|merge(specialism)...


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