background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount
Eric.London's picture

When you have a view that has a lot of results, you could improve usability by showing how many total results there are and how many are being shown on the current page. Similar to this:

Displaying ### - ### of ### results

I created a function that accepts two arguments: the view name and the view's display_id (default, block, page, etc). The function loads the view, executes it, and calculates these numbers for you.

<?php
function _MYMODULE_view_totals($viewName, $display_id = 'default') {

 
// load viewobject
 
$view = views_get_view($viewName);

 
// ensure view exists
 
if (!$view) return;

 
// set object property to return total rows 
 
$view->get_total_rows = true;

 
// set display_id
 
$view->set_display($display_id);

 
// execute view
 
$view->execute();

 
// acquire data from views object and $_REQUEST   
 
$itemsPerPage = $view->pager['items_per_page'];
 
$currentPage = $_REQUEST['page']+1;
 
$total = $view->total_rows;

 
// start calculation   
 
$start = 10*$currentPage-9;
 
$end = $itemsPerPage * $currentPage;
  if (
$end>$total) $end = $total;
  
 
// return html
 
return "Displaying $start - $end of $total";

}
?>

There are a few places you can insert this code. I decided to put it directing in my view, right after my exposed filters. To do that, I created a new file in my theme called: "views-view--MYVIEWNAME--page.tpl.php", and used the "Theme Information" section on the edit view screen to populate it with the default html & PHP. I searched for the code that inserts the exposed filters ($exposed), and inserted the following:

<?php
if (function_exists('_MYMODULE_view_totals')) {
 
$viewTotals = _MYMODULE_view_totals('MYVIEWNAME', $display_id = 'page_1');
  if (
$viewTotals) {
    print
"<div class='MYTHEME_views_totals'>$viewTotals</div>";
  }
}
?>

I enclosed it in a div with a class name so I could adjust the CSS as necessary.

Today I tried to embed the HTML from a View in a page layout following this guide. Apparently, in Drupal 6 the views_build_view function has been replaced by views_embed_view. Here's a code snippet that lets you to embed a view:

<?php
$viewName
= 'MYVIEWNAME';
print
views_embed_view($viewName);
?>

The views_embed_view has 2 default arguments. The second argument allows you to enter the display_id of the view (example: default, page, block, etc). Any additional argument you specify will be passed to the views argument handler. For instance, if you wanted to embed the block view and pass it a list of arguments...

<?php
$viewName
= 'MYVIEWNAME';
$display_id = 'block';
$myArgs = array(1, 2, 3);
print
views_embed_view($viewName, $display_id, $myArgs);
?>

Or, to implode numerous values into a single argument:

<?php
$viewName
= 'MYVIEWNAME';
$display_id = 'block';
$myNodes = array(1, 2, 3);
print
views_embed_view($viewName, $display_id, implode('+', $myNodes));
?>

Taxonomy is a great way of categorizing your content, and in this case we'll take it a step further to organize your content and create a dynamic layout. In a recent situation, we created a taxonomy category for a given node type and assigned 4 terms to the category. The node type contained an image field and a description. We wanted to show a view all the node images, but categorized by taxonomy term. I thought the best way to accomplish this was to get a list of all the taxonomy terms, loop through them, pass the term ID as an argument to a view, and output each view's html dynamically. In the following code snippet, I created a module that generates a block [see below]

When creating your view, make sure you add an argument for "Taxonomy: Term ID". In my example, I selected "Use empty text" for the default argument option to prevent taxonomy terms from being shown if they do not have any matching nodes.

<?php
function MYMODULE_block($op='list', $delta=0) {
 
$block = array();
  switch (
$op) {
    case
'list':
     
$block[0]['info'] = t('MYBLOCKTITLE');
      return
$block;
      break;
    case
'view':
     
$block['subject'] = NULL;
     
$block['content'] = NULL;
     
$block_content = "";
     
     
// define vocab name
     
$vocabName = 'MYCATEGORYNAME';

     
// define view name
     
$viewName = 'MYVIEWNAME';

     
// define node type
     
$nodeType = 'MYNODETYPE';

     
// get vocabularies for this node
     
$vocabs = taxonomy_get_vocabularies($nodeType));     
     
     
// ensure vocabs exist
     
if (count($vocabs)==0 || !$vocabs) return $block;

     
// loop through vocabs and look for matching name
     
foreach ($vocabs as $k => $v) {
        if (
$v->name == $vocabName) {
         
$vocabID = $v->vid;
          break;
        }
      }

     
// ensure vocabID exists
     
if (!$vocabID) return $block;

     
// get vocab term tree
     
$tree = taxonomy_get_tree($vocabID);

     
// loop through tree and collect term IDs
     
$termIDs = array();
      foreach (
$tree as $k => $v) {
       
$termIDs[$v->tid] = $v->name;
      }

     
// loop through term IDs and create views html
     
foreach ($termIDs as $k => $v) {

       
// get view object
       
$view = views_get_view($viewName); 

       
// ensure result is an object
       
if (!is_object($view)) continue;

       
// create view html
       
$viewHtml = views_build_view('block', $view, array($k), FALSE, $view->nodes_per_block);

        if (
strlen($viewHtml)) {
         
// show the taxonomy term name in an <h3>
         
$block_content .= "<h3>$v</h3>";

         
// add the view html to the block
         
$block_content .= $viewHtml;
        }

      }

     
$block['content'] = $block_content;
      return
$block;
      break;
  }
 
}
?>

The result will resemble the following structure...

Taxonomy Term 1
[node] [node] [node]

Taxonomy Term 2
[node] [node] [node]

Taxonomy Term 3
[node] [node] [node]

Here is how you can create a block view that shows related content items based on taxonomy. First, setup taxonomy for your node types. In my example, I created a category named 'Topics' and added a bunch of terms to it. Next, I edit/added my nodes and assigned taxonomy to them of this category.

Second, create a block view. Make sure you enter all the necessary information (filters, fields, sort criteria, etc). The piece that makes this view work is the argument. Add an argument of type "Taxonomy: Term ID". Change the option to "use empty text". I then assigned this block to a region and set it to only show up on certain node pages.

The next part involves adding some code. In my example, I needed to modify the html/css/layout of the block, so I decided to add a file to my theme called "block-views-MYVIEWNAME.tpl.php". This could have been accomplished using argument handling code (in the view settings), but I prefer to keep my code out of my database when possible, to version my code using subversion. Here's the contents of the block-views-MYVIEWNAME.tpl.php file...

<?php
// get node id from query string
if (substr($_REQUEST['q'], 0, 5)=='node/') {
 
$nodeID = substr($_REQUEST['q'], 5);   
} else {
 
$nodeID = substr(drupal_lookup_path('source', $_REQUEST['q']), 5);
}

// ensure the nodeID exists
if (!is_numeric($nodeID) || !$nodeID) return;

// load node object
$node = node_load($nodeID);

// ensure the node object was loaded
if (!is_object($node)) return;

// get vocabularies for this node
$vocabs = taxonomy_get_vocabularies($node->type);
   
// ensure there is taxonomy
if (!is_array($vocabs)) return;
if (
count($vocabs)==0) return;
   
// loop through vocablularies, look for vid that matches vocab name
foreach ($vocabs as $vocab) {
  if (
$vocab->name == 'Topics') {
   
$vid = $vocab->vid;
    break;
  }
}
   
// lookup terms for this node, by vocabularyID
$nodeTerms = taxonomy_node_get_terms_by_vocabulary($node->nid, $vid);
   
// loop through node terms and get a list of term IDs
$nodeTermIDs = array();
foreach (
$nodeTerms as $nodeTerm) {
 
$nodeTermIDs[] = $nodeTerm->tid;
}
   
$args = $nodeTermIDs;

if (
count($args)==0) return;

// get view object
$view = views_get_view('related_content');

if (!
is_object($view)) return;

// generate view html
$viewHtml = views_build_view('block', $view, $args, FALSE, $view->nodes_per_block);

if (
$view->block_title && $viewHtml) echo "<h2>" . $view->block_title . "</h2>";
echo
$viewHtml;
?>

Syndicate content