layout | Eric's Drupal Blog

Content tagged with: layout

Eric's picture

Using jQuery to ensure Panel columns are the same height

I recently implemented the Panels module to create a page layout with 3 columns. I added background images to the columns, repeating on the y axis to span the entire length of the column. The problem I encountered: you cannot predict how tall the content will be in your columns and they will be staggered. To provide a more uniform styling, I added some jQuery to find the tallest column and set the shorter ones to the max height.

$(document).ready(function(){

  // keep track of the tallest column
  var tallest = 0;

  // loop through columns and find the tallest
  $('#panel_other_programs .panel-panel').each(function(){
    if ( $(this).outerHeight(true) > tallest )
      tallest = $(this).outerHeight(true);
  });

  // loop through columns and adjust height as necessary
  $('#MY-PANEL-UNIQUE-IDENTIFIER .panel-panel').each(function(){
   
    // check if current column needs to be adjusted
    if ( $(this).outerHeight(true) < tallest ) {
      // set new height
      $(this).height( tallest );
    }
  });

});

Now, all the columns should have a uniform height and the backgrounds should all span the entire length of each column.

gradient spacer
Eric's picture

Changing the user login block to a horizontal layout

At some point your design may call for a horizontal user login block. Luckily this can be accomplished with just a few lines of CSS. I added the following CSS to my theme:

.block #user-login-form { text-align: left; }
.block #user-login-form #edit-name-wrapper { float: left; margin-right: 10px; }
.block #user-login-form #edit-pass-wrapper { float: left; margin-right: 10px; }
.block #user-login-form #edit-submit { float: left; margin-top: 25px; }
.block #user-login-form .item-list { clear: both; text-align: right; }

Before:

After:

gradient spacer
Eric's picture

Creating a custom printer-friendly layout for certain node types

If you're like me, you probably use complicated node types with many fields and custom layouts. If that's the case, the default printer-friendly rendering of nodes may not suit you. In this code snippet I'll explain how you can override the templates and how I got to this step.

The first step when making modifications like this is to determine how the html was generated (template, function, callback, etc). Take a look at the query string for a printer friendly page: book/export/html/YOURNODEID. If you check out the book module, you'll see an entry in the book_menu() hook (book/export/%/%) that uses the book_export() page callback. Examining that function leads you to book_export_html(). This function generates the html for printer-friendly layout using the book_export_traverse() function and then calls the theme() function. The theme function allows us to override the theme layer. In this example I'll create a function that follows the templates suggestions guidelines to insert my code...

<?php
// the first argument being passed to theme function is book_export_html, so I'll prefix my function with my theme's name
function MYTHEME_book_export_html($title, $contents, $depth) {
 
// since the node ID is not being passed as an argument,
  // we'll grab it from the query string...
  // load node
 
$node = node_load(arg(3));
   
 
// define a list of node types to override
 
$nodeTypes = array('MYCOMPLICATEDNODETYPE1','MYCOMPLICATEDNODETYPE2');
  if (!
in_array($node->type, $nodeTypes)) {
   
// for all the rest of my node types, I'll use the default template:
   
return theme('MYTHEME_book_export_html', $title, $contents, $depth);
  }

 
// now, you have access to the $node variable and can do what ever you'd like with it
  // note: the drupal_render() function is great for generating the output for a CCK field

 
return "MY NEW AMAZING PRINTER-FRIENDLY HTML";
}
?>

In the above code, the theme registry was overrode by creating a function named: MYTHEME_book_export_html. The last part of this code snippet is returning regular nodes back to the default book template file (book-export-html.tpl.php). In the above code, I mention a theme registry entry called "MYTHEME_book_export_html", which has not been registered yet. We can register a new template using hook_theme()...

<?php
function MYTHEME_theme() {
  return array(
   
// register the default book export template
   
'MYTHEME_book_export_html' => array(
     
// pass it the same arguments, defined in the book_theme() function
     
'arguments' => array('title' => NULL, 'contents' => NULL, 'depth' => NULL),
     
// define the same template as defined in the book_theme() function
     
'template' => 'book-export-html',
     
// since this file does not exist in our theme directory,
      // we'll specify the path of the book module
     
'path' => 'modules/book',
    )
  );
}
?>

Now that we've registered the "new" template (and rebuilt the theme registry) all of our standard nodes will use the original book template file and our custom node types will be modified as defined.

gradient spacer
Eric's picture

Creating an alternate theme layout for certain pages, part 2

This code snippet shows you how you can create alternate theme layouts for certain pages using a preprocess function. In this function, we'll test for certain conditions and apply different CSS classes to the body tag. The following function belongs in your theme's template.php file:

<?php
function MYTHEME_preprocess_page(&$variables) {
 
$exploded = explode('/', $_REQUEST['q']);
  if (
$variables['is_front']) {
   
$bodyClass = 'front';
  } elseif (
$exploded[0]=='admin') {
   
$bodyClass = 'admin';   
  } else {
   
$bodyClass = 'interior';   
  }
 
$variables['bodyClass'] = $bodyClass;
}
?>

Next, in your page.tpl.php file, replace your opening body tag with the following:

<body class="<?php print $bodyClass; ?>">

Now, you can add CSS to change the layout of your page based off of the classes you applied to the body tag. For example:

/* hide right column for admin pages */
body.admin .column_right{ display: none; }

/* set width for right column on interior pages */
body.interior .column_right { width: 250px; }

/* set different width for right column on home page
body.front .column_right { width: 500px; }

gradient spacer
Eric's picture

Revise the structure, layout, and visibility of your node fields

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;

  }

}
?>

gradient spacer Syndicate content