Craft CMS Stack Exchange is a question and answer site for administrators, end users, developers and designers for Craft CMS. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to work out how I can order news posts by postDate, unless a lightswitch is toggled for a post, at which point it will use the dateUpdated to order that item.

This is so a client can still change posts without them appearing at the top of the list (for corrections, etc), but also make substantial updates to certain posts and have them appear as the latest newest item.

share|improve this question
up vote 8 down vote accepted

You can do this entirely from the order param using MySQL’s CASE syntax:

{% set newsItems = craft.entries({
    section: 'news',
    order:   '(CASE field_myLightswitchField
                  WHEN 1 THEN elements.dateUpdated
                  ELSE elements.dateCreated
              END) DESC'
}) %}

Note that you’ll need to include that “field_” prefix before your Lightswitch field’s handle since this is a more complex condition and Craft won’t be sure if it should add that automatically.

share|improve this answer
That is perfect! Thank you Brandon :) – Ian Isted Jul 10 '14 at 6:45

I don't know if it's possible (but would like to see a query solution).

There is one problem with your setup: If an entry gets a "substantial update", you can't make a correction afterwards, since it would become the latest item again.

I propose you write a plugin which would:


Quick-and-Dirty example:

public function init()

    //Event: onBeforeSaveEntry
    craft()->entries->onBeforeSaveEntry = function(Event $event) {

        //Check if its the right section
        if ( $event->entry->section == 'news' ) {

            //Check if the lightswitch-field is "on"
            if ( $event->entry->lightswitch_field_handle == 1 ) {
                //Set postDate to current date
                $event->entry->postDate = $event->entry->dateUpdated;

                //Set Lightswitch-filed to "off"
                $event->entry->lightswitch_field_handle = 0;


        return $event;


If you add this function to your primary plugin class and sort your entries by postDate it should work just like you want.

share|improve this answer
This is quite an interesting solution, wondering if we could produce a solution based around this idea. Thank you :) – Ian Isted Jul 8 '14 at 13:33
Forgot to say that you just need to add this function to your primary plugin class and sort your entries by postDate. – Victor In Jul 8 '14 at 13:52
If you're going to the trouble of resetting the postDate programatically, why don't you just ask your client to change the postDate themselves—they'd be changing the lightswitch field anyway? This would give you the exact same result but without any extra code. – Stuart Whitehead Jul 8 '14 at 14:27
@StuartWhitehead I really don't know why I haven't thought of that -.- – Victor In Jul 8 '14 at 14:29
@VictorIn Your staggering SE rep is clouding your judgment, Victor. :) – Matt Stein Jul 9 '14 at 16:56

I think I'd create a twig function or filter to create a custom sort (usort in php), pass the collection to the function so it's returned 'sorted'.

Would be interested in seeing if anyone has a nice craft.entries query straight off the bat for this though.

share|improve this answer
Thanks Billy. This is also and interesting direction :) – Ian Isted Jul 8 '14 at 13:33

My 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.

So, you could do something like:

{% set sortedEntries = entries | supersort('sortAs', '{{ object.myLightswitch == 'y' ? object.dateUpdated: object.postDate }}') %}
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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