In views preprocess hooks, there's an empty $attributes_array variable. Adding anything to this doesn't do anything because it's not printed in the template.

<?php

/**
 * @file
 * Default simple view template to display a list of rows.
 *
 * @ingroup views_templates
 */
?>
<?php if (!empty($title)): ?>
  <h3><?php print $title; ?></h3>
<?php endif; ?>
<?php foreach ($rows as $id => $row): ?>
  <div <?php print $row_classes[$id]; ?>>
    <?php print $row; ?>
  </div>
<?php endforeach; ?>

The only way to get custom attributes is to override the template and do your own handling in preprocess.

Comments

kris_mcl’s picture

This was very useful, thanks for posting.
Based on this comment I implemented the following to get custom data- attributes on views rows. This is implemented in D7, just posting here in case it's still relevant moving forward.

I added this to template.php:

function mytheme_preprocess_views_view_unformatted(&$variables) {
  $num_rows = count($variables['classes_array']);
  for ($i = 0; $i < $num_rows; $i++) {
    $variables['attributes_array'][$i] = array('#name' => 'data-mytheme-myattributename', '#value' => 'myCustomValue', );
  }

and then I customized a Views style template as indicated above, like this:

<?php
/**
 * @file
 * Default simple view template to display a list of rows.
 *
 * @ingroup views_templates
 */
?>
<?php if (!empty($title)): ?>
  <h3><?php print $title; ?></h3>
<?php endif; ?>
<?php foreach ($rows as $id => $row): ?>
  <div
  <?php if ($classes_array[$id]) { print ' class="' . $classes_array[$id] .'"';  } ?> 
  <?php if ($attributes_array[$id]) { print ' ' . $attributes_array[$id]['#name'] . '="' . $attributes_array[$id]['#value'] .'"';  } ?>
  >
    <?php print $row; ?>
  </div>
<?php endforeach; ?>

And I end up with this output:

<div class="views-row views-row-1 views-row-odd views-row-first" data-mytheme-myattributename="myCustomValue">
...
</div>

Seems to work like a charm. Thanks again!

Edit: removed dpm(); comment in template header.

dawehner’s picture

Project: Drupal core » Views (for Drupal 7)
Version: 8.x-dev » 7.x-3.x-dev
Component: views.module » Code

In Drupal 8 we do know use attributes all over the place. If someone manages to fix the templates without breaking existing templates/sites feel free to post it.

kris_mcl’s picture

For anyone coming across this, I've come to realize that while this does in fact work, it only allows assigning a single name => value pair per views row. I ran into problems trying to expand the functionality to allow assigning multiple attributes to a single row. I was able to work within this limit on a recent project but I'd love to revisit this and figure out how to do it. I'll post any progress here.

kris_mcl’s picture

Issue summary: View changes

fix formatting.

agoradesign’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new1.97 KB

As the variables $attributes, $title_attributes and $content_attributes are available automatically in every tpl file (see https://api.drupal.org/api/drupal/includes%21theme.inc/function/template...), I've added these attributes, whereever it made sense to me (not every Views template has a wrapping container element, nor elements, where the title or content attributes would fit).

mustanggb’s picture

Status: Needs review » Needs work

It's a great start, but it'd also be really handy to be able to add per row attributes.

I made the following additions:

views.module

+ function views_process(&$vars) {
+   if (isset($vars['row_attributes_array'])) {
+     foreach ($vars['row_attributes_array'] as $row_number => $row_attributes_array) {
+       $vars['row_attributes'][$row_number] = drupal_attributes($row_attributes_array);
+     }
+   }
+ }

theme/views-view-table.tpl.php

...
- <tr <?php if ($row_classes[$row_count]) { print 'class="' . implode(' ', $row_classes[$row_count]) .'"';  } ?>>
+ <tr <?php if ($row_classes[$row_count]) { print 'class="' . implode(' ', $row_classes[$row_count]) .'"';  } if ($row_attributes[$row_count]) { print $row_attributes[$row_count];  } ?>>
...

Which then allows you to do something like this:

my_custom_module.module

+ function my_custom_module_preprocess_views_view_table(&$vars) {
+   foreach ($vars['rows'] as $row_number => $row) {
+     $vars['row_attributes_array'][$row_number]['my_custom_attribute'] = 'my_custom_attribute_value_' . ($row_number + 1);
+   }
+ }

Obviously this is only for the table format so far, it may be pertinent to include this in the theme files for other formats.

mustanggb’s picture

Issue summary: View changes

Updated issue summary as dawehner confirmed this is a D7 only issue.

chrisgross’s picture

Here's a re-roll of #4 that also adds content attributes to the "view-empty" div.