Hot answers tagged

51

The answer depends on the field type. Assets, Categories, Checkboxes, Dropdown, Entries, Matrix, Multi-select, Radio Buttons, Tags, and Users fields each will each appear to be non-empty, even if they don’t have a user-submitted value, because in each case, entry.myFieldHandle will still return something: an ElementCriteriaModel object for Assets, ...


27

You can either have MySQL select the blocks in a random order using RAND(): {% set blocks = entry.myMatrixField.order('RAND()') %} Or you can shuffle the blocks from Twig instead, using Craft’s shuffle() function: {% set blocks = shuffle(entry.myMatrixField) %} There’s not a major performance difference either way in most cases, however if you also want ...


21

That’s what getUrl() returns if the transform hasn’t been generated yet. When the browser requests that URL, Craft will generate the transform, and respond with a 302 redirect to the actual image URL. Update: As of Craft 2.2, even if the transform generation URL doesn’t get directly requested (e.g. if it’s a social media image, or a srcset size that doesn’t ...


20

Rather than trying to store multiple stats together in a single block, another option would be to make a "Stat" (singular) block type, which only holds a single stat, and just have authors create as many of those as they need, positioned together. From your template, when looping through blocks, you can check to see if the current block is the first/last of ...


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

Getting a Matrix field working on the front-end is going to require 2 things: Setting up the field inputs so the data submits correctly. Some custom JavaScript to make the blocks repeat and behave how you want them to. Here's an example of the Matrix input code you'll need on the front-end. You'll need to update all of the field handle values to fit your ...


17

Folks may also want to checkin the Super Table plugin that just came out. It allows you to create table fields that include almost any field type: https://github.com/engram-design/SuperTable Keep in mind, though, that in many cases this may make your CMS/data pretty dependent on a plugin.


15

You don't get table headings with the entry model data (use the dump() function while in dev mode to see yourself). But there's the method getFieldByHandle() that returns a field model containing info to any field settings. This is how you access the headings of a table field Craft 2 {% set field = craft.fields.getFieldByHandle('myTableField') %} {% for ...


15

There's about a 99% chance you're bumping into your php.ini file's max_input_vars value and/or its post_max_size. If you bump those to higher values, it should start working as expected. Note that you may have to restart your web server for the settings to take affect.


15

This should work: {% if block['blockTitle'] is defined %} // Do your thing {% endif %}


15

You could first set a variable to test against and then change it the first time the block type appears. {% set firstTime = true %} {% for block in entry.matrixField %} {% if block.type == "text" and firstTime == true %} ...Do something once... {% set firstTime = false %} {% endif %} {% endfor %}


13

Here’s how you would do that: {% set futureEvents = entry.myMatrixField.myDateField('>= '~now) %} {% for event in futureEvents %} {{ event.description }} {% endfor %} Update: This actually hadn’t worked as I expected to, but it does as of Craft 2.3.


13

block.type is actually an alias for a getType() function, which returns a new MatrixBlockTypeModel object. Those will output their handle by default, which is why it's possible to compare block.type against block type handles. But MatrixBlockTypeModel also has a handle property, so this is totally possible: {{ block.type.handle }}


13

You get this error because {{ block.slideLink }} returns an array of EntryModels (even if you set your Entries field up to only allow 1 entry). So you need to add the first() method to get the first (and only) EntryModel that you are interested in: {% set entry = block.slideLink.first() %} Access the url property to return the URL of that entry: {% if ...


12

If you have a peek through the Twig documentation, you'll come across the empty test. {% if block.heading is empty %} {# ... #} {% endif %}


11

At the time of this writing, the ideal solution isn't possible. But, as jpea suggested, creating a plugin was dead easy, so here it is: Low Blocks ...which lets me use syntax like this: {% set block = craft.lowBlocks.id(craft.request.segment(2)) %} {% set entry = block.owner %}


11

This is because of a combination of settings in your php.ini file: max_input_vars & post_max_size, not any limitation in Craft CMS. c.f.: Matrix field input error from within the control panel


11

Saving Matrix fields programmatically got a lot easier in Craft 3 thanks to all the content refactoring. use craft\elements\Entry; use craft\elements\MatrixBlock; // Figure out the section & entry type $section = Craft::$app->sections->getSectionByHandle('news'); $entryTypes = $section->getEntryTypes(); $entryType = reset($entryTypes); // ...


10

Matrix within Matrix isn't possible... yet. Brandon has stated a few times that it's part of the long-term plan, and it's really more of the UI which is a stumbling block, rather than any major technical challenge. ... Matrix within Matrix is still something we intend to get working at some point. … Matrix within Matrix will be coming eventually. The ...


10

Creating the field/block types manually is only part of the equation - you would also need to create the new content table for your Matrix field. All you need to do is assign all of your block types and their sub-fields’ settings to $field->settings before calling saveField(): $field = new FieldModel(); $field->groupId = 1; $field->name ...


10

I'm not sure I understand your question 100%, but I'm assuming you're talking about a thoroughly modular approach to templating, and not about letting your end users/content editors actually edit the content model (i.e. create/edit Sections, fields, field layouts etc) – because the latter is not a good approach, in general. Either way, this is a very open ...


9

First you need to define the category. If your category group has the “Categories in this group have their own URLs” checkbox checked, and the URL Format is set to category/{slug}, and this is happening on the template you’ve specified in the Category Template setting, then all the stars have aligned and this step is taken care of for you automatically. The ...


9

Use brackets instead of dot notation for the field handle when you test for defined: ... {% if block['test'] is defined %} ... {% endif %}


8

You should be able to do this like so: {% for block in entry.productIndo.type('specifications') %} {% for download in block.downloads %} {{ download.url }} {% endfor %} {% endfor %} Of if the nested loops don't suit you: {% set specificationBlock = entry.productIndo.type('specifications').first() %} {% if specificationBlock %} {% for ...


8

My SuperSort plugin is built for use cases exactly such as this. It allows you to render each object in your array using a Twig object template and sort the array based on the rendered value.


8

Fun question! :) You can use getNext() and getPrev() Methods on the MatrixBlockModel documentation page. {% for point in entry.keyPoints %} {# if this is the "typeToWrap" block type #} {% if point.type == 'typeToWrap' %} {# if there is a previous point to check #} {% if point.getPrev() %} {# if the previous point wasn'...


8

Yes that's possible, all Twig loops have a loop variable: loop.index - The current iteration of the loop. (1 indexed) loop.index0 - The current iteration of the loop. (0 indexed) Example: {% for block in entry.myMatrixField %} {% if block.type == "quote" %} <blockquote class="quote{{ loop.index }}"> <p>{{ block.quote }}</p&...


8

Assuming you have an entry to work with, something like this should work: {% for block in entry.myMatrixFieldHandle if block.type == "employment" %} <select> {% for option in block.myDropDownFieldHandle.options %} <option value="{{ option.value }}">{{ option.label }}</option> {% endfor %} </...


8

There's no block types with SuperTable, so no need to check that. Other that that it works just the same as Matrix fields. {% for row in superTableField %} {{ row.textFieldInSuperTableField }} {% endfor %}


8

At the moment loop.first and loop.index0 are relative to your block.image loop. If you want them to be set based on your entry.locationSlideshow loop (the parent loop) you can use {{ loop.parent.loop.index0 }} and {{ loop.parent.loop.first }} For more information see the Twig documentation.


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