I've been working on this off and on for a couple of weeks and after doing lots of research on theming views, I think I'm *really* close. I have all the pieces I need, just can't connect them. This is my first time theming views to this extent and I'm just so impressed with the functionality available.

I have a list view, grouped by taxonomy terms. I want to break the list in half and present it in 2 columns side by side. I've figured out that in the template.php file I can use the theme_preprocess_views_view function to count the number of results and split the value in half using floor(count($view->result) / 2). I've stored this value as $variables['halfway'].

In the same function I am setting a counter within a foreach loop and looping through the results. What I want to do is insert some html (</div><div id="rightcol">) at the point where the count equals the halfway variable. Then I'll use CSS to float the columns. I've already wrapped <div id="leftcol"></div> around the whole list.

Where I'm getting stuck is that I need to print the html above in the views-view-list.tpl.php file, right before the <div id="item-list">. But the code to determine when to print it needs to be in the preprocess function for views-view (not views-view-list). I can't figure out how to connect the two.

Any suggestions on completing this approach, or even a better approach, would be greatly appreciated. I have not found any documentation for achieving this in Drupal 6, only Drupal 5, so I'm hoping this will benefit some others as well.

Thanks for any help!
Kate

Comments

nevets’s picture

Silly question why not just use the grid style and specify 2 columns?

k.obrien’s picture

Thanks for responding nevets! I did try that initially and it's almost what I want, but there are a couple of things that aren't quite what I had in mind. Both of these approaches are almost there. If I can't do exactly what I want, I could fall back on either of these methods depending on how strongly I feel the design needs the 2 columns.

My plan was to have a list of businesses, grouped by category where the 1st half of the categories are in the left column, and the 2nd half in the right:

Category 1              Category 3
1. biz1                    1. biz1
2. biz2                    2. biz2
3. biz3                    3. biz3

Category 2              Category 4
1. biz1                    1. biz1
2. biz2                    2. biz2
3. biz3                    3. biz3

The grid view presented me with:

Category 1              
biz1                    biz3
biz2   

Category 2              
biz1                    biz3
biz2    

So it's creating columns of the businesses within the categories instead. I know, big deal it's still 2 columns. And it definitely looks better than the 1 long column I have now with the list view. But I'm also not crazy about the table markup since it's really a list, so semantically the markup isn't quite right.

I know more about theming views now than I did when I tried the grid so I might be able to fiddle with it so I'm happier with the markup it produces. Either way neither of these is the perfect solution yet. But I really appreciate your response to get me rethinking about the grid view as a possibility. I had sort of discarded that idea after my initial test with it. I'll have to try theming it and see where it gets me.

If I don't see any other solutions I'll post back with what I decided and a link to the page. Thanks again!

k.obrien’s picture

After nevets' suggestion, I looked at theming the grid to use lists instead of tables so the markup would be semantic.

I realized however that I could just use the same principle I'm trying to use to make the 2 category columns, within the views-view-list.tpl.php file to do exactly what the grid view does, but with lists instead of tables.

In views-view-list.tpl.php, I'm getting a count of all the nodes in the category, splitting it in half and storing this value (call it $half). Then I added a counter into the foreach loop that already exists in the views-view-list.tpl.php file. If the counter equals the $half variable, I'm printing out </ol><ol> tags which effectively creates 2 ordered lists instead of one. Then I just set the start attribute in the 2nd list to the value of the counter. Floating the lists using CSS finishes it off. It looks just like the grid view, but uses ordered lists.

It's still not exactly what I wanted, but it's a good compromise until I figure out how to implement my original idea.

k.obrien’s picture

I still haven't been able to achieve the split list as described above, so I'm still open to suggestions!

Kate

k.obrien’s picture

It may not be the most elegant solution, but it works and I'm happy with it.

In template.php I used the preprocess_views_view function to get the total number of items (in my case businesses) for my view, split it in half ($half), and was able to get the taxonomy term name (which is ultimately the group title) of the business that was at the halfway point from view->result, since each item has a unique key in the array. I store the taxonomy term as $halfway_point. My view name is "category-list", hence the "__category_list" in the function name.

function theme_preprocess_views_view__category_list(&$variables) {
        $view = $variables['view'];
        $half = ceil(count($view->result) / 2);
        $variables['halfway_point'] = $view->result[$half]->term_data_name;
}

Then in my views-view--category-list.tpl.php file, I added the following to str_replace the group heading with the same name, but with a </div><div> at the beginning of it. I had to include some of the view template html in the str_replace because the left column should end and the right should begin BEFORE the <div class="item-list"> tag so the html remains in the proper order.

### add the </div><div> in at the
### halfway point to separate the columns
$rows = str_replace("<div class=\"item-list\"><h3>$halfway_point","</div><div id=\"biz_rightcol\"><div class=\"item-list\"><h3>$halfway_point",$rows);

I also made the following change further down in the views-view--category-list.tpl.php file where $rows gets printed out, which sets up the left column:

 <div id="biz_leftcol">
      <?php print $rows; ?>
</div>

I then floated the 2 columns next to each other.

hanskuiters’s picture

Thanks k.obrien. Seems to work nice for you, but not for me.

I have a view block with the name 'block_domeinen_thema'. It is a HTML list with the fields 'Content: Reference' and 'Node: Title'. The list is grouped by field 'Content: Reference'.

This outputs to:
Reference title 1
-Node title 1
-Node title 2
Reference title 2
-Node title 3
-Node title 4
...

This is a list of 46 items which I want to display in 2 columns. The html structure looks like this:

<div class="item-list">
  <h3>Reference title 1</h3>
  <ul>
    <li class="views-row'>Node title 1</li> 
    <li class="views-row'>Node title 2</li>
  </ul>
</div>
<div class="item-list">
  <h3>Reference title 2</h3>
  <ul>
    <li class="views-row'>Node title 3</li>
    <li class="views-row'>Node title 4</li>
  </ul>
</div>

I put this in my template.php, where I changed 'theme_' with the name of my theme:

function theme_preprocess_views_view__block_domeinen_thema(&$variables) {
  $view = $variables['view'];
  $half = ceil(count($view->result) / 2);
  $variables['halfway_point'] = $view->result[$half]->term_data_name;
}

It won't find term_data_name but that is because I can't get a var_dump() from the $variables.

I then followed your code but can't figure out which template file you use to alter. If I use 'views-view--block-domeinen-thema.tpl.php' and I do a var_dump() on $rows I get one string with all the 'item-list' items (like the html I printed above) where instead I need an array.

Hope you or someone else can help me out.

soulfroys’s picture

in template.php:

function [template_name]_preprocess_views_view__glossary_wiki__page(&$variables) {
  $view = $variables['view'];
  $half = ceil(count($view->result) / 2);
  $variables['halfway_point'] = $view->result[$half]->customfield_phpcode_0;
}

In created template file views-view--glossary-wiki--page.tpl.php:

  \<?php if ($rows): ?\>
    \<?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=\"item-list\"><h3>$halfway_point"; 
    $replace = "</div><div id=\"biz_rightcol\"><div class=\"item-list\"><h3>$halfway_point";
    $rows = str_replace($search, $replace, $rows); // 
    ?\>
    <div class="view-content" id="biz_leftcol">\<?php print $rows; ?\></div>
  \<?php elseif ($empty): ?\>
    <div class="view-empty">
      \<?php print $empty; ?\>
    </div>
  \<?php endif; ?\>

View name:
glossary_wiki

Hope this helps!

hanskuiters’s picture

Thanks. I'll try it. I need the columns for a mega menu. For now I use Views-php-array module.
- Install the module
- Make a new display PHP Array
- Do the magic on that array like split it in half to make two columns
- Put all that php code in a block
- Assign the block to a mini panel for the mega menu

socialnicheguru’s picture

This is an excellent post on themeing views 2.

Thanks! Chris

http://SocialNicheGuru.com
Delivering inSITE(TM), we empower you to deliver the right product and the right message to the right NICHE at the right time across all product, marketing, and sales channels.

Michsk’s picture

joachim’s picture

I've just added this page to the theme snippets: http://drupal.org/node/790530

memmons’s picture

I realize this is an old post but wanted to share my solution anyway. I took all other suggestions but did not use the actual template file since you don't have access to the rows anyway. This version allows you to set the # of columns at the top so if needed then it can be configurable. This version will require that you use an HTML List as your format since I prefer to work with the <ul><li> structure. Once done you can add your css which makes them float accordingly i.e. ul.view-column { float:left; }.

function your_theme_preprocess_views_view__your_view(&$vars){

        $columns = 3; //Number of Columns
        $count = ceil(count($vars['view']->result) / $columns);
        
        $vars['split'] = $count;

        $rows = preg_replace('~>\s+<~', '><', $vars['rows']);
        $rows = str_replace('<ul', '<ul class="view-column view-column-1"', $rows);

        for ($i = 2; $i <= $columns; $i++) {
            
            $row_count = ($i - 1) * $count + 1;
            $search = '<li class="views-row views-row-' . $row_count;
            $replace = '</ul><ul class="view-column view-column-' . $i . '"><li class="views-row views-row-' . $row_count;
            $rows = str_replace($search, $replace, $rows);
        
        }
        
        $vars['rows'] = $rows;
    
}
georgemastro’s picture

Nice solution! I made a small change because it was including my contextual filter lists.

$rows = str_replace('<ul>', '<ul class="view-column view-column-1">', $rows);