Skip to main content

Restrict nodequeue by field values

File under

A couple of times now I’ve wanted to restrict what can go into a nodequeue by more than just the node type. A good example of when you might want to do this (though not my use case) is if you want to restrict the blog posts that can go into a carousel to only those posts that have an image. In any case, there are three steps to putting your restriction in place:

  1. Apply greggadson’s nodequeue patch:
  2. Implement hook_query_TAG_alter() to rewrite the title autocomplete query (this is for the title autocomplete found at admin/structure/nodequeue/%qid/view/%qid).
  3. Implement hook_nodequeue_alter() to prevent certain queues from showing up at node/%nid/nodequeue.

In detail:

  1. Apply the patch to nodequeue. This adds a tag and some metadata that allows you to intercept the autocomplete query and to tell you which queue you’re dealing with.
  2. Implement hook_query_TAG_alter(). This will vary depending on what you’re trying to do. In my case, I’m filtering on the value of field_member_type. I create a join on that table and then add a condition (the WHERE part of the query); $query is an object so it’s automatically passed by reference even though I don’t request it.
    function YOUR_MODULE_query_nodequeue_api_autocomplete_alter($query) {
      $qid = $query->alterMetaData['queue']->qid;
      if ($qid == MEMBER_PROFILE_QID || $qid == VOLUNTEER_PROFILE_QID) {
        if ($qid == MEMBER_PROFILE_QID) {
          $value = 'Member';
        else {
          $value = 'Volunteer';
        $query->join('field_data_field_member_type', 'm', 'n.nid = m.entity_id');
        $query->condition('m.field_member_type_value', $value);
  3. Implement hook_nodequeue_alter() to unset the queues that are “loaded” for this node. Ideally we’d hit this a bit earlier (i.e., before load), but nodequeue doesn’t provide many hooks and this is the only one that works.
    function YOUR_MODULE_nodequeue_alter(&$loaded, $context) {
      if (arg(0) == 'node' && is_numeric(arg(1))) {
        // Unfortunately menu_get_object() doesn't work here.
        $node = node_load(arg(1));
        $node_wrapper = entity_metadata_wrapper('node', $node);
        if ($node_wrapper->getBundle() == 'member_profile') {
          $member_type = $node_wrapper->field_member_type->value();
          if ($member_type == 'Member') {
            // Clear out the Volunteer nodequeue.
          else {
            // Clear out the Member nodequeue.

You might also want to reference adding conditional clauses to queries: