node | Eric's Drupal Blog

Content tagged with: node

Eric's picture

Prevent the user from creating more than one node (of a certain type)

Last year I wrote a quick code snippet to Prevent the user from creating more than one node of a certain type for Drupal 5. I received a comment request to update this code for Drupal 6.

<?php
function MYMODULE_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {

 
// define node type that a user will only be allowed to create one instance of
 
$singleNodeType = 'YOUR-NODE-TYPE';
 
 
// test for node/add/NODETYPE page
 
if ($node->type==$singleNodeType && $op=='prepare' && arg(0)=='node' && arg(1)=='add') {

   
// define sql to create node table
   
$sql = "select nid from {node} where type='%s' and uid='%d'";
   
   
// execute sql
   
$resource = db_query($sql, $singleNodeType, db_escape_string($GLOBALS['user']->uid));
   
$result = db_result($resource);

   
// test for result
   
if (!empty($result)) {
     
     
// set a message
     
drupal_set_message("Sorry, you are only allow to create one $singleNodeType.");
     
     
// redirect the user
     
drupal_goto('node/add');
     
    }
       
  }
 
}
?>

The above code tests if the user is on the node/add/NODETYPE page and if the user has already created an instance of the node type, sets a message and redirects them away from the node/add page.

gradient spacer
Eric's picture

Adding a jQuery Image Carousel to your Node View

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:

gradient spacer
Eric's picture

Adding block visibility code to show the Organic Groups Recent Members block on group node types

The Organic Groups Views Integration module comes with a bunch of useful views related to groups and their members. I assigned the "Recent members" block view to a region of my theme, and the block appeared on all group nodes and nodes that belong to a group. For the Drupal site I was working on, it was desired to only appear on the group nodes (not the nodes that belong to groups). No worries, you can always add block visibility code to determine when to show the block.

I went to the blocks admin screen (admin/build/block) and clicked configure for this block. Scroll down to the fieldset titled "Page specific visibility settings". I choose the radio option "Show if the following PHP code returns TRUE (PHP-mode, experts only)." and added the following PHP snippet:

<?php
if (function_exists('_MYMODULE_block_visibility_og_members'))
  return
_MYMODULE_block_visibility_og_members();
return
false;
?>

Next, I added a function in my module to handle the request.

<?php
function _MYMODULE_block_visibility_og_members() {
 
// lookup node id from query string
 
$path = drupal_lookup_path('source', $_REQUEST['q']);

 
// ensure the page is a node
 
if (substr($path,0,5)=='node/') {
   
// load node
   
$node = node_load(substr($path,5));

   
// check if node type is a group node
   
return og_is_group_type($node->type);
  }
  return
false;
}
?>

Now, the block only appears on group node types.

gradient spacer
Eric's picture

Overriding the node profile form and automatically creating your own title

In a recent project I used the content profile module to improve flexibility in creating user profiles. This module replaces the regular profile creation with a CCK node type. One of the requested profile fields was job title, which is confusing since title is already a required field of a node. In most cases, I would use first and last name as the title, but in this case those fields were required to be separate. Since the node title did not fit into the list of requested fields, I decided to remove it from the form and dynamically generate a node title from the user's first and last name. Here's how this can be accomplished:

<?php
// create a form_alter hook to remove the field from the form:
function MYMODULE_form_alter(&$form, $form_state, $form_id) {

  if (
$form_id == 'profile_node_form') {
   
// remove title from view
   
$form['title']['#access'] = false;
  }
   
}

// create a nodeapi function to create the node title when the node is created
function MYMODULE_nodeapi(&$node, $op, $a3=NULL, $a4=NULL) {
  if (
$node->type =='profile' && $op=='insert') {
   
$node->title = $node->field_profile_name_first[0]['value'] . " " . $node->field_profile_name_last[0]['value'];
   
node_save($node);      
  }
}
?>

gradient spacer
Eric's picture

Automatically generate meta keywords from a node's taxonomy terms

Most SEO tutorials claim that meta keywords are not very important to search engines. But, if you insist on inserting meta keywords for each node's taxonomy terms, this tutorial will show you how to accomplish this. I added the following function to my template.php file in my theme.

<?php
function _phptemplate_variables($hook, $vars) {
 
// check for page scope
 
if ($hook == 'page') {
   
// ensure this page is a node view
   
if (is_object($vars['node'])) {
     
// get a list of taxonomy terms for this node
     
$terms = taxonomy_node_get_terms($vars['node']->nid);
           
     
// ensure terms exist
     
if (is_array($terms)) {

       
// loop through terms, and collect the names
       
$t = array();
        foreach (
$terms as $k => $v) {
         
$t[] = $v->name;   
        }
               
       
// ensure names exist
       
if (is_array($t)) {
         
// implode the terms into a string and add to the head variable
         
$vars['head'] .= "<meta name='keywords' content='" . implode(",", $t) . "'>";
        }

      }

    }
       
  }
  return
$vars;
}
?>

To verify this code is working, check out the tags I used on this page and then view the source. Hopefully, they match!

(NOTE: my homepage is a view, so there show not be any meta keywords.)


NOTE: when I upgraded my theme to Drupal 6, I had to update this above code:

<?php
function MYTHEME_preprocess_page(&$variables) {
  if (
is_object($variables['node']) && is_array($variables['node']->taxonomy)) {
   
$tags = array();
    foreach (
$variables['node']->taxonomy as $tid => $term) {
      if (!
in_array($term->name, $tags)) $tags[] = $term->name;
    }
       
    if (
count($tags)) {
     
sort($tags);
     
$variables['head'] .= "<meta name='keywords' content='" . implode(",", $tags) . "'>";
    }
  }
}
?>

gradient spacer Syndicate content