Help remove three DIVS surrounding "list view" block
rareexample - July 6, 2007 - 20:06
I've been rummaging through the forums for hours with no luck.
What I'm trying to accomplish.
When you create a list view using the views module and use a block to display the list, it generates the following html source code :
<div id="block-views-key_features_auto" class="clear-block block block-frontkeys">
<h2>Block Title</h2>
<div class="view view-key-features-auto">
<div class="view-content view-content-key-features-auto">
<div class="item-list">
<ul><li> <a href="link">Link to my node</a>
</li><li> <a href="link">Link to my node</a>
</li><li> <a href="link">Link to my node</a>
</li><li> <a href="link">Link to my node</a>
</li><li> <a href="link">Link to my node</a>
</li><li> <a href="link">Link to my node</a>
</li><li> <a href="link">Link to my node</a>
</li>
</ul>
</div>
</div>
</div>
</div>So the tree divs :
<div class="view view-key-features-auto">
<div class="view-content view-content-key-features-auto">
<div class="item-list">are unnecessary and I would like to remove them from wrapping my unordered list but can't find out how without hacking views.module. If anyone has any suggestions, I would be very greatful.

override the theme callback
(without looking) i think the lists are themed by a function called theme_item_list which you can override by making your own phptemplate_item_list which contains whatever you want. Just pull the theme_item_list function from api.drupal.org and modify until you are content.
Thanks for the reply
Thanks for the reply casconed. I took a look at that but there's only 1 div that function is spitting out, not the 3 I'm looking for.
Anyone else have any ideas ?
I found this in views.module
I found this in views.module which I think may be outputing these divs
/**
* Display the nodes of a view as a list.
*/
function theme_views_view_list($view, $nodes, $type) {
$fields = _views_get_fields();
foreach ($nodes as $node) {
$item = '';
foreach ($view->field as $field) {
if (!isset($fields[$field['id']]['visible']) && $fields[$field['id']]['visible'] !== FALSE) {
if ($field['label']) {
$item .= "<div class='view-label ". views_css_safe('view-label-'. $field['queryname']) ."'>" . $field['label'] . "</div>";
}
$item .= "<div class='view-field ". views_css_safe('view-data-'. $field['queryname']) ."'>" . views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view) . "</div>";
}
}
$items[] = "<div class='view-item ". views_css_safe('view-item-'. $view->name) ."'>$item</div>\n"; // l($node->title, "node/$node->nid");
}
if ($items) {
return theme('item_list', $items);
}
}
I tried putting that in my template.php file and making changes but my page goes blank. Any clues as how I can get this done?
Thanks in advance.
rename the function
try changing the name of the function from theme_views_view_list to phptemplate_views_view_list and then make your changes.
doesn't work
I tried the above solution but to no go, page still comes up blank.
That damn view module produces some of the messiest code i have ever seen. It is terminally unnecessary! I'd love just for it to produce something like this (say if it was a block view):
<div class="block"><h2>Block Heading</h2>
<ul class="list1>
<li>content1<li>
<li>content2<li>
</ul></div>
If I could assign individual classes to specific
instead it looks like this:
<div class='view view-10-articles'><div class='view-header view-header-10-articles'><h2>Recent Articles</h2></div>
<div class='view-content view-content-10-articles'><div class="item-list"><ul><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/about/technology/web_toolkit">Web Toolkit</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/about/technology/creative_toolkit">Creative Toolkit</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/%5Bcontainerfirst%5D/%5Bcategoryfirst%5D/want_to_read_a_little_more">Want to read a little more?</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/%5Bcontainerfirst%5D/%5Bcategoryfirst%5D/an_advanced_approach_to_all_designs">An advanced approach to all designs</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/%5Bcontainerfirst%5D/%5Bcategoryfirst%5D/web_design_with_a_little_extra_thought">Web design with a little extra thought</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/%5Bcontainerfirst%5D/%5Bcategoryfirst%5D/an_introduction">An Introduction</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/about/technology/browsers_and_screen_sizes">Browsers and Screen Sizes</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/about/background/a_brief_history">A Brief History</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/about/philosophy/declaration_of_ideals">Declaration of Ideals</a></div></div>
</li><li><div class='view-item view-item-10-articles'><div class='view-field view-data-node-title'><a href="/b_Mine/jacktaranto.com/current/info/about/philosophy/introduction">Introduction</a></div></div>
</li></ul></div></div></div>
Horrible!!!
No work around?
So far no work around for this?
I have removed the divs from
I have removed the divs from the function in the code below and added an id and class (test and test2) to the ul-tag.
I wanted to have an id in the ul-tag for having the html correct for using jcarousel. In that case test becomes fi mycarousel and test2 would be jcarousel-skin-tango. With the views theme wizard it is possible to get in an easy way a piece of similar code where you can strip divs the same way just for one specific view.
This piece of code (change yourthemename) combined with the other one further in this post strips all unneccesary div-tags.
Great! Just a pity of all this removing work. It would be a lot better if views simply did not output all this useless stuff. It's almost worse than tables design!
/**
* Display the nodes of a view as a list. Cleaning up views ugly markup html - Removing unnecessary divs.
*/
function yourthemename_views_view_list($view, $nodes, $type) {
$fields = _views_get_fields();
foreach ($nodes as $node) {
$item = '';
foreach ($view->field as $field) {
if (!isset($fields[$field['id']]['visible']) && $fields[$field['id']]['visible'] !== FALSE) {
if ($field['label']) {
$item .= $field['label'];
}
$item .= views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
}
}
$items[] = $item;
}
if ($items) {
return theme('item_list', $items, NULL, 'ul', array('id' => 'test', 'class' => 'test2'));
}
}
Good luck!
Hans
KOBA - Webdesign with Drupal
Still some divs left
Hi Hans,
I've tried your method. Here are the results;
<div id="block-views-Products" class="clear-block block block-views"><h2>Products</h2>
<div class="content">
<div class='view view-Products'>
<div class='view-header view-header-Products'>
<p>
<hr />
</p>
</div>
<div class='view-content view-content-Products'>
<div class="item-list">
<ul id="test" class="test2">
<li><a href="/content/products/item 1">item 1</a></li>
<li><a href="/content/products/item 2">item 2</a></li>
<li><a href="/content/products/item 3">item 3</a></li>
<li><a href="/content/products/item 3">item 4</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
As you see there are quite some divs left to make a mess of things! I guess I'm missing something being a Drupal noob ;) Do I have to create a .tpl.php file for this function?
Cheers
I think I got it; you're
I think I got it; you're looking at the wrong function. You need to override theme_views_view in template.php with something like the following. The blank page might be because your php memory limit is too low:
function phptemplate_views_view($view, $type, $nodes, $level = NULL, $args = NULL) {
$num_nodes = count($nodes);
if ($type == 'page') {
drupal_set_title(filter_xss_admin(views_get_title($view, 'page')));
views_set_breadcrumb($view);
}
if ($num_nodes) {
$output .= views_get_textarea($view, $type, 'header');
}
if ($type != 'block' && $view->exposed_filter) {
$output .= views_theme('views_display_filters', $view);
}
$plugins = _views_get_style_plugins();
$view_type = ($type == 'block') ? $view->block_type : $view->page_type;
if ($num_nodes || $plugins[$view_type]['even_empty']) {
if ($level !== NULL) {
$output .= views_theme($plugins[$view_type]['summary_theme'], $view, $type, $level, $nodes, $args);
}
else {
$output .= views_theme($plugins[$view_type]['theme'], $view, $nodes, $type);
}
$output .= views_get_textarea($view, $type, 'footer');
if ($type == 'block' && $view->block_more && $num_nodes >= $view->nodes_per_block) {
$output .= theme('views_more', $view->real_url);
}
}
else {
$output .= views_get_textarea($view, $type, 'empty');
}
if ($view->use_pager) {
$output .= theme('pager', '', $view->pager_limit, $view->use_pager - 1);
}
if ($output) {
return $output;
}
}
I'm totally on the same page with you when it comes to views creating ridiculously messy markup.
Another version:
Keep default markup but for non-empty results only
<?php
function phptemplate_views_view($view, $type, $nodes, $level = NULL, $args = NULL) {
$num_nodes = count($nodes);
if ($type == 'page') {
drupal_set_title(filter_xss_admin(views_get_title($view, 'page')));
views_set_breadcrumb($view);
}
if ($num_nodes) {
$output .= views_get_textarea($view, $type, 'header');
}
if ($type != 'block' && $view->exposed_filter) {
$output .= views_theme('views_display_filters', $view);
}
$plugins = _views_get_style_plugins();
$view_type = ($type == 'block') ? $view->block_type : $view->page_type;
if ($num_nodes || $plugins[$view_type]['even_empty']) {
if ($level !== NULL) {
$output .= "<div class='view-summary ". views_css_safe('view-summary-'. $view->name) ."'>". views_theme($plugins[$view_type]['summary_theme'], $view, $type, $level, $nodes, $args) . '</div>';
}
else {
$content = views_theme($plugins[$view_type]['theme'], $view, $nodes, $type);
if (!empty($content)) {
$output .= "<div class='view-content ". views_css_safe('view-content-'. $view->name) ."'>". $content . '</div>';
}
}
$output .= views_get_textarea($view, $type, 'footer');
if ($type == 'block' && $view->block_more && $num_nodes >= $view->nodes_per_block) {
$output .= theme('views_more', $view->real_url);
}
}
else {
$output .= views_get_textarea($view, $type, 'empty');
}
if ($view->use_pager) {
$output .= theme('pager', '', $view->pager_limit, $view->use_pager - 1);
}
if (!empty($output)) {
$output = "<div class='view ". views_css_safe('view-'. $view->name) ."'>$output</div>\n";
}
return $output;
}
?>
yay! how to remove views div class from lists!
This thread deserves stars! We should be able to exclaim its greatness. I am just adding this here in case someone else needs to know how to do this...
If you specifically want to remove all the div tags from the code output for lists in your views, you need to place the following function into your template.php file.
Where the function name below contains "phptemplate" you can place your own theme name.
/**
* Display the nodes of a view as a list.
*/
function phptemplate_views_view_list($view, $nodes, $type) {
$fields = _views_get_fields();
foreach ($nodes as $node) {
$item = '';
foreach ($view->field as $field) {
if (!isset($fields[$field['id']]['visible']) && $fields[$field['id']]['visible'] !== FALSE) {
if ($field['label']) {
$item .= $field['label'];
}
$item .= views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
}
}
$items[] = $item;
}
if ($items) {
return theme('item_list', $items);
}
}
Great indeed
Yeah, it is a relief to find some help on this issue. I too have list views that originally were buried in that horrible div tangle. When I added that last function to my template.php, everything extra inside li tags disappeared.
So I think it's a great start to get views output cleaner! But there are still those three div's outside the ul tag (.view, .view-content, .item-list). I think one would be enough. How to do that? And now there are no tags anymore to specify content inside the li tag, whereas previously there were too many of them... one per field would still be nice. How?
By the way, is this the only way to do this? Or would it be possible to make a file similar to page.tpl.php, something like view.tpl.php, where one could organize the output. It would be more familiar at least for me, closer to traditional html files.
Subscribed
Subscribed
Problem Solved
I was able to remove the extra divs around the content by adding this to my template.php (replace mytheme with theme name):
function mytheme_views_view($view, $type, $nodes, $level = NULL, $args = NULL) {
$num_nodes = count($nodes);
if ($type == 'page') {
drupal_set_title(filter_xss_admin(views_get_title($view, 'page')));
views_set_breadcrumb($view);
}
if ($num_nodes) {
$output .= views_get_textarea($view, $type, 'header');
}
if ($type != 'block' && $view->exposed_filter) {
$output .= views_theme('views_display_filters', $view);
}
$plugins = _views_get_style_plugins();
$view_type = ($type == 'block') ? $view->block_type : $view->page_type;
if ($num_nodes || $plugins[$view_type]['even_empty']) {
if ($level !== NULL) {
$output .= "<div class='view-summary ". views_css_safe('view-summary-'. $view->name) ."'>". views_theme($plugins[$view_type]['summary_theme'], $view, $type, $level, $nodes, $args) . '</div>';
}
else {
$output .= views_theme($plugins[$view_type]['theme'], $view, $nodes, $type);
}
$output .= views_get_textarea($view, $type, 'footer');
if ($type == 'block' && $view->block_more && $num_nodes >= $view->nodes_per_block) {
$output .= theme('views_more', $view->real_url);
}
}
else {
$output .= views_get_textarea($view, $type, 'empty');
}
if ($view->use_pager) {
$output .= theme('pager', '', $view->pager_limit, $view->use_pager - 1);
}
return $output;
}
and 5 is worse???
not quite sure but i think Dr5 has made this even worse... I am trying to swap out a view with AJAX so needed a div around my view output.. which i thought i could just do with adding a div with id opening in my view header and close it in my view footer... but views now wraps the header and footer with a div so i get
<div class=myview-header><div id="myid-for-ajax> </div> - but this is closing for header but will now look likel closing for my ID div??? duhhhPeter Lindstrom
LiquidCMS - Content Management Solution Experts
None of the examples above
None of the examples above did anything for clearing away div tags I tried them all
For drupal 5
Okay, this does help remove one or 2 of the divs, we are still left with -
-A div for the block,
-A "content" div (wth?)
-An "item-list" div
then we have ul,li etc..
Would be great to loose all but the block div, and be able to assign a class and id to the ul... possible?
/**
* This snippet removes some of the unnessecary DIV's from the view module
*/
function phptemplate_views_view($view, $type, $nodes, $level = NULL, $args = NULL) {
$num_nodes = count($nodes);
if ($type == 'page') {
drupal_set_title(filter_xss_admin(views_get_title($view, 'page')));
views_set_breadcrumb($view);
}
if ($num_nodes) {
$output .= views_get_textarea($view, $type, 'header');
}
if ($type != 'block' && $view->exposed_filter) {
$output .= views_theme('views_display_filters', $view);
}
$plugins = _views_get_style_plugins();
$view_type = ($type == 'block') ? $view->block_type : $view->page_type;
if ($num_nodes || $plugins[$view_type]['even_empty']) {
if ($level !== NULL) {
$output .= views_theme($plugins[$view_type]['summary_theme'], $view, $type, $level, $nodes, $args);
}
else {
$output .= views_theme($plugins[$view_type]['theme'], $view, $nodes, $type);
}
$output .= views_get_textarea($view, $type, 'footer');
if ($type == 'block' && $view->block_more && $num_nodes >= $view->nodes_per_block) {
$output .= theme('views_more', $view->real_url);
}
}
else {
$output .= views_get_textarea($view, $type, 'empty');
}
if ($view->use_pager) {
$output .= theme('pager', '', $view->pager_limit, $view->use_pager - 1);
}
if ($output) {
return $output;
}
}
I'm assuming you've read
I'm assuming you've read about theming in Drupal, and theming views specifically.
What I often do is grab the code output by the views theme wizard, and then change the name to be more generic so that I can run a bunch of other views through it. Then I add some arguments to the function so that I can assign a class to the list. Notice the $attributes argument that then gets passed to the theme('item_list') function.
My generic function:
One of the major differences with this function from the standard one is that I have to grab the template file name from the view name, which is the first thing I do, and then pass that into _phptemplate_callback.
<?php
/**
*re-write of theme function to insert a class or id into the <ul>
*/
function phptemplate_views_view_ul_list_with_class($view, $nodes, $type, $attributes = array()) {
$template = 'views-list-'.$view->name;
$fields = _views_get_fields();
$taken = array();
// Set up the fields in nicely named chunks.
foreach ($view->field as $id => $field) {
$field_name = $field['field'];
if (isset($taken[$field_name])) {
$field_name = $field['queryname'];
}
$taken[$field_name] = true;
$field_names[$id] = $field_name;
}
// Set up some variables that won't change.
$base_vars = array(
'view' => $view,
'view_type' => $type,
);
foreach ($nodes as $i => $node) {
$vars = $base_vars;
$vars['node'] = $node;
$vars['count'] = $i;
$vars['stripe'] = $i % 2 ? 'even' : 'odd';
foreach ($view->field as $id => $field) {
$name = $field_names[$id];
$vars[$name] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
if (isset($field['label'])) {
$vars[$name . '_label'] = $field['label'];
}
}
$items[] = _phptemplate_callback($template, $vars);
}
if ($items) {
return theme('item_list', $items, NULL, 'ul', $attributes);
}
}
?>
Then I place the correct function name in the template file and with that call my generic function, pass in the normal views arguments, and pass in the class and id for the ul:
<?php/**
*the following views need to have classes in the <li> elements
*/
function phptemplate_views_view_list_titles_by_term_publications($view, $nodes, $type) {
return phptemplate_views_view_ul_list_items_with_class($view, $nodes, $type, array('class' => 'brieflist', 'id' => 'by-term-publications'));
}
?>
You could extend this to passing in a class to the li as well, check out theme_item_list: http://api.drupal.org/api/function/theme_item_list/5 on how the lists are built.
Setting the class of the li could be set in the former function. You can run through the nodes to see what content type the node is, or whatever (get friendly with print_r($nodes) to see what data is available), and then add a variable to the item array like this:
<?phpforeach ($view->field as $id => $field) {
$name = $field_names[$id];
$vars[$name] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
if (isset($field['label'])) {
$vars[$name . '_label'] = $field['label'];
}
}
$items[]= array(
'data' => _phptemplate_callback($template, $vars),
'class' => views_css_safe($node->type),
);
?>
Whether removing divs or adding classes its usually possible through the theme functions.
can't i just change a css file?
I assume that a div class calls css styles from some css file. I am not a coder but can see from the code above that there aren't any styles being applied (e.g., padding, margins, text-indent, etc.). So ...
I am thinking, if I can just find the css file that this code uses, I can adjust the indent being applied to the header block. I think I have changed every applicable style in the theme's css file but to no success.
What am I missing? Where is the style that causes the header block in the views display to indent?
thanks
... never mind, found the table margin style -- finally. thanks anyway
subscribe
subscribe
content div comes from block.module
Thanks for this great thread! I pinpointed the location of the content div in my own instance of this problem -- it shows up when the block that I'm using to display the view gets themed. Just override theme_block() from the block.module file.
Copy that function into your template.php file, rename it phptemplate_block() or yourtheme_block(), and get rid of those divs!
I'll add a vote of confidence that EVERY div Earl included in the views module has a purpose. It's just awful for those of us who want clean, semantic code.
actually - it's in block.tpl.php
Both Zen and Garland wrap block content in extra divs, particularly the class="content" div.
I'm running the zen theme, and theme_block() doesn't seem to affect anything. The divs surrounding my views block all come from the block.tpl.php file. If you want to fix it, copy block.tpl.php into your theme directory, and get rid of those divs.
To sneak an id and a class for ajax past all the divs...
I randomly lifted some code from one of the examples, and this worked for me. I confess to not understanding it, so use at own risk.
I only wanted to make the change for one specific view, not all of them as the other code samples here seem to.
1. Create a theme for your view by going to admin/build/views/wizard (I've only done this using a list view with one field, FYI)
2. Add the bit to your template.php and create the views-list-view_name.tpl.php file as directed.
3. In the template.php bit, replace this code:
return theme('item_list', $items);With this:
return theme('item_list', $items, NULL, 'ul id="myid" class="myclass"', $attributes);That will get your class and id up close to the view results.
4. If you want to strip down the divs around the results too, you can replace this code in your views-list-view_name.tpl.php template:
<div class="view-label view-field-nid"><?php print $nid_label ?>
</div>
<div class="view-field view-data-nid">
<?php print $nid?>
</div>
With this:
<?php print $nid?>If your view has one field that is a thumbnail image as a link (like mine did), that gets you something like:
<ul class="myclass" id="myid"><li><a href="/path/image1"><img src="img1.jpg" [...]></a></li>
<li><a href="/path/image2"><img src="img2.jpg" [...]></a></li>
<li><a href="/path/image3"><img src="img3.jpg" [...]></a></li>
...
</ul>
Hope that helps!
Update: Upon taking a closer look, it appears that the closing ul actually contains the class and id as well. Not the end of the world, but:
</ul class="myclass" id="myid">I tried this approach but I
I tried this approach but I keep getting an error that PHPTemplate can't find a valid template file...see below
<div class="view-content view-content-Members"><div class="item-list">
<ul class="myclass" id="myid">
<li>
<!-- PHPTemplate was instructed to override the views-list-Members theme function, but no valid template file was found. -->
</li>
<li>
<!-- PHPTemplate was instructed to override the views-list-Members theme function, but no valid template file was found. -->
</li>
<li>
<!-- PHPTemplate was instructed to override the views-list-Members theme function, but no valid template file was found. -->
</li>
</ul>
</div>
</div>
can anyone throw any light on this for me?
Clear cache
If you are adding a new function to your template.php that overrides an old function you will need to clear the cache first ...
Use strip_tags in php
To remove all
<div>tags, but leave the<li> and <a>tags, you can write something like this in the template file (page.tpl.php or page-front.tpl.php):<?php
$block = module_invoke('views', 'block', 'view', 'front_slide_links');
$theblock = strip_tags($block['content'], '<li><a>');
print $theblock;
?>
Details on strip_tags is here: http://us.php.net/strip-tags
Anybody fix it?
I've tried to use all functions listed here, but result is not good. The annoying nested divs removed out from the the list items, but still surrounded ul. Please, help.
To get rid of the containing
To get rid of the containing ul and li items, I replace this in template.php:
<?phpif ($items) {
return theme('item_list', $items, NULL, 'ul', $attributes);
}
?>
With this:
<?phpif ($items) {
return implode("",$items);
}
?>
did anything changed with 6?
hello
has someone experiences with the new views for drupal 6? did something change?
i wrote this post: http://drupal.org/node/266737
and as a designer i have to say: i don't understand the guidelines here - all this overhead stuff - nobody who is a little bit comfortable with css needs all this classes and surrounding divs - you get really trashy html for the simplest sites. this isn't professional ...
greetings momper