Passing a variable to an include I have a category listing template where I'm having trouble passing in some variables.

top of the template I have this snippet where I'll set the channel and category field name based on the segment

{% set segment = craft.request.segment(1) %}

{# set channel based on segment_1 #}
{% if segment == "business-intel" %}
    {% set channelName = "businessIntel" %}
    {% set categoryName = "businessIntelCategories" %}
{% elseif segment == "foo" %}
    {# do nothing #}
{% endif %}
{# end set channel #}


Then further down the template I have this:

{% include ('_includes/cat_sub_with_article') with { 'categoryName' : categoryName } %}


And then the included template looks like this:

 {% for category, catEntries in entries | group('categoryName.first().title') %}
    &lt;h2&gt;{{ category }}&lt;/h2&gt;


    {% set featuredThumb = {
        mode: 'crop',
        width: 370,
        height: 168,
        quality: 90,
        position: 'top-center'
      } %}

    &lt;div class="article-cards"&gt;
        {% for entry in catEntries %}
        &lt;div class="article-card__wrapper"&gt;
            &lt;a href="{{ entry.url }}" class="article-card"&gt;

                {% set image = entry.featuredImage.first() %}

                &lt;span class="article-card__image"&gt;
                    &lt;img src="{{ image.url(featuredThumb) }}" /&gt;
                &lt;/span&gt;
                &lt;span class="article-card__text"&gt;
                    &lt;span class="article-card__category"&gt;{{ entry.postDate.format('M d, Y') }}&lt;/span&gt;
                    &lt;h3 class="article-card__title"&gt;{{ entry.title }}&lt;/h3&gt;
                    &lt;p&gt;{{ entry.featuredSummary }}&lt;/p&gt;
                    &lt;p&gt;&lt;span class="link--green" href="{{ entry.url }}"&gt;Learn More&lt;/span&gt;&lt;/p&gt;
                &lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        {% endfor %}
    &lt;/div&gt;&lt;!-- /.article-cards --&gt;
 {% endfor %}


If I hardcode the category field name into line 1 of the above block everything works. However if I try to use the passed varialbe. I get this error, which I don't know how to fix:


  Craft\EntryModel and its behaviors do not have a method or closure
  named "categoryName".
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.

{% set entriesGrouped = entries|group('{ object[categoryName].first().title }') %}


Here’s an attempt to explain the syntax.

First you should have a look at the Craft documentation for Dynamic Entry Titles. You see that you can dynamically generate titles with a normal Twig template {{ object.property }} or a special shortcut syntax {property}.

The group filter uses the same internal functionality to render the string that you pass in as a filter argument group('my twig template string'). The syntax has to be a bit different though, because group already adds one pair of curly braces for you.

So usually you echo the title property like so

{{ object.title }}


and in the context of the group filter you can do both of the following.

{% set entriesGrouped = entries|group('title') %}

{% set entriesGrouped = entries|group('{ object.title }') %}


The first syntax, which uses the shortcut syntax, is documented and fine for most cases. But you can’t use it if you need to do something a bit more advanced, like using a ternary operator or in your case access the object object differently.

So to wrap this up, the syntax for group('{ object[categoryName].first().title }') is confusing. But what it does is to render the following Twig code for each element of your array of entries (each entry is passed in as the variable object).

{{ object[categoryName].first().title }}


If you don’t like the object['propertyName'] syntax, you can use the attribute function instead.

{{ attribute(object, categoryName).first().title }}