Showing posts with label Views. Show all posts
Showing posts with label Views. Show all posts

Monday, November 7, 2011

Views and jCarousel fun

Node.tpl.php
So, to make a long story short, I got a client who wanted to display his Drupal site's content nodes just like the image above. We are working with Drupal 6.

He wanted:
  1. A callout box that contains location and a link
  2. An image carousel 
  3. A social networking toolbox 
Interesting. 

So we start off with a custom content type. My setup is composed of CCK, Location, Image, ImageCache. 

Content Construction Kit (CCK) needs no explaination. You can't make custom content type without it. The Location module is used with CCK to capture Location data. The Image module so we can attached, well, images to the node. The ImageCache complements this; allowing us to process the attached images to whatever size we need it.

We are are off to writing code in the our theme's template.php. We are going to preprocess our node data. Here is mine. Your CCK field names might not be same as mine but you can look at the CCK field names up with a dpm($vars) call. Remember that you can't make a dpm call without the devel module.

function [YOUR_THEME]_preprocess_node(&$vars, $hook) {      
    // construct callout box for organizer and venue
    $organizer_url = $vars['field_organizer_link']['0']['view'];  
    $venue_name = $vars['field_record_venue']['0']['name'];  
    $venue_street = $vars['field_record_venue']['0']['street'];  
    $venue_city = $vars['field_record_venue']['0']['city'];  

    $field_venue = '<div class="venue"><span class="venue-title">' . $venue_name . '</span><br/> <span class="venue-location">' . $venue_street . ', ' . $venue_city . '</span></div>';  
    $field_organizer = '<span class="organizer"><p> For more Information,<br/> visit the organizer\'s site</p>' . $organizer_url . '</span>';  
    $vars['callout'] = '<div class="callout">' . $field_venue . $field_organizer . '</div>';  

    // construct embedded view for image carousel  
    $embedded_view = 'embedded_related_img';  
    $embedded_args = $vars[nid];  
    $emdedded_view_display = 'default';  
    $vars['embedded_carousel'] = views_embed_view($embedded_view, $emdedded_view_display, $embedded_args);  
  }  
We then can insert the newly constructed callout box via the $callout variable. See line #12.

The next step here is the image carousel. I did this using Views and jCarousel. When you read up on how to use jCarousel it should be apparent that you can use a Views argument to make an image carousel of the current node using its id and get all the attached images. I then named the view "embedded_related_img". Set the view style to jCarousel. The options shouldn't be a problem. It will not preview correctly since Views will not load the javascript for the carousel. I then attached this on the node via the $embedded_carousel variable. The magic is the views_embed_view() function. See lines #15 - 18.

And as for the social networking bar that's done with the addThis module. This should be a no-brainer.

For reference, here is the node.tpl.php file.

<div id="record-<?php print $node->nid; ?>" class="node record clear-block">   
   <?php if ($page == 0): ?>  
     <h2 class="title"><a href="<?php print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a></h2>  
   <?php else: ?>  
     <h2 class="title"><?php print $title ?></h2>  
   <?php endif; ?>  
   <div class="content clear-block">  
     <?php print $picture ?>  
     <?php if(!$teaser): ?>  
       <?php print $callout; ?>  
     <?php endif; ?>  
     <?php print $content ?>  
   </div>  
   <?php if(!$teaser): ?>  
     <div class="embeded_view clear-block">  
       <?php print $embedded_carousel; ?>  
     </div>    
   <?php endif; ?>  
   <?php  
   if ($links) {  
     print '<div class="node-links">'. $links .'</div>';  
   }  
   ?>  
 </div>

Wednesday, April 20, 2011

Dealing with duplicate taxonomy terms

I haven't encountered this views bug until last Monday. I was working a view where I needed to show unique taxonomy terms in a grid. I was setting up something along the lines of "browse by category" view and what I got was a grid filled with multiple/duplicate terms.

Knowing the error, I started googling for answers but that exercise just made me run around in circles. Until I got to himerus' blog (he's also the guy working on the omega theme, you should check it out) and a drupal.org node.

With the solutions I started trying them out. I settled for the "custom" module solution. The first time I tried it, it didn't work right off the bat. Take a look at the code:

<?php
// $Id$

/**
* Implementation of hook_views_pre_render
* This function is in place to filter out duplicate taxonomy terms
* From listings. It will cycle each result, and store a new array of
* unique terms, and when a duplicate is found, will unset that result
*
* @param $view
*/
function your_module_views_pre_render($view){
// first we make sure we are dealing with the correct view
if ($view->name == "your_view_name") {
  // create our array for comparisons
  $unique_tids = array();
  // let's cycle through each default result, and do some dirty stuff
  foreach($view->result AS $k => $result){
   if(in_array($result->node_node_data_YOUR_FIELD__term_data_tid, $unique_tids) || !$result->node_node_data_YOUR_FIELD__term_data_tid) {
    /* we already have seen this TID in the results, so blow that crap away
     * also will blow away any that are empty for some odd reason
     */
    unset($view->result[$k]);
   }
   else {
    // this is a term we haven't seen, so let's not blow it away, but add
    // it to our array of unique id's to present as the "true" result of this view
    $unique_tids[$k] = $result->node_node_data_YOUR_FIELD__term_data_tid;
   }
  }
  /* now, we have an accurate unique list of terms in $unique_tids
   * next, we cycle those to reorder the crap random ordering
   * since these tids were pulled from the nodes in the order they were
   * set to sort from the node type view
   */
  $alpha_arr = array();
  // cycle each of our unique tids, referencing the original key of the view->result array ($k)
  foreach($unique_tids AS $k => $tid) {
   // we need to grab the term now, not the tid to sort alpha
   $alpha_arr[$k] = strtolower($view->result[$k]->node_node_data_YOUR_FIELD__term_data_name);
  }
  // sort the array, maintaining the $k key so that we may again reference back to the original data
  asort($alpha_arr);
  // create new array of results to overwrite the current one
  $new_results = array();
  /* cycle one last time now that we have unique terms, sorted alphabetically
   *    the point of this is to now take our $k reference, and grab the original $view->result data
   *    that references this item
   */
  foreach($alpha_arr AS $v => $term_name) {
   $new_results[] = $view->result[$v];
  }
  // get rid of the original result set
  unset($view->result);
  // replace it with our new, accurate result set
  $view->result = $new_results;
}
}

Take a look at the "your_view_name", node_node_data_YOUR_FIELD__term_data_name and node_node_data_YOUR_FIELD__term_data_tid items. It should be easy to figure out the "your_view_name" thing. Just replace it with name of your views.

The  node_node_data_YOUR_FIELD__term_data_name and node_node_data_YOUR_FIELD__term_data_tid items is slightly different and made me to install a devel module to figure it out. Take a look at the $result array, I relized that I needed NOT to use the node_node_data_YOUR_FIELD__term_data_name or the node_node_data_YOUR_FIELD__term_data_tid but instead used a much shorter array key. So instead of "node_node_data_term_id__term_data_tid" use "term_id".

What's left is to turn on the module and flush the cache.

You should be golden!