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 43 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 42 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 42 weeks ago

That fixed it! Thanks.

Contact Us

About Amanda Luker

Amanda Luker is a web designer in Minneapolis, MN.

AdvoTwitter

  • RT @lpackard: Running for office? How to get a winning campaign website http://t.co/0xsa8mJLkX via @dailykos #p2
    July 23, 2014 - 3:47pm
  • RT @cannon2337: Interesting Insight @eduserv- Charities failing to address shift to #mobile devices http://t.co/vD776SDQww #charity #nptec…
    July 23, 2014 - 12:18pm
  • Size of tech budget doesn't mean higher tech adoption – smarter spending correlates more than simply spending more. http://t.co/E0gYT6Dec5
    July 23, 2014 - 11:15am
  • Our brand new developer Sarah (@hey_germano) will be at DrupalCamp WI this weekend! Will you? Find her and say hi! http://t.co/gDVyFidJsW
    July 23, 2014 - 11:15am
  • 7% of small orgs say they're at the leading end of the "Technology Adoption" spectrum vs 3% of the very large orgs: http://t.co/E0gYT6Dec5
    July 23, 2014 - 11:05am