I need to count the number of consecutive years a user has been a member of our organization. For example, if they've been a member from in 2018, 2019, 2020 and 2021, their loyalty will be 4 years.

If they've been a member in 2018, 2019 and 2021, their loyalty will be 1 year (they missed 2020.)

I'm currently using Categories to assign a year to Users in Craft to do the assignment of a year to a person.

Hope that makes sense. I would very much appreciate some help on how to tackle it!

2 Answers 2


If you don't want to build a custom plugin, this would be a good time to use Twig's reduce filter, which takes a set of values and iterates over them to output a single value based on supplied logic.

Using Andy's answer as the basis might look like this (untested):

{% set currentYear = now|date('Y') %}

{% set loyaltyScore = currentUser.years.all()|reduce(
    (score, year) => 
        score == 0 and year == currentYear or 
        score > 0 and year == currentYear - 1 ?
        score + 1,
) %}

I'm assuming your data is already in the right order if it's a category group.

  • Thanks so much for this! So my categories are in the format of 2021/22, so I updated a bit to the following, but when I dd on loyaltyScore it's blank. I've not used reduce before so a bit unsure. {% set currentYear = now|date('Y') ~ '/' ~ now|date_modify("+1 year")|date('y') %}
    – supazu
    Apr 27, 2021 at 5:46
  • Trying to do maths on something that's not a number is going to be tricky! You should look to convert the format into a proper number with just a single year. You could convert "2021/22" to "2021" using Twig's slice filter: {{ '2021/22'|slice(4) }} Apr 28, 2021 at 8:21
  • Thanks for your help - looks like this one is a bit beyond me.
    – supazu
    Apr 30, 2021 at 1:04


  • Fetch all category values, push the year string to an array.

  • Sort that array in descending order by value.

  • Initialise a counter, loop over the array, cast each value as an integer:

    -- if first array value is same as the current year, increase a counter, otherwise break.

    -- if loop year equals previous loop year minus 1, increase a counter otherwise break.

Your loyalty value is the counter.

  • The code is the part I'm having trouble with 😅
    – supazu
    Apr 30, 2021 at 1:05
  • That's fairly straightforward PHP, trying to do it in Twig is just making things more complicated (and really, you should minimise the amount of logic/processing in a Twig template). It would be worth looking at creating a Twig filter in a Craft module, which you could pass the user's years history to, e.g. currentUser.years|myfilter
    – Wallace
    Apr 30, 2021 at 7:55

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.