Note: I spend a lot of time in this question explaining, what I've been trying to do, but the end goal is to be able to sort by content type in an arbitrary order. I'm then grouping on content type, and getting headings in my results as desired. If you can show me how to do it without hook_views_query_alter() I'd be just as happy, though why my solution isn't working is giving me an ulcer. I'd prefer to avoid creating a whole bunch of attachments since I'm dealing with about 20 types here, but I think that is the next thing I'll have to try if nobody can help me.

A few other answers here, have gotten me to where I feel I'm close, but I'm getting not results, hopefully someone here can see what I'm doing wrong.

My actual setup is more complex than this. Basically I have a variable in settings that gives me some details about the different content types I'm dealing with, including a weight value for each. I'm building my order by clause using those weight values, but that doesn't seem to be the problem, so here is the query taken to it's simplest form:

Given a view that loads a set of nodes of at least two different types, one of which (for the purposes of this function has a machine name of 'brief' and a human readable name of Briefs):

 * Implements hook_views_query_alter().
function MYMODULE_views_query_alter(&$view, &$query) {

    if ($view->name == "view_name" && $view->current_display == "display_block_name") {

        $caseclause = 'CASE node_type WHEN "brief" THEN 1 ELSE 2 END';
        array_unshift($view->query->orderby, array(
            'field' => $caseclause, 
            'direction' => 'ASC'));

I would expect this to give me the node listing with Briefs listed first, and other types listed afterward. Instead I get no results. If I remove the alteration to $view->query->orderby I get results. I've tried checking for "Briefs" instead of "brief". I got the column name, by adding it as a sort in the view and seeing what the view itself used, but just in case I've also tried node.type and type as the column name to put in the case statement. I tried doing all of this with the $query object too, just in case.

I tried adding the CASE clause as $query->addExpression, setting an alias of order_col for the expression, intending to then order by that column, but the whole page stopped showing up. It is possible I did something wrong on that attempt, if you can make that work, please let me know.

So here's what I need: How can I make a CASE statement work in hook_views_query_alter(), or failing that, how can I sort content type by an arbitrary order?

Here's a really brief section of the configuration variable that I have in settings.php that I'm trying to get the weight value from to do my sort.

$conf['pubtype_bundles'] = array(
    'brief' => array(
        'name' => 'Briefs',
        'weight' => 5,
        'description' => 'Issue Briefs, Policy Briefs, and Briefing Notes',
        'help' => '',
        'types' => array(
            'issue' => 'Issue Brief',
            'policy' => 'Policy Brief',
            'briefing' => 'Briefing Note',
        'typehelp' => '',
    'book' => array(
        'name' => 'Books',
        'weight' => 10,
        'description' => '',
        'help' => '',
        'types' => array(
            'book' => 'Book',
        'typehelp' => '',

2 Answers 2


When you want to do arbitrary sort, U must be having your own sorting routine/algo/criteria? When you have that then you can add a "global php" field in sort criteria and then u can use a setup code(if required) and then you can write your sorting logic in "sort code". enter image description here enter image description here enter image description here

  • I'll add a brief sample of what I'm working with in the question. I really just need a simple numerical sort, the issue is that there is no where to provide those numbers. It looks like your solution must be using php views or something?
    – UltraBob
    Jun 15, 2016 at 7:05
  • Yup my solution is using php views and u can get the numerical sort done in the global php Jun 15, 2016 at 10:49
  • This is the best answer so far. I've ended up just making a bunch of attachments and adding them to views in the right order, which will be a giant PITA if the order needs to change. I'd really like to know why my CASE solution doesn't work, I've seen others, including someone on the documentation page for the hook claiming that it should.
    – UltraBob
    Jun 16, 2016 at 3:13

Though I am not very clear with this

Basically I have a variable in settings that gives me some details about the different content types

What I understood is, you have a settings defined somewhere which has weight and content type relation. Based on this one solution can be:

  • Create a weight field / setting (assuming there is no configuration for it) in content types, and populate the weight from your settings.
  • Use this weight field to sort nodes in views.
  • Thank you. The problem with this approach is that the only way I can see to do that is to create an admin only weight field in each content type's fields with a default value. In the larger scheme it is minimal, but that is a lot of unnecessary duplication. Additionally: when I decide I want one type to move up, I need to somehow go update every single node of all content types whose weight has changed.
    – UltraBob
    Jun 15, 2016 at 6:55
  • Yes, duplication will be a problem. You may also try using this module - drupal.org/project/vvf, It allows you to use variables in views. Or If it doesn't work, I think you will have to create views handler relations.
    – user62410
    Jun 15, 2016 at 7:01
  • I'm trying to figure out how this would help me, but I'm not quite seeing it. Does it integrate with tokens? If I could have variables set for type_book_weight and type_brief_weight, etc and then load the appropriate variable based on the type, then I could see where that would be workable, assuming it is available to the filters and not just to the fields. By the way, I updated my question to clarify the part that was unclear.
    – UltraBob
    Jun 15, 2016 at 7:10

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.