I am using Drupal 6.x and Views2. I am trying to theme the view to add a "sticky" class (so I can give the whole row a background-image to indicate it's stickiness). I already have created a views-view-unformatted--my-view.tpl.php file, and have added a class to the wrapper. I need to add an additional class if the node is sticky.

I have no idea how to go about this. In the .tpl.php file that I have now, $row is already-formatted HTML. I have no idea how to access the node's sticky attribute from inside this file.

I added the node's stickiness as a field for the view (excluded from display). I also have successfully dipped into a preprocess function for the view thanks to http://www.drupaler.co.uk/blog/theming-views-drupal-6x/67. Unfortunately, I just don't know how that's useful!

I'm an advanced user (themes, module development, etc) who is just new to Drupal 6 and Views 2. Any help is MUCH appreciated!

Comments

jstoller’s picture

I've been struggling with the same issue all morning. Have you discovered any solutions yet?

––
Jeremy Stoller
Senior Graphic Artist
California Science Center

––
Jeremy Stoller
Senior Graphic Artist
California Science Center

jstoller’s picture

I think I've got it!Add the following to your template.php file:

function phptemplate_preprocess_views_view_list(&$vars) {
  $view     = $vars['view'];
  $rows     = $vars['rows'];

  $vars['classes'] = array();
  // Set up striping values.
  foreach ($rows as $id => $row) {
    $vars['classes'][$id] = 'views-row-' . ($id + 1);
    $vars['classes'][$id] .= ' views-row-' . ($id % 2 ? 'even' : 'odd');
    if ($id == 0) {
      $vars['classes'][$id] .= ' views-row-first';
    }
    if ($view->result[$id]->node_sticky == 1) {
      $vars['classes'][$id] .= ' sticky';
    }
  }
  $vars['classes'][$id] .= ' views-row-last';
}

You also need to make sure there's a views-view-list.tpl.php template in your theme, otherwise Drupal won't recognize this function. This of course assumes you are trying to style list view.

––
Jeremy Stoller
Senior Graphic Artist
California Science Center

––
Jeremy Stoller
Senior Graphic Artist
California Science Center

darkodev’s picture

Brilliant! Been playing with this preprocessor all morning without much luck. Added a node-unpublished class based on node_status in the same way.

In D5/Views 1, this could have happened by overriding theme_views_view_list in template.php

Just added that so others might possibly find this post when searching theme_views_view_list()

Thanks much!

tanc’s picture

Thanks Jeremy, also saved me some time figuring this out. Here's a condensed version that doesn't overwrite default styles:

/**
 * Add a sticky class to any rows which are stickied in Views
 */
function template_preprocess_views_view_unformatted(&$vars) {
  foreach ($vars['rows'] as $id => $row) {
    if ($vars['view']->result[$id]->node_sticky == 1) {
      $vars['classes'][$id] .= ' sticky';
    }
  }
}

Note that this is for the unformatted style. If you're using a list style just change the function name to phptemplate_preprocess_views_view_list and make sure you have the correct template file in your theme's directory so the preprocess function will work.

michael.scappa’s picture

Thanks for this, saved me some time. I have no clue why this isn't implemented in views anyway, seems like such a common thing.

One thing I did notice, you dropped the views-row class when you're building your classes. May cause issues for some that theme using that class (as I do).

hansrossel’s picture

For Views 3 in Drupal 7 use the following code in template.php.
Also don't forget to add sticky as a field to the view (and exclude the field from display).


function template_preprocess_views_view_unformatted(&$vars) {
  $view = $vars['view'];
  $rows = $vars['rows'];

  $vars['classes_array'] = array();
  $vars['classes'] = array();
  // Set up striping values.
  $count = 0;
  $max = count($rows);
  foreach ($rows as $id => $row) {
    $count++;
    $vars['classes'][$id][] = 'views-row';
    $vars['classes'][$id][] = 'views-row-' . $count;
    $vars['classes'][$id][] = 'views-row-' . ($count % 2 ? 'odd' : 'even');
    if ($count == 1) {
      $vars['classes'][$id][] = 'views-row-first';
    }
    if ($count == $max) {
      $vars['classes'][$id][] = 'views-row-last';
    }

    if ($row_class = $view->style_plugin->get_row_class($id)) {
      $vars['classes'][$id][] = $row_class;
    }

    // Add a sticky class. Remark: make sure sticky is also added as a field to the view (and excluded from display)
    if ($vars['view']->result[$id]->node_sticky == 1) {
      $vars['classes'][$id][] = 'sticky';
    }

    // Flatten the classes to a string for each row for the template file.
    $vars['classes_array'][$id] = implode(' ', $vars['classes'][$id]);
  }
}
mshepherd’s picture

In views 3, template overrides like this shouldn't be necessary, as you can add custom classes to rows from the user interface.

You'll need to add the sticky field into the view - I formatted my sticky field like this:

formatting a sticky field

Take a look at the replacement patterns available in one of the fields after the sticky field - mine looked like this:

replacement pattern

The replacement pattern for the sticky field is [sticky] - unless your setup is very different to mine, yours will probably be [sticky] aswell.

row format settings

Type the replacement pattern into the row class field, apply to your display & save the view.

row class field

Any sticky nodes should now get the Sticky class.

djg_tram’s picture

Nice idea but has a drawback: on a multilanguage site, the class name will be localized (and changing depending on the language).

conan_payne’s picture

After setting the Output format to Sticky/ you then scroll down to Rewrite results and check Rewrite the output of this field; you can define the classname as the text.

conan_payne’s picture

Due to a change in views 7.x-3.4: Add an outut format for "Promoted" similar to what "Sticky" and "Published" have. The sticky output format now outputs on a negative result. So you get the defined classname regardless of sticky status.

(It still doesn't work if you don't use rewrite results, as you get the classes "Sticky" and "Not Sticky" -- which in CSS would both be regarded as sticky.)

A solution is to change the Output format to True/False, then include the token *in* the Rewrite results e.g., sticky-row-[sticky]
This way you'd then get the classes: sticky-row-True and sticky-row-False.

Joel MMCC’s picture

Instead of choosing “Sticky/Not Sticky” or “True/False” or some such, simply choose “Custom” instead from the drop-down menu.

Then, enter “sticky” (for consistency with other class names) or “Sticky” (if you want to quickly spot it in an HTML Source view) as the Custom Value for TRUE, and leave Custom Value for FALSE empty!

Then, do everything else as described in mshepherd’s outstanding post above. Voila!

This way, you can also give a more semantically meaningful class name if you prefer. For instance, if you’re doing this for your “Upcoming Events” Display of an Event Calendar View, and you use Sticky to flag Events that are of special public interest, you could use “public” instead of “sticky” as your class name by simply entering that as the Custom Value for TRUE.

rroose’s picture

Thanks! Just what I needed. A simple solutions without the help of extra code.

timmay’s picture

Thanks for the tip. This worked fine for me.