Flowing a list view into two columns

Columns. While it may seem like a good idea to a graphic designer, the idea of newspaper-style columns strikes fear in the hearts of themers everywhere. In particular, you may run into an instance where you need a list view to be A-L in the first column, then M-Z in the second column. I'll walk you through a method for doing just that, using a little PHP. Note that this is for Drupal 7, but is easily adaptable for Drupal 6.

I will note first that there are a couple other quickie options that might work for your situation.

1. There are several javascript solutions available, which finds a midpoint in the text and wraps the chunks in divs. This works, but if a user has a plugin like NoScript enabled, this solution does not degrade gracefully.

2. There IS a CSS3 multicolumn solution, but it is largely unsupported. Currently it is only supported by Firefox 1.5+ and Safari 3.

So, eventually, there will be a simple CSS solution, but, for the time being, the cleanest option is server-side, using PHP.

In my example here, we'll look at theming a list view to have multiple columns.

Say you have a view with a some items that we want to display in two columns. Views generates HTML that looks something like this:

<div class="view-columns">
  <div class="view-content">
    <div class="views-row views-row-1 views-row-odd views-row-first"> ... </div>
    <div class="views-row views-row-2 views-row-even"> ... </div>
    <div class="views-row views-row-3 views-row-odd"> ... </div>
    <div class="views-row views-row-4 views-row-even views-row-last"> ... </div>
  </div>
</div>

Here's what that looks like just floating each row to the left. Looks like columns, but they are not in the order we want.

floated rows

Instead, we want something that looks like this:

newspaper style columns

To make this themable with CSS, we need the markup to look like this instead:

<div class="view-columns">
  <div class="view-content" id="leftcol">
    <div class="views-row views-row-1 views-row-odd views-row-first"> ... </div>
    <div class="views-row views-row-2 views-row-even"> ... </div>
  </div>
  <div class="view-content" id="rightcol">
    <div class="views-row views-row-3 views-row-odd"> ... </div>
    <div class="views-row views-row-4 views-row-even views-row-last"> ... </div>
  </div>
</div>

The solution to building this markup is with PHP in a views template. The next trick is to choose the right one! Editing your view, click on the Advanced tab, then on Theme: Information. We want to use the Display output template. So, for example, mine is called: views-view--columns--page.tpl.php.

First, we'll make a preprocess function in our template.php file specific to that views template file that finds the number of view results and the halfway point.

This first function here is a helper function for Drupal 7 so you can add preprocess functions to specific views on the fly:

<?php
 
function THEME_preprocess_views_view(&$vars) {
    if (isset(
$vars['view']->name)) {
     
$function = 'THEME_preprocess_views_view__'.$vars['view']->name;
      if (
function_exists($function)) {
      
$function($vars);
      }
    }
  }
?>

And here's the preprocess function:

<?php
 
function THEME_preprocess_views_view__columns(&$variables) {
   
$view = $variables['view'];
   
// Create a variable that divides number of results in half and add one.
   
$variables['half'] = ceil((count($view->result) / 2) + 1);
  }
?>

Once you have determined the $half variable, which is row number that starts the second column.

So let's add the markup to the views tpl file.

Replace the lines:

<div class="view-content">
  <?php print $rows; ?>
</div>

with:

<?php
 
// remove white space in html
 
$rows = preg_replace('~>\s+<~', '><', $rows);
 
// add the </div><div> in at the halfway point to separate the columns
 
$search = '<div class="views-row views-row-' . $half;
 
$replace = '</div><div id="rightcol" class="view-content"><div class="views-row views-row-' . $half;
 
$rows = str_replace($search, $replace, $rows); //
?>

<div class="view-content" id="leftcol">
  <?php print $rows; ?>
</div>

This will wrap the first half of your results in a leftcol div and the second half in a rightcol div. From there, float your columns and add the necessary padding. Enjoy!

Dave wrote 2 years 50 weeks ago

This is actually a comment re your previous blog but comments are closed there.

I followed the D7 instructions to create a searchable directory but I can't get it to make a directory of users, It's giving me a directory of nodes. Nice, but not much help. Please could you give me so indication as to what I've missed? One thing I think is probably significant is that I don't get the User: fields listed in the list of fields I can add to the directory.

If possible, could you reply by email.

Thanks

Amanda Luker wrote 2 years 50 weeks ago

Hi Dave! The very first step of making the view (after giving it a name and description) is the option to select what kind of information to show -- make sure you select "Users" there. Let me know if that does the trick.

I'll check to see if the post requires revision.

Dave wrote 2 years 50 weeks ago

That fixed it! Thanks.

Contact Us

About Amanda Luker

Amanda Luker is a web designer in Minneapolis, MN.

AdvoTwitter

  • September 13, 2014 - 4:51pm
  • Develop a process *with* your team to build ownership and buy in. -@brettharned #dpm2014
    September 13, 2014 - 3:39pm
  • Most important thing is to pick and choose. Design a process that works for you. Our process is evolving daily. -@brettharned #dpm2014
    September 13, 2014 - 3:36pm
  • Talking kick off meetings. Lotta people advocating for a full day workshop. #dpm2014
    September 13, 2014 - 2:47pm
  • Spotted: first Gantt chart of #dpm2014 http://t.co/dOdTCT4ydw
    September 13, 2014 - 2:24pm