I'm trying to create a list of countries with a sublist of territories per country based on their existence in the same record. The following is shorthand pseudocode to illustrate:

    locations =>
         United States =>
             New York
         France =>

Here is my code so far:

   {% set allEntries = craft.entries.section('projects').limit(2000) %}
   {% set countries = allEntries|group('country') %}
   {% set country_arr ={} %}

   {% for country, entriesInCountry in countries %}

       {% if not attribute(country_arr, country) is defined %}

         {# Add country to list, if unique #}

         {% set country_arr = country_arr | merge([country]) %} 

       {% endif %}

       {% for entry in entriesInCountry %}

          {# Somehow add the entry.state here as a property or sub-object of the country, if unique #}

       {% endfor %}
  {% endfor %}
  • Why don't you just relate your territories with your countries via relation field or you create a structured section with parent child relations Apr 19 '18 at 21:50
  • The data for the site self-presented in this way and it's how it makes sense to the client. I'm trying to avoid redundant queries in this instance and a few other relational instances Apr 19 '18 at 21:52
  • There won't be redundant queries when you use relation fields. How to you know which territory belongs to which country then? Apr 19 '18 at 21:54
  • I have roughly 1,620 records of these projects, some data being geographical. The client needs to have the freedom to add or edit these records without going into field setup. They set it up as text, and it appears in search drop downs on the next query. Apr 19 '18 at 21:56
  • Well without explaining more of your structure you won't receive any help since we can't provide any hints. You have a custom record and don't use Craft elements, you don't use Craft fields but how are your records stored. Could you show us both classes? Apr 19 '18 at 21:59

Definitely not the most efficient way to do this (it'd be cleaner and more efficient with PHP), but assuming you have "projects" section that has a "country" Plain Text field and it also had a "state" Plain Text field and you wanted to group projects by country and then state, something like this should work:

{% set countryArr = {} %}

{# grab all projects #}
{% set allEntries = craft.entries.section('projects').limit(null) %}

{# group them by country #}
{% set countries = allEntries|group('country') %}

{# Build the nested array structure #}
{% for country, projects in countries %}
    {# if it's a new country, add it to our structure #}
    {% if countryArr[country] is not defined %}
        {% set countryArr = countryArr|merge({(country):[]}) %}
    {% endif %}

    {# loop through all of the projects in that country #}
    {% for project in projects %}
        {# see if we have a record for the state yet #}
        {% if project.state not in countryArr[country] %}
            {# because twig isn't great with multidimensional arrays #}
            {% set tempArr = countryArr[country] %}
            {% set tempArr = tempArr|merge([project.state]) %}

            {# merge back into our main structure indexed by country #}
            {% set countryArr = countryArr|merge({(country):tempArr})  %}
        {% endif %}
    {% endfor %}
{% endfor %}

{# output our structure #}
{% for country, projects in countryArr %}
        <li>{{ country }}
                {% for project in projects %}
                    <li>{{ project }}</li>
                {% endfor %}
{% endfor %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.