Take the 2-minute tour ×
Craft CMS Stack Exchange is a question and answer site for administrators, end users, developers and designers for Craft CMS. It's 100% free, no registration required.

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

3 Answers 3

up vote 7 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 :) –  ianisted Jul 10 at 6:45

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 :) –  ianisted Jul 8 at 13:33

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()
{
    parent::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
        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 :) –  ianisted Jul 8 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 at 13:52
3  
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 at 14:27
    
@StuartWhitehead I really don't know why I haven't thought of that -.- –  Victor In Jul 8 at 14:29
1  
@VictorIn Your staggering SE rep is clouding your judgment, Victor. :) –  Matt Stein Jul 9 at 16:56

Your Answer

 
discard

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.