This is the documentation page for the Nodequeue module.

The original source for most of this information is the README.txt file.

You may also wish to view the Comparison of node ordering modules

The Nodequeue module allows users to put nodes in an arbitrarily ordered list. Examples of this might be to create a block listing teasers for 5 forum posts that the admin thinks are important. Another use might be to create a list of nodes, and then display a randomly selected node from the group on the frontpage of the site. This concept is extended upon with Smartqueues (see below).

Queues and Subqueues

Note: Despite the fact that this module is called "Nodequeue", there is no such thing as a nodequeue, and you'll never encounter one when working with the module. A nodequeue is like the Loch Ness monster or Big Foot or a pleasant experience with airport security: It doesn't exist.

If you see something in the module's interface or code that refers to a Nodequeue, please file a bug report.

When working with the Nodequeue module, you will encounter queues and subqueues. A subqueue is an individual list of nodes. Every subqueue belongs to a parent queue, which contains settings that affect all of the subqueues that belong to that queue. Yes, a queue can have many subqueues. When a queue has many subqueues, the subqueues are neatly listed on the Queue administration page.

Some settings that Queues can have include:

  • Restriction of which types of nodes can be added to the queue's subqueues
  • How long subqueues within the queue can be (how many nodes each can contain)
  • Which user roles can manipulate the subqueues

The most basic way to use Nodequeue is with simple queues. A simple queue contains only one subqueue. Why have the distinction between queues and subqueues? See below on Smartqueues.

Smartqueues

Nodequeue allows companion modules to define new types of queues -- called smartqueues -- which have special behavior. For example, the Taxonomy Queue module (included with the Nodequeue package) provides a single subqueue for each term of a vocabulary.

The Smartqueue per-user module allows each user on the site to have his or her own personal subqueue.
The Smartqueue per-organic group module provides a subqueue for each organic group.

Developers can read more about the Smartqueue API below.

Embedding Content from a queue

Once a queue is set up, a new tab will appear on eligible nodes for eligible users. This tab will allow the user--regardless of node edit permissions--to add or remove that node from the queue. Queue admins can view the nodes in the queue, and can modify the items therein. Items may also appear in a node's links area to add/remove them from the queue.

When a node is added to the subqueue, it is added to the back. If a subqueue is full when a node is added, the front is removed.

Nodequeue has support for nodes with i18n Internationalizations.
You must install the Translation Helpers module.

Automatic Creation of Views

When configuring Nodequeue, you can opt to "Automatically create one view per queue" (you may wish to leave this off if you plan to create the views yourself).
The views created automatically cannot be deleted from the Views interface because they are implemented "in code". However, if you disable the auto-creation, then clear caches, these views will be removed.

It is highly recommended that you use the Views module to display your subqueues. However, if you choose not to, you can alternatively use a small PHP snippet.

To use nodequeue from views (D7), add a 'relationship' to the queue, and typically set to 'require this relationship'. Optionally add 'nodequeue: Position' to match the preset queue order.

You can embed a node that is in a particular position in a queue (without writing code) anywhere there is an input format by using the Insert View module to embed a View that takes the subqueue id and position as arguments, using the

"[view:name of view=name of display=arg1,arg2,arg3] invokes the view using the specified display and passes arg1, arg2 and arg3 to the view.]" format.

Programmatic Ways of Displaying Content from a Queue

Nodequeue provides several functions which simplify getting a loaded node object from the front, back or a random position in a queue. For more selecting or displaying content in a more specific or complicated way, the Views module is probably your best bet.

Please note that there are some differences between the functions available in the 5.x-2.x and 6.x.-2.x versions of Nodequeue.

To Create a Block to Display Node Titles of a Queue

You'll need the Queue ID, which is easily extracted from the URL on the queue administration page.

Create a new block, and insert the following PHP snippet into the block:

print nodequeue_node_titles($subqueue_id);

If you want this queue to be printed in the reverse order, you can tell it to print backward:

print nodequeue_node_titles($subqueue_id, '', TRUE);

The '' in the line above is an optional title field. Feel free to put something here, but it's not terribly necessary in a block.

To Display a list of teasers from a queue:

Like above, you'll need the Queue ID.

Create a new page (or a new dashboard!) or any node type you like, really, and set the input filter to PHP. Insert the following PHP snippet:

With Nodequeue 6.x-2.x:

print nodequeue_view_nodes($subqueue_id);

With Nodequeue 5.x-2.x

print nodequeue_nodes($subqueue_id);

There are a few more options available here; changing the order of the nodes, whether or not to use teasers or full nodes, whether or not to display the links, and how much of the queue to display. See below.

To render the first or last node from a queue

With Nodequeue 6.x-2.x:

 $node = nodequeue_load_front($subqueue_id);
 $rendered_node = node_view($node);
  

With Nodequeue 5.x-2.x:
$rendered_node = nodequeue_fetch_front($subqueue_id);

Or

With Nodequeue 6.x-2.x:

 $node = nodequeue_load_back($subqueue_id);
 $rendered_node = node_view($node);
  

With Nodequeue 5.x-2.x:
$rendered_node = nodequeue_fetch_back($subqueue_id);

To render a random node from a queue

With Nodequeue 6.x-2.x:

$node = nodequeue_load_random_node($subqueue_id);
$rendered_node = node_view($node);

With Nodequeue 5.x-2.x:

$rendered_node = nodequeue_fetch_random($subqueue_id);

Remember that the front of the queue will have the least recently added nodes (unless it was rearranged manually), and the back will have the most recently added.

Available Functions and Descriptions

NOTE: this section needs to be updated for Nodequeue 6.x-2.x

nodequeue_node_titles($qid, $title = '', $backward = TRUE, $from = 0, $count = 0)
Display a title list of the queue. If backward is TRUE (the default) the list will be from back (newest) to front (oldest).
nodequeue_nodes($qid, $backward = TRUE, $teasers = TRUE, $links = TRUE, $from = 0, $count = 0)
Display the nodes of a queue. If backward is TRUE (the default) the list will be from back (newest) to front (oldest). If $count is set to non-zero, it will use a range. For example, passing $from = 2 and $count = 2 will show the 3rd and 4th elements of the queue. ($count starts at 0, not 1.) If $teasers is TRUE, the node teaser will be shown; otherwise the full node will be shown.
nodequeue_fetch_front($qid, $teasers = TRUE, $links = TRUE)
Fetch the node at the front of the queue.
nodequeue_fetch_back($qid, $teasers = TRUE, $links = TRUE)
Fetch the node at the back of the queue.
nodequeue_fetch_random($qid, $teasers = TRUE, $links = TRUE)
Fetch a random node from the queue.

Nodequeue API

Beginning with 6.x-2.5 the following API calls will be available in Nodequeue:

hook_nodequeue_info()
Collect info about all of the possible nodequeue types from owning modules.
hook_nodequeue_add($sqid, $nid)
A node is being added to the given node queue.
hook_nodequeue_remove($sqid, $nid)
A node is being removed from the given node queue.
hook_nodequeue_swap($sqid, $nid)
A node is being swapped in a queue ie it's delta is changing.

Actions Module Integration

The node queue module provides two actions, so that workflow can add and remove items from queues.

Smartqueue API

Nodequeue provides a robust API that allows other modules to define smartqueues, which are associated with external data. For example, the included taxonomy smartqueue creates subqueues for a given queue for every term in the chosen vocabulary. Nodes are then only eligible for subqueues whose term matches the nodes terms. This makes it very easy to have queues for each category without cluttering the management page.

You might be wondering about the performance implications of a site a taxonomy smartqueue with thousands of taxonomy terms and thousands of nodes. Currently, no public benchmarks have been available, and smartqueue_taxonomy (currently smartqueue.module) includes a warning about possible performance implications, but merlinofchaos writes:

For a single vocabulary, I don't think the size matters much.

If you select multiple vocabularies, it has to process all of the possible combinations of terms, so thousands of terms could start to have a performance impact on your site. I would recommend not doing this.

I didn't do any benchmarks so I don't have specific numbers; I threw in the warning because, at the time I wrote it, it seemed like a good idea to let people know that doing something like combining two taxonomies each with a thousand terms (which leads to a million unique combinations) could really create lots of subqueue data.

Example Smartqueue API Implementation

Smartqueue API hook definitions begin with nodequeue_api -- so reading the doxygen documentation for these functions will be helpful. You can also learn about the smartqueue API by reading existing smartqueue modules. A hypothetical code example is listed below, and you can also look at the Smartqueue_og and Smartqueue_users modules.
This hypothetical smartqueue_author (or authorqueue) module demonstrates a basic implementation of the Smartqueue API. If you wish to have a Nodequeue based on node authorship, please see the Smartqueue_users module.

<?php
// $Id: authorqueue.module,v 1.4 2008/10/06 15:47:34 ezrag Exp $
//This Module exists as a simple example of Nodequeue's Smartqueue API.
//For a Smarqueues based on node authorship, see http://drupal.org/project/smartqueue_user.

/**
 * Implementation of hook_nodequeue_info()
 */
function authorqueue_nodequeue_info() {
  return array('smartqueue_author' => array(
    'title' => t('Author queue'),
    'description' => t('Each user in the selected roles will be given a queue; nodequeue administrators can select nodes by that author for placement into that queue, allowing the site to easily hilight content by particular authors.'),
    ));
}

/**
 * Implementation of hook_nodequeue_form()
 */
function smartqueue_author_nodequeue_form($queue, &$form) {
  $roles = user_roles(TRUE);
  $form['placeholder']['rids'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Roles'),
    '#description' => t('Select which roles a user must have to create a queue. If none are checked, all node authors will get a queue.'),
    '#options' => $roles,
  );

  $form['subqueue_title'] = array(
    '#type' => 'textfield',
    '#title' => t('Subqueue title'),
    '#default_value' => $queue->subqueue_title,
    '#size' => 50,
    '#maxlength' => 64,
    '#description' => t('What to display for the subqueue title; use %subqueue to embed the actual subqueue title. This is used to distinguish multiple nodequeues with subqueues from each other, as internal subqueue title is filled automatically.'),
  );


  if ($queue->qid && !empty($queue->reference)) {
    $form['placeholder']['rids']['#default_value'] = explode('-', $queue->reference);
  }
}

/**
 * Implementation of hook_nodequeue_form_validate()
 */
function smartqueue_author_nodequeue_form_validate(&$form, $form_state) {

  if (!isset($queue->qid)) {
    $rids = !empty($form_state['values']['rids']) ? array_keys(array_filter($form_state['values']['rids'])) : array();
    // Convert this to our reference.
    form_set_value($form['reference'], implode('-', $rids), $form_state, $form_state);
  }
}

/**
 * Implementation of hook_nodequeue_subqueues()
 */
function smartqueue_author_nodequeue_subqueues(&$queue, $node) {
  // Sorry, no anonymous nodes allowed.
  if (empty($node->uid)) {
    return;
  }

  $rids = !empty($queue->reference) ? explode('-', $queue->reference) : array();

  $account = user_load(array('uid' => $node->uid));
  if (!empty($rids) && !array_intersect($rids, array_keys($user->roles))) {
    return;
  }

  if (!nodequeue_load_subqueues_by_reference(array($queue->qid => array($node->uid)))) {
    nodequeue_add_subqueue($queue, $account->name, $node->uid);
  }

  return array($node->uid);
}

function smartqueue_author_nodequeue_subqueue_title($queue, $reference) {
  $account = user_load(array('uid' => $reference));
  if ($account) {
    return $account->name;
  }
}

// TODO:
// * Automatically delete subqueues when a user is deleted.

The example .info file:

; $Id: smartqueue_users.info,v 1.1.2.3 2008/12/26 02:00:06 ezrag Exp $
name = Smartqueue per User
description = Provides a Nodequeue for users of one or more specified roles.
dependencies = nodequeue
package = Nodequeue

Creating queues programmatically

This snippet creates queues.

 $queue_data = array(
    'queue1' => array(
      'title' => 'Name',
      'subqueue_title' => '',
      'size' => '0',
      'reverse' => 0,
      'link' => 'Add to queue',
      'link_remove' => 'Remove from queue',
      'roles' => array ( ),
      'types' => array ( 0 => 'story',),
      'i18n' => 1,
      'op' => 'Submit',
      'submit' => 'Submit',
      'owner' => 'nodequeue',
      'show_in_links' => true,
      'show_in_tab' => true,
      'show_in_ui' => true,
      'reference' => 0,
      'subqueues' => array ( ),
      'new' => true,
      'add_subqueue' => array ( 0 => 'Name',), // match title above
    ),
  );
  
  foreach ($queue_data as $q) {
    $queue = (object) $q;
    $qid = nodequeue_save($queue); // sets $queue->qid if needed.
  }  

Comments

charles_elwood’s picture

If you're including a nodequeue within a node by using a PHP capable input format, remember you need to print the node you want to display. Also node_view() can take extra parameters in order to display a node in teaser form, or suppress the links that usually print at the bottom.

 /* Nodequeue 6.x-2.x only */
$node = nodequeue_load_random_node(1);
print node_view($node, $teaser=TRUE, FALSE, $links=FALSE);
technicka’s picture

I wrote a short article about Nodequeue for anyone that wants a quick overview about how to get started with basic functionality:

http://technicka.net/tech/nodequeue-arbitrarily-ordering-nodes

spacechick’s picture

Thanks so much for article on Nodequeue. I had NO idea how to use it and the documentation didn't help. Your article made it crystal clear and I had my queue up and running within minutes. You deserve a big pat on the back for this!

bdimaggio’s picture

Hey, this article's URL changed. In case anybody else wants to read it: http://technicka.net/articles/nodequeue-arbitrarily-ordering-nodes

aarsic’s picture

Will dive into this because documentation left me puzzled.

dalehgeist’s picture

The goal: display n number of articles on a single page, one of which has been manually flagged as "Featured" and will be displayed differently from the others (for instance, more fields will be displayed.)

Displaying the Featured article is no problem; there are many different ways to flag it and create a View that returns only the one article most recently flagged as Featured.

The problem comes in with the list of non-Featured articles. After some thought and trial-and-error, I concluded that to create that list, and exclude the Featured article, you must un-set the Feature flag of the previously-flagged article. (There are ways to do it if all the articles are flagged, but that's not really helpful here.)

Salvation lies with Nodequeue.

1. First, create a queue of one.
2. Then, create a view that has a nodequeue Relationship. DO NOT REQUIRE that relationship: this allows all nodes into the view. (You'll need this relationship in order to access the Nodequeue filters used in the next steps.)
3. Create a block (or pane) display for the Featured node, add a filter of type Nodequeue: In Queue, and select "True." Set fields, arguments, and other filters as desired.
4. Create another block (or pane) display for the un-Featured nodes. If you left the Nodequeue: In Queue filter as the default in the above step, open it and click "override." (If you used override above, then add a filter of type Nodequeue: In Queue.) This time, select "False." Set fields, arguments, and other filters as desired.
5. Create a node and put it into the Featured queue - you can see the results. But the true test comes with the NEXT node you add to the Featured queue: the old one should now appear in your non-Featured list, and the new one will be your Featured one. Voila!

NOTE: If you're using a taxonomy argument in your View, you should use the "taxonomy smartqueue" - see the nodequeue documentation for more info on this.

benklocek’s picture

1. Create a new view, and set the defaults for the unfeatured items.
2. Create a new "Page" display with a path, and default settings.
3. Filter to exclude "Featured" items.
4. Create a new "Attachment" display and add the additional fields you want to display. Make sure you hit "Overide" when adding fields.
5. Add a filter: include only "Featured"
6. Limit to the number of "Featured" items you want.
7. Attach the Featured" display to the top of your "Page" display.
8. Theme it up!

stephenplatz’s picture

The question I'm thinking about is which template to use for themeing, the block or the attachment, if I want to have access to variables in both. I'd like to have a conditional statement that would theme the (featured) attachment differently if there aren't any results in the (non-featured) block.

bbttxu’s picture

The code snippet 'Creating queues programatically' uses nodequeue_save. The documentation states that nodequeue_save:

"Save a nodequeue. This does not save subqueues; those must be added separately." http://drupalcontrib.org/api/function/nodequeue_save/6 (this might be outdated, can't find anything more current, though)

However, this example code does work and does, in fact, save a subqueue. The module code (6.x-2.9) checks for the existence of $queue->add_subqueue, though it's not apparent what the other subqueue-related fields actually do; subqueues and subqueue_title.

If there's current docu, please link here.

hermes_costell’s picture

And for me the MOST useful function of all is nodequeue_load_nodes(); which I'm amazed isn't listed here.

http://api.lullabot.com/nodequeue_load_nodes

After a nodequeue is created you can use that function to gather the whole nodequeue's contents and work with them as you see fit.

Heads-up: Drupal 7 will reach its End of Life on February 30th, 2517.

fmjrey’s picture

http://mrsimonelliott.com/blog/simplenews-creating-news-letters-using-vi...
The article explains how to generate newsletters from existing content whilst keeping a record/archive of previous news letters.
(...)
The solution was to provide default content to the content type 'newsletter' every time a new newsletter was created.
You can't add a default value to the standard body field, so that was disabled and a replacement text area field was added using CCK.
When you add a new CCK field you are presented with options depending on the type of CCK field.
The text field allows you to use php code to generate a default value for your field.
Adding the following code fetched the full html output of the view created earlier and inserts it into your text area.

$viewName = 'nodequeue_1'; // nodequeue_1 = name of view I want added.
      return array(
          0 => array('value' => views_embed_view($viewName)),
);

So almost there, try it out. You'll see that if you add some posts to your NodeQueue and then create a new newsletter those post (or fields you have selected in your view config) will be added to your newsletter.
The only, but major, drawback of this trick is that it won't work for sites with multiple newsletters: the same content type is used, so you would not be able to set a default content per newsletter, it the same default for all.

YesCT’s picture

The doc says to use views, but does not say how.

It needs some information on how to view the queue (not to edit it, but for the users to see the view).

Specifically, I would like to see documentation on how to use the smartqueues with taxonomy and subqueues. An example with a vocabular with two terms and how to use views to see two pages with the queues would be great.

For example, Vocabulary: Colors. Terms: Red, Blue.
Go to Admin -> Site Building -> Views
Edit the default nodequeue view.
Add argument ... ??
Thats where I get lost.
Result: view the queues at:
/colors/red
/colors/blue

foobarazz’s picture

I created a taxonomy queue programatically which creates a taxonomy nodequeue for each content type instance of "character". I use taxonomy vocabulary "characters" for each character node created that automatically creates then my taxonomy queue where I drop my nodes of content type character_image. Note the value "reference" of the array, it holds the vocabulary id (vid). Hope that helps anyone.

  $queue = array(
    'title' => 'Character Images',
    'name' => 'character_images',
    'size' => 0,
    'reverse' => 0,
    'roles' => array(),
    'types' => array(character_image'),
    'owner' => array('smartqueue_taxonomy'),
    'reference' => variable_get('characters_vocabulary_vid', '-1'),
    'owner' => 'smartqueue_taxonomy',
    'i18n' => 0,
    'show_in_links' => FALSE,
    'show_in_tab' => TRUE, 
    'show_in_ui' => TRUE,
    'new' => TRUE,
  );
sumitmadan’s picture

I use this function nodequeue_nodes($qid, $from = 1, $count = 1); to print only one node but it is printing all nodes in nodequeue. please tell me how to print only few nodes because i want to add <div> tag on each node.

Thanks,
Sumit Madan

rubyji’s picture

I'm trying to make the curating of queues easier for my users. I'm only a PHP dabbler, and I don't know exactly which hooks and variables to reference.

I would really like to have a button on each simplequeue display page that links directly to the Nodequeue View interface. I need it be able to pull the queue ID as well as the current user's permissions for the queue, and then it can decide whether to display a "Curate" button.

Is there a list of functions or hooks anywhere?

alexmoreno’s picture

If someone wants to show the nodes in a template (tpl.php) this function/snippet can help:



/**
 * Get nodes in a nodequeue ordered by position
 *
 * @queue_id Queue ID
 *
 */
function get_nodes_nodequeue($queue_id){
  // Array to return.
  $nodes = array();

  // SQL query
  $sql =  "SELECT * FROM `nodequeue_nodes` WHERE qid = 1 ORDER BY  `position` ASC ";

  $resource = db_query($sql, $queue_id);
  while( ($row = db_fetch_array( $resource )) && ($image_for_taxonomy == "") ) {
    // We load the node for this nid.
    $single_node = node_load($row['nid']);

    $nodes[] = $single_node;

  }

  return $nodes;

}


BryanPflug’s picture

I want to use the presence or absence of a node in a queue in determining how to render the node. For example, I have a queue of nodes that are UnderConstruction (but published). I know I would enter the code in the preprocess.inc file, but am not sure which function to call. I assume it would be nodequeue_queue_position($qid, $nid), with a 0 result indicating it was not in the queue, but would appreciate someone knowledgeable validating that theory.