1

I've been having trouble figuring out how to query my entries for another template. Currently, I have a channel of entries for "programs." These programs have a super table that contains a list of states (stateRestrictions). You can add an individual state, then input some text description details about that program in that state. For example, under the program for "dog walker," you can add "Nebraska" as a state with details about the program. Each program can have any number of states.

On a separate template, I want to query all programs that have a super table entry with "Nebraska" and list them under that state.

That template looks like this:

{% extends "layout/main" %}

{% block main %}

    <section class="base global-modules">
        <div class="constrained-layout state-restrictions">
            {% set stateRestriction = craft.app.fields.getFieldByHandle('stateRestrictions') %}
            {% for field in stateRestriction.blockTypeFields if field.handle=='region' %}
                {% for option in field.options %}
                    <div class="state">
                        <h2 class="title">{{ option.label }}</h2>
                        {% for entry in craft.entries.section('programs').all() %}
                            {% if entry.stateRestrictions|length %}
                                {% for row in entry.stateRestrictions %}
                                    {% if row.region == option.value %}
                                        <div class="program">
                                            <h3 class="title"><a href="{{ entry.url }}">{{ entry.title }}</a></h3>
                                            <div class="label {{ row.restrictionLevel.value }}">{{ row.restrictionLevel.label }}</div>
                                            <div class="description">
                                                {{ row.text }}
                                            </div>
                                        </div>
                                    {% endif %}
                                {% endfor %}
                            {% endif %}
                        {% endfor %}
                        <p class="note">This state has no program restrictions.</p>
                    </div>
                {% endfor %}
            {% endfor %}
        </div>
    </section>

{% endblock %}

I'm trying to query the stateRestrictions dropdown of states to generate the list of states on this template, then show the programs that have that state as a filled value, but my approach seems convoluted and also unable to handle the case where there are no restrictions and a state should just show "No restrictions." It is a bit confusing since the query needs to bubble up from within the program entry. Is there a better way of approaching this?

1 Answer 1

1

Instead of going through the entries and manually searching their super table blocks, I would query the super table blocks directly. You can use Super Table Block Queries to find specific blocks. For example:

{% set stateRestrictionsField = craft.app.fields.getFieldByHandle('stateRestrictions') %}
{% set state = 'Nebraska' %}
{% set restrictionsForState = craft.superTable.blocks()
    .fieldId(stateRestrictionsField.id)
    .region(state)
    .all()
%}
{% for block in restrictionsForState %}
    {% set program = block.owner %}
    {# … #}
{% endfor %}

You may need to adjust the query (for dropdown fields, you can search by value instead of label), but you get the idea. This will find all super table blocks in the stateRestrictions field with the region set to Nebraska. Then you can iterate through those directly. If you need access to the entry the block is on, you can access it with block.owner as in the example above.

If you really need a list of entries with those blocks (e.g. to sort them), you can map the array of super table blocks to an array of entries like this:

{% set entriesWithStateRestriction = restrictionsForState|map(block => block.owner) %}
1
  • 1
    Aha excellent, that is great. I didn't know about block.owner, which is very helpful in this case. I set the state to option.label, which also will work through each state in the field dropdown.
    – Erol
    Commented Mar 24, 2023 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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