8

I have two Instagram API responses that I want to merge, by the photo's created_time. Is there a way to do that in Twig?

Right now I am just using this

{% set instagram = <data> %}
{% set community = <data> %}
{% set feed = instagram|merge(community) %}

    {% for photo in feed %}
        <img src="{{photo.images.low_resolution.url}}" alt="">
        <br />
    {% endfor %}

Each photo has a created_time string that I'd like to sort the array by, is that possible without creating a custom Twig extension?

The sortByField plugin looked promising and sort of what I want, but it was directly aimed at Craft entry manipulation. Is there anything hacky that could be done?

  • 2
    Since the only way to sort a multidimensional array in PHP is with a usort and thus a custom function based on your array, I think you'd have to create a custom twig filter. You could use one of mine as a base. It's very simple, so pretty easy to pick apart: github.com/jpeacock/highestmultiple – jpea Jul 9 '14 at 19:51
  • 1
    Yeah it looks that way! I've already written a primitive plugin for getting the first paragraph of an Rich Text Field so i should be able to hack something together. Which is a pain, because the sortByField plugin gets quite close. Thanks! – Sean O'Grady Jul 10 '14 at 0:20
8

This is only possible with a custom Twig Extension, since sorting a multidimensional array can't be done with Twig itself.

I've written a plugin which extends Twigs sorting methods, which you could use as a base: Craft-TwigBetterSort.

Just add this to the TwigBetterSortTwigExtension.php

public function twig_sort($array, $method='asort', $sort_flag='SORT_REGULAR')
{
    // ....
    case 'custom_sort_name':
        usort($array, array('TwigBetterSortTwigExtension','custom_sort_function'));
        break;
    // ....
}

private function custom_sort_function($a, $b)
{
    // Do stuff with your array
}

and use it like this in your templates:

{% array|sort('custom_sort_name') %}
  • hmm not having any luck with this. feel like im missing something. I have object similar to the original question and i have this... case 'dateSort': usort($array, array('TwigBetterSortTwigExtension','created_date_sort')); break; ... public function created_date_sort($a, $b) { if ($a.created_at == $b.created_at) { return 0; } return ($a.created_at < $b.created_at) ? -1 : 1; } – Keith Mancuso Jul 25 '14 at 18:24
  • @KeithMancuso Just tried your code on a random array: {% set array = { 2: '5', 4: '6', 1: '5', 3: '6', 2: '7', 4: '8' } %} and it got re-sorted. What exactly isn't working for you? (Share bigger code using CraftBin ) – Victor In Jul 25 '14 at 22:50
  • Sorry you are right it's working, not sure what was going on but thanks – Keith Mancuso Aug 1 '14 at 1:23
13

The SuperSort Plugin is built for use cases exactly such as this. It allows you to render each object in your array using a Twig object template and sort the array based on the rendered value.

For example, in OP's case, we could sort the combined array by the created_time variable like this:

...
{% set feed = instagram|merge(community) %}
{% set sortedFeed = feed | supersort('sortAs', '{created_time}') %}

(The plugin parses {created_time} — a Craft 'micro-template' — into {{object.created_time}}, which provides the value by which the array is sorted.)

If the property of interest happened to be different between two arrays, we could include a conditional or ternary operator in the micro-template to differentiate them:

{% set sortedFeed = feed | supersort('sortAs', '{{ object.current_time is defined ?: object.someOtherProperty }}') %}
  • There's a download link on the docs page: michaelrog.com/craft/supersort – Michael Rog Jan 24 '15 at 16:55
  • I'm trying to accomplish the same. Making some sort of feed with multidimensional data array. Like combining comments feed with entries and twitter. Michael can you give us a simple example of to use your plugin? De docs are hard to understand for me. – Johannes Lamers Mar 28 '15 at 23:07
  • Surely — I've added a code example to my answer. – Michael Rog Mar 29 '15 at 3:55
  • @michael Great little plugin, thanks so much for making this. – carlcs Mar 29 '15 at 9:28

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.