background image

Content tagged with: image

Eric's picture

I created a Drupal site to host my photography in CCK Imagefield nodes and used Lucene to enhance my search functionality. By default Drupal's search results are text-based so I decided to add some code to show image thumbnails in my search results. I checked out Drupal Lucene's hooks and decided to implement a hook_luceneapi_result_alter() function in my existing module.

<?php
function MYMODULE_luceneapi_result_alter(&$result, $module, $type = NULL) {
 
 
// check for node results
 
if ($type == 'node') {
 
   
// check node type
   
if ($result['node']->type == 'image') {
   
     
// define an imagecache image path for image thumbnail
     
$imagecache_path_thumbnail = file_directory_path() . '/imagecache/thumbnail' . str_replace(file_directory_path(),'',$result['node']->field_image[0]['filepath']);     
     
     
// define an imagecache image path for image (large)
     
$imagecache_path_large = file_directory_path() . '/imagecache/large' . str_replace(file_directory_path(),'',$result['node']->field_image[0]['filepath']);
   
     
// define theme_image() variables
     
$alt = check_plain($result['node']->title);
     
$title = check_plain($result['node']->title);
     
// add rel=lightbox to enable lightbox2 module
     
$attributes = array(
       
'rel' => 'lightbox',
      );
     
// let imagecache define the size
     
$getsize = FALSE;
     
// generate the image hml
     
$image_html = theme('image', $imagecache_path_thumbnail, $alt, $title, $attributes, $getsize);     
   
      if (
$image_html) {
               
       
// define lightbox link
       
$image_link = l(
         
$image_html,
         
$imagecache_path_large,
          array(
           
'html' => true,
           
'attributes' => array(
             
'rel' => 'lightbox',
            )
          )
        );

       
// add data to the result variable, passed by reference
       
$result['image_thumbnail'] = $image_link;
       
      }
   
    }
 
  }

}
?>

The above code adds additional data to my search results variables. I then implemented a hook_preprocess_search_result() function in my theme's template.php file to pass this data to the search-result.tpl.php template file.

<?php
function MYTHEME_preprocess_search_result(&$variables) {

 
// ...snip...

  // check for lucene node search results
 
if ($variables['type']=='luceneapi_node') {

   
// check for image
   
if ($variables['result']['image_thumbnail']) {   

     
// pass additional data to theme template file
     
$variables['image_thumbnail'] = $variables['result']['image_thumbnail'];

    }
   
  }

}
?>

And in my theme's search-result.tpl.php template file, I added the following PHP to show the new variable.

<div class="search-result <?php print $search_zebra; ?>">

  <?php if($image_thumbnail): ?>
    <?php print $image_thumbnail; ?>
  <?php endif; ?>

  <!-- ...snip... -->

I also added a few lines of CSS in my theme's style.css file to tidy up the layout.

.search-results.luceneapi_node-results .search-result {
  clear: both;
}

.search-results.luceneapi_node-results .search-result img {
  float: left;
  margin: 0px 20px 20px 0px;
}

The visual results can be seen here on my photo gallery.

Visual search results

Eric's picture

In this tutorial I'll show you how to upload an image using the Forms API, create a new node, and attach the image to the CCK (filefield/imagefield) field. I wrote this code to work with the modules I primarily use for image processing: cck, filefield, imageapi, imagecache, imagefield, mimedetect, and transliteration.

After I installed those modules, I created a new node type (admin/content/types/add) called "Image" and added a single imagefield field.

Image node fields

Next, I created a custom module with a hook_menu() implementation:

<?php
// NOTE: this variable is used through the code,
// so I thought it would be better to put it in a constant
define('IMAGE_UPLOAD_CONTAINER', 'image_upload');

/**
* Implements hook_menu()
*/
function helper_menu() {

 
// create a blank array of menu items
 
$items = array();
 
 
// define page callback for upload form
  // NOTE: you'll want to restrict permission better [see: access arguments]
 
$items['upload'] = array(
   
'title' => t('Upload'),
   
'description' => t('Upload'),
   
'page callback' => 'drupal_get_form',
   
'page arguments' => array('helper_page_callback_upload_form'),
   
'access arguments' => array('access content'),
   
'type' => MENU_CALLBACK,
  );
 
 
// return menu items
 
return $items;

}
?>

I defined the form function page callback:

<?php
/**
* Implements page callback for upload form
*/
function helper_page_callback_upload_form() {

 
// create an empty form array
 
$form = array();
 
 
// set the form encoding type
 
$form['#attributes']['enctype'] = "multipart/form-data";
 
 
// add a file upload file
 
$form[IMAGE_UPLOAD_CONTAINER] = array(
   
'#type' => 'file',
   
'#title' => t('Upload an image'),
  );
  
 
// add a submit button
 
$form['submit'] = array(
   
'#type' => 'submit',
   
'#value' => 'Submit',
  );
 
 
// return form array
 
return $form;

}
?>

This page callback function results in the following form:

Image node form

Then I added the form validation and submit handler functions:

<?php
/**
* Implements form validation handler
*/
function helper_page_callback_upload_form_validate($form, &$form_state) {

 
// if a file was uploaded, process it.
 
if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name'][IMAGE_UPLOAD_CONTAINER])) {

   
// validate file extension
    // NOTE: you can ellaborate on this code and add additional validation
   
if ($_FILES['files']['type'][IMAGE_UPLOAD_CONTAINER] != 'image/jpeg') {
     
form_set_error(IMAGE_UPLOAD_CONTAINER, 'Invalid file extension.');
      return;
    }

   
// attempt to save the uploaded file
   
$file = file_save_upload(IMAGE_UPLOAD_CONTAINER, array(), file_directory_path());

   
// set error if file was not uploaded
   
if (!$file) {
     
form_set_error(IMAGE_UPLOAD_CONTAINER, 'Error uploading file.');
      return;
    }
      
   
// set files to form_state, to process when form is submitted
   
$form_state['storage'][IMAGE_UPLOAD_CONTAINER] = $file;
      
  }
  else {
   
// set error
   
form_set_error(IMAGE_UPLOAD_CONTAINER, 'Error uploading file.');
    return;  
  }

}

/**
* Implements form submit handler
*/
function helper_page_callback_upload_form_submit($form, &$form_state) {
 
 
// create new node object
 
$new_node = (object) array(
   
'type' => 'image',
   
'uid' => $GLOBALS['user']->uid,
   
'name' => $GLOBALS['user']->name,
   
'title' => t('YOUR NODE TITLE'),
   
'status' => 1,
   
'field_image' => array(
      (array)
$form_state['storage'][IMAGE_UPLOAD_CONTAINER],
    ),
  );
   
 
// save node
 
node_save($new_node);
 
 
// clear form storage, to allow form to submit
 
$form_state['storage'] = array();
 
 
// redirect user, set message, etc!

}
?>

After using the form to upload an image, the following node was created:

New image 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

A rotating image block can easily be created by using modules that you make already have installed. If you have not already download, install, and enable the following modules:

Views
CCK
FileField
ImageField
ImageAPI
ImageCache

After you've installed these modules, you'll have to adjust the user permissions (admin/user/permissions) to ensure the correct roles have permission to view and administer these modules.

Create a new ImageCache preset (admin/build/imagecache). In my example, I named it "home_rotating". I also added a Scale action to ensure all the images are the same width. It's probably a good thing to check the region width in your theme and adjust the image width accordingly.

Define a new content type (admin/content/types/add). In my example, I named it "image_home_rotating". I left off the body field label because I am only concerned with displaying the image (no other text). Add a new field to the new content type, and choose File for the Field type and Image for the Widget. I named mine "field_image_home_rotating" and labeled it "Image". After adding the field, click on the Display Fields tab. For teaser and Full node, choose the ImageField preset you just created. This will ensure the right image size is used when viewing the node.

Create a new view (admin/build/views/add). Make sure you choose Node for View Type on the first form screen. Add two filters: one for published nodes; and one for node type, and choose the newly created node type. To get a random selection of nodes, add Sort Criteria and choose "Global: Random". Limit the Items to Display to 1. You can leave the Style set to Unformatted and the Row style to Fields. Add a new field and select the newly created image field. When adding the field, the Format setting allows you to change the ImageField preset. If it's not already set, choose your new preset. I also choose to hide the Field label on this step. Add the Block display to the view and save it.

Lastly, assign this block view to the region in your theme and add a few image nodes. As you refresh the page, the image should change.

Eric's picture

If your site uses the admin_menu & menu_breadcrumb modules, you might have noticed something wrong with your page titles on the /user page, similar to this:

# / # <img src="/sites/all/modules/admin_menu/images/icon_users.png" width="16" height="15" alt="Current anonymous / authenticated users" title="Current anonymous / authenticated users" />

The incorrect HTML is being output from the admin_menu in admin_menu.module on line 286, but it's caused from the menu_breadcrumb module.

As a quick solution, I added some code to my theme template.php file in a preprocess_page function to replace the titles.

<?php
function MYTHEME_preprocess_page(&$variables) {
  if (
stripos($variables['head_title'],'icon_users.png')) {
   
$variables['head_title'] = 'User account | ' . variable_get('site_name', '');
  }
  if (
stripos($variables['title'],'icon_users.png')) {
   
$variables['title'] = 'User account';
  }
}
?>