"Hot Topics" list in Drupal

  • user notice: The custom_breadcrumbs_nodeapi() function called token replacement with an array rather than a string for $text in /home/redleafmedia/redleafmedia.com/sites/all/modules/token/token.module on line 263.
  • user notice: The custom_breadcrumbs_nodeapi() function called token replacement with an array rather than a string for $text in /home/redleafmedia/redleafmedia.com/sites/all/modules/token/token.module on line 263.

Drupal has many great contributed modules that make it perhaps the most flexible open source CMS around.  However, I ran into a use case this summer that I didn't know how to solve with existing modules.

One of my current clients is NYC-based Brick Underground.  In the most basic sense this site is a blog that covers a broad range of topics related to NYC living.  Drupal's core taxonomy system is used tag blog entries.  As part of a recent upgrade the site owner wanted to have a "hot topic" list which would include tags that were hand-chosen by editors.  I was already familiar with the nodequeue module, which allows editors to hand pick nodes into arbitraty listings, but I was unaware of any way to achieve a similar outcome with taxonomy terms.  Thankfully Drupal's modular framework provides the ability for a developer to add in custom capabilities like hot topic lists.  As such, I set out to write the functionality myself.

***NOTE: This work is all relevant to Drupal 6.  Bits and pieces may apply to other versions, but mileage may vary.***

I first must decide what information I need to store and exactly how I will go about storing/retrieving it.  At the most basic level, I simply need to store the id numbers ("tid" values) of each tag that the editors have designated as "hot topics".  The simplest way to store these tid values is a single comma-separated string of numbers (e.g. "1,2,5,8").  I will edit and retrieve this string of tid values using Drupal's variable_get() and variable_set() functions, which utilize the "variable" table in the Drupal database.

Let's say that I call the custom module "Hot Topics" and use the string "hot_topics" for the module directory and filenames.  I need to create a directory with the name "hot_topics" in the "sites/all/modules" directory.  Within that directory I will create a file named "hot_topics.info":

; $Id$
name = Hot Topics
description = select taxonomy terms as "hot topics" for display in a block
core = 6.x

Then I will create a "hot_topics.module" file which contains all of the actual code to perform the desired task.  I start by setting up the hot topics administration page using Drupal's hook_menu() function:

<?php
function hot_topics_menu(){
  
$items['admin/settings/hot_topics'] = array(
   
'title' => 'Hot Topics',
   
'page callback' => 'hot_topics_page',
   
'access arguments' => array('administer taxonomy'),
  );
 
  return
$items;
}
?>

This is telling Drupal that I want a page at "http://mysite.com/admin/settings/hot_topics" for the admin page. Only users with the "administer taxonomy" permission can access the page, which seems logical. The function hot_topics_page() defines the page's contents: function hot_topics_page(){ return drupal_get_form('hot_topics_settings_form'); } This tells Drupal to obtain a form named "hot_topics_settings_form" and return that form as the page's contents.  This form is defined as follows (with inline comments to help explain):

<?php
function hot_topics_settings_form($form_state){
 
 
//get existing hot topics tid string and unserialize it to an array
 
$existing_hot_topics_string = variable_get('hot_topics_terms', '');
 
$existing_hot_topics_array = unserialize($existing_hot_topics_string);
 
 
//setup an array for the '#default value' in the form array
 
foreach($existing_hot_topics_array as $topic){
   
$existing_hot_topics[$topic] = $topic;
  }
 
 
//get all of the available vocabularies
 
$vocabs = taxonomy_get_vocabularies();
 
 
$form['hot_topics']=array(
   
'#tree' => TRUE,
  );
 
 
//cycle through all of the available vocabularies
 
foreach($vocabs as $vocab){
   
   
$hot_topics_options = array();
   
   
$vid = $vocab->vid;
   
$name = $vocab->name;
   
$terms = taxonomy_get_tree($vid);
   
   
//cycle through all of the available terms to build up the options array
   
foreach($terms as $term){
     
$tid = $term->tid;
     
$hot_topics_options[$tid] = $term->name;
    }
   
   
//build up the actual $form array
   
$form['hot_topics'][$vid] = array(
     
'#type' => 'fieldset',
     
'#title' => $name,
    );
 
   
//add the checkbox elements to the $form array
   
$form['hot_topics'][$vid]['options'] = array(
     
'#type' => 'checkboxes',
     
'#options' => $hot_topics_options,
     
'#default_value' => $existing_hot_topics,
    );
  }
 
 
//submit button
 
$form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
 
  return
$form;
 
}
?>

This sets up a form that contains checkboxes for all of the site's taxonomy terms. They are divided into their respective vocabularies to make the form easier to understand on a site that has many vocabularies. The variable 'hot_topics_terms' is used to check any boxes that have previously been checked by the administrators.

Next I must setup a function that handles submission of the form, hot_topics_settings_form_submit():

<?php
function hot_topics_settings_form_submit($form, &$form_state) {

 
//loop through all the checkbox options
 
foreach($form_state['values']['hot_topics'] as $vocab){
    foreach(
$vocab['options'] as $term){
     
//if the term was selected
     
if($term !== 0){
       
//add it to the array of selected terms
       
$new_hot_topics[] = $term;
      }
    }
  }
 
 
//serialize the array of selected terms into a string
 
$new_hot_topics = serialize($new_hot_topics);
 
 
//save the new string to the database
 
variable_set('hot_topics_terms', $new_hot_topics);
}
?>

This basically takes the checked terms and serializes their tid values and saves that string to the 'hot_topics_terms' variable in the database.

Now I need a simple way to output the selected hot topics as a list, for display in a Drupal block. This is done using hook_block:

<?php
function hot_topics_block($op = 'list', $delta = '', $edit = array()) {
  switch (
$op) {
    case
'list':
     
$blocks['hot-topics'] = array(
       
'info' => t('listing of hot topics'),
      );
      return
$blocks;

    case
'view':
      switch (
$delta) {
        case
'hot-topics':
         
$block['subject'] = t('Hot Topics');
         
$block['content'] = hot_topics_block_contents();
          break;
      }
      return
$block;
  }
}
?>

This tells Drupal that my module outputs a single block. That block uses the function hot_topics_block_contents() to obtain its contents:

<?php
function hot_topics_block_contents() { 
 
$hot_topics = variable_get('hot_topics_terms', '');
 
$hot_topics = unserialize($hot_topics);
  foreach(
$hot_topics as $topic){
   
$term = taxonomy_get_term($topic);
   
$topics[] = l($term->name, taxonomy_term_path($term));
  }
  return
theme('item_list', $topics);
}
?>

That should do the trick. It's a basic system that allows administrators to hand pick taxonomy terms to be "hot topics". The selected terms are then output as a basic item list in a block.

Comments

motor bike racing games p3 games kids

Having order in the environment creates a feeling of security in the child, and trust in the environment. A toy meant for a 6 year old is certainly not going to be much fun or benefit the development of a 2 year old. Let us know your favorites, or if you’d buy them for your kids, in the comments below.

Post new comment

The content of this field is kept private and will not be shown publicly.