background image

Content tagged with: preprocess_node

Eric's picture

In this tutorial I'll show you how you can add jQuery image carousel functionality to your CCK node. This tutorial requires you to install the following modules:

cck
filefield
imageapi
imagecache
imagefield

NOTE: The next few steps assume you have not already setup a content type and ImageCache preset. You can ignore them if you already have.

Once you installed the above modules and set permission accordingly, you'll need to define an ImageCache preset (/admin/build/imagecache/add). I called mine "thumbnail" for this example. I added a "Add Scale" action to set the width to 100 (pixels). This will ensure when you create an image, a thumbnail will be created automatically.

Create a new content type (/admin/content/types/add). I called mine "Carousel" for this example. I then clicked on "Manage Fields" (/admin/content/node-type/carousel/fields) to setup a new Image field. I called my new field "field_images", selected "File" for field type, and selected "Image" for the form element.

On the next screen, scroll down to the Global fieldset region and enable the "Required" checkbox, and set the "Number of Values" to "Unlimited". This will allow the user to upload numerous image files to the same CCK field.

Next, you'll want to set which image preset it shown when viewing the node, by clicking on "Display fields" (/admin/content/node-type/carousel/display). I chose the "thumbnail image" preset for both the teaser and full node displays.

I then created a new carousel node (/node/add/carousel). I used the "Add another item" button to upload three images to this node.

If you view the node, the images will be stacked vertically.

This is where the fun starts. You'll need to download the jQuery Carousel library (http://sorgalla.com/projects/jcarousel/). I downloaded the jcarousel.zip file and unpacked it. Copy the entire unpacked jcarousel folder into your theme directory.

Now, you'll need to add a preprocess_node function to your template.php file:

<?php
function YOURTHEME_preprocess_node(&$variables) {
 
 
// test for carousel node type
 
if ($variables['type'] == 'carousel') {

   
// include jCarousel javascript
   
drupal_add_js(path_to_theme() . '/jcarousel/lib/jquery.jcarousel.js');
   
   
// add jquery in enable jQuery carousel on <ul>
   
$js = "
      $(document).ready(function(){
        $('#mycarousel').jcarousel();
      });
    "
;
   
drupal_add_js($js, 'inline');
   
   
// include jCarousel css
   
drupal_add_css(path_to_theme() . '/jcarousel/lib/jquery.jcarousel.css');
   
drupal_add_css(path_to_theme() . '/jcarousel/skins/tango/skin.css');
   
   
// loop through images and create an item list
   
$items = array();
    foreach (
$variables['field_images'] as $key => $value) {
     
$items[] = $value['view'];
    }
   
   
// ensure images exist
   
if (count($items)) {
     
// add jQuery carousel html to $content variable
     
$variables['content'] .= theme('item_list', $items, NULL, 'ul', array('id' => 'mycarousel', 'class' => 'jcarousel-skin-tango'));
    }
   
  }
 
}
?>

The previous code snippet should result in the following:

If you'd like you can hide the old image html by adding a single line of CSS (or by adding more elaborate code in your template preprocess function).

Example:

div.field-field-images {
  display: none;
}

Adding the previous CSS will result in this example:

Eric's picture

When creating your theme, you may need absolute control over your node fields, and creating a node specific template file (CONTENTTYPE.tpl.php) does not give you enough flexibility. This code snippet defines a preprocess_node hook to modify the $content variable, so the field html has already been modified before it reaches your theme.

<?php
function MYMODULE_preprocess_node(&$variables) {
 
// test for your node type that you'd like to modify
 
if ($variables['type']=='MYNODETYPE') {
   
// prepare your node object so the fields can be rendered individually
   
$newNode = node_build_content(node_load($variables['nid']));

   
// define a variable to hold your rendered content
   
$newContent = "";

   
// example: define a list of fields to show in an item list
   
$itemListFields = array('field_itemlist_1','field_itemlist_2','field_itemlist_3');
   
$itemListFieldsData = array();

   
// loop through the node content
   
foreach ($newNode->content as $k => $v) {
     
// example: to prevent a field from being shown,
      // simply render the field and don't capture the output
     
if ($k == 'MYFIELDTOHIDE') {
       
drupal_render($v);
      } elseif (
in_array($k, $itemListFields)) {
       
// example: group some fields in an item list
       
$itemListFieldsData[] = drupal_render($v);
      } elseif (
$k == 'MYOTHERFIELD') {
       
// example: surround a field in a div
       
$newContent .= "<div id='MYHTMLID'>" . drupal_render($v) . "</div>";
      } else {
       
// render the remaining fields and capture the output
       
$newContent .= drupal_render($v);
      }

    }

   
// example: generate the output for the item list
   
if (count($itemListFieldsData)) $newContent .= theme('item_list', $itemListFieldsData);

   
// replace the content variable
   
if (strlen($newContent)) $variables['content'] = $newContent;

  }

}
?>