1

I need to reuse logic for 15 entry groupings in a template. In my non DRY version, I simply changed one word in the variable name to create a new variable and although it works just fine, it's very cumbersome to make changes because if I need to make a logic change, I have to do it for all 15 groupings. I'm wondering if there's a way to create a main variable group where I could specify each variable keyword once and then have that keyword replaced in the code. I found a similar post: Reusing logic to set string variables

Here's a sample of the code in non DRY fashion. You'll notice the code is almost identical except for the words "Aorta" and "Cardiac". I'm treating each of those words as their respective grouping keyword (the top example in each section shows you were the KEYWORD is).

Set the variables:

<!-- Get study count for logged in sonographer -->
    {% set entriesLogKEYWORD = craft.entries.section('logsQA').search('logGeneral_studyType:KEYWORD').relatedTo(
        { targetElement: currentUser, field: 'logGeneral_sonographerName' }
    ) %}
    {% set entriesLogAorta = craft.entries.section('logsQA').search('logGeneral_studyType:Aorta').relatedTo(
        { targetElement: currentUser, field: 'logGeneral_sonographerName' }
    ) %}
    {% set entriesLogCardiac = craft.entries.section('logsQA').search('logGeneral_studyType:Cardiac').relatedTo(
        { targetElement: currentUser, field: 'logGeneral_sonographerName' }

<!-- Starting study count -->
    {% set startingCountKEYWORD = currentUser.userProfile_startingCountKEYWORD %}
    {% set startingCountAorta = currentUser.userProfile_startingCountAorta %}
    {% set startingCountCardiac = currentUser.userProfile_startingCountCardiac %}

<!-- Count logged -->
    {% set countLogKEYWORD = entriesLogKEYWORD.total %}
    {% set countLogAorta = entriesLogAorta.total %}
    {% set countLogCardiac = entriesLogCardiac.total %}

<!-- Count total -->
    {% set countTotalKEYWORD = countLogKEYWORD + startingCountKEYWORD %}    
    {% set countTotalAorta = countLogAorta + startingCountAorta %}
    {% set countTotalCardiac = countLogCardiac + startingCountCardiac %}

Output to front end:

<table class="table">
    <tbody>
        <tr>
            <td class="c-font-uppercase c-font-bold" scope="row">KEYWORD</th>
            <td class="c-center c-font-bold"> {{ countTotalKEYWORD }}</td>
        </tr>
        <tr>
            <td class="c-font-uppercase c-font-bold" scope="row">Aorta</th>
            <td class="c-center c-font-bold">{{ countTotalAorta }}</td>
        </tr>
        <tr>
            <td class="c-font-uppercase c-font-bold" scope="row">Cardiac</th>
            <td class="c-center c-font-bold">{{ countTotalCardiac }}</td>
        </tr>
    </tbody>
</table>

Possible to set the keyword variable and then call it elsewhere like this so template would look something like this where I'd only be writing the logic code once?

{% set KEYWORD = "Aorta %}
{% set KEYWORD = "Cardiac" %}
etc...

<!-- Get study count for logged in sonographer -->
    {% set entriesLogKEYWORD = craft.entries.section('logsQA').search('logGeneral_studyType:KEYWORD').relatedTo(
        { targetElement: currentUser, field: 'logGeneral_sonographerName' }
    ) %}

<!-- Starting study count -->
    {% set startingCountKEYWORD = currentUser.userProfile_startingCountKEYWORD %}

<!-- Count logged -->
    {% set countLogKEYWORD = entriesLogKEYWORD.total %}

<!-- Count total -->
    {% set countTotalKEYWORD = countLogKEYWORD + startingCountKEYWORD %}

<!-- OUTPUT -->
<table class="table">
    <tbody>
        <!-- Loop through all keyword groups? -->
        <tr>
            <td class="c-font-uppercase c-font-bold" scope="row">KEYWORD</th>
            <td class="c-center c-font-bold"> {{ countTotalKEYWORD }}</td>
        </tr>
        <!-- END Loop -->
    </tbody>
</table>
1

If you use brackets notation instead of the usual dot notation to access your different properties, you can append a keyword variable to the property handle:

{% set startingCount = currentUser['userProfile_startingCount'~keyword] %}

Of course, you can use the ~ operator to append a keyword to your craft.entries .search() parameter as well:

{% set entriesLog = craft.entries.section('logsQA').search('logGeneral_studyType:'~keyword) ... %}

So with that in mind, it'd probably make sense to create a simple array with your keywords, and just loop over them like this:

<table class="table">
    <tbody>

        {% set keywords = ['Aorta', 'Cardiac'] %}

        <!-- Loop through all keyword groups -->    
        {% for keyword in keywords %}

            <!-- Get study count for logged in sonographer -->
            {% set entriesLog = craft.entries.section('logsQA').search('logGeneral_studyType:'~keyword).relatedTo(
    { targetElement: currentUser, field: 'logGeneral_sonographerName' }
) %}

            <!-- Starting study count -->
            {% set startingCount = currentUser['userProfile_startingCount'~keyword]|default(0) %}

            <tr>
                <td class="c-font-uppercase c-font-bold" scope="row">{{ keyword }}</th>
                <td class="c-center c-font-bold">{{ entriesLog.total() + startingCount }}</td>
            </tr>

        {% endfor %}
        <!-- END Loop -->

    </tbody>
</table>

Note: I've omitted the countLog and countTotal variables completely in the above example; unless those two variables are going to be re-used, in this case its perfectly fine to just add up entriesLog.total() + startingCount when you echo the value, saving a few lines of code.

Also note that I've added a |default(0) to the startingCount variable, just in case the 'userProfile_startingCount'~keyword property doesn't exist for currentUser (in which case you'd probably get a template error).

| improve this answer | |
  • Thank you so much, Mats, that worked perfectly to get my total studies. I have another template that I'm doing something similar but I can't get it to work. I will edit my original so I can include the code. – Lori Aug 26 '16 at 12:57
  • That's great, @Lori – happy it helped you out. It might be a good idea to create a new question for your other template, unless that issue is specifically related to this one. – Mats Mikkel Rummelhoff Aug 26 '16 at 13:06
  • Thanks, @MatsMikkelRummelhoff. I edited this post because the two templates are almost identical and using the same types of variables. I hope that was the correct thing to do. – Lori Aug 26 '16 at 13:18
  • I figured out my additional question so I removed it from the original post. Thanks again @MatsMikkelRummelhoff for your help. – Lori Aug 26 '16 at 15:36

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.