Here is my situation:
MY doc type is xhtml strict

I have views that return a list of articles teasers in descending order.

Through the Template.php I have wrapped the Node Tile, which is incapsulated inside an achor link to the full node, inside an h2 tag So that I can have properly symatic code.

My problem is that Views encapsulate this inside a span tag like so:

<div class="views-field-title">
  <span class="field-content">
    <h2 class="pageTitle"><a href="/news/news-3.html">News 3</a></h2></span>
</div>

This does not validate as you cannot have have a block level element (h2) inside an in-line element (span).
How do I either:
(1) Change the span into a div?
or
(2) remove the span altogether?

I appreciate any insight into this matter and thank you for any assistance.

Comments

jmbuytaert’s picture

Ok, so you need to create a template specifically for that views field (views-view-fields--name-of-views-your-view.tpl.php) and then do a little bit of php that basically says:

<?php
if(substr($field->content, 0, 22)=='<h2 class="pageTitle">'){
	$field->content = str_replace('<h2 class="pageTitle">', '', $field->content);
	$field->content = str_replace('</h2>', '', $field->content);
?>
<h2 class="pageTitle"><span class="field-content"><?php print $field->content; ?></span></h2>
<?php } else { ?>
<<?php print $field->element_type; ?> class="field-content"><?php print $field_content; ?></<?php print $field->element_type; ?>><?php // see footnote ?>
<?php } ?>

That pretty much sees if your content that's being called ("News 3") has an <h2> in, and if so, it removes it (with your class name), as well as the ending </h2> tag, then properly re-writes the field with <h2> tags outside of the <span>s. You can also rewrite the line without the <span> tags, but that might mess up some of your code on other pages.

You're welcome TheresaB :)

footnote: this line is the original code in views-view-field.tpl.php
TheresaB’s picture

That is real good but not all my content comes in a H2 tag. I am sorry of I did not make that clear. I have other content that comes in divs, which again are block level elements. What I really need is a way to remove them altogether or change those spans into divs. Any ideas on this and would it cause problems?

Oh and it is views-view-fields.tpl.php copied from /sites/all/modules/views/theme/

TheresaB’s picture

In the Views online help it states in its chapter View row styles:

The fields row style displays each field defined in the view, one after another. Each field defines its own output.

By default, each field is put in a div unless it is selected to be inline. If it is inline, it is put in a span. Two items in divs will be displayed one after another, with the second one below the first. Two items in spans will be displayed on the same line. One item in a span next to divs is the same as two items in divs. This means that for the inline setting to do anything, at least two consecutive items must be set inline.

How do I define the field as block or inline for each field, or is there a way to over ride the display in Views or through coding?

TheresaB’s picture

While digging though the Drupal Themer Information I found an array called options with 2 elements

inline(Ararry, 0 elements)
separator(string, 0 characters)

Is this what is setting my fields to be considered inline and wrapping them in spans and if so how do I go about changing the value so that the fields are not considered inline elements so that I can have divs instead?

TheresaB’s picture

OK update:

It seems that somewhere Views has set the element type as span ($field->element_type;

So now I need to find where this is happening as I have set NO fields to inline in Views and when I double check they are NOT set as inline. Never were set that way either (I only found out you could while researching this problem).

Does anyone know where I can fine the code that is responsible for setting the element type for fields???

TheresaB’s picture

OK just found this and it looks like the problem may not be with Views at all but with CCK!
Look at the following code from /cck/includes/views/handlers/content_handler_field.inc
Yes, this is from the latest version of CCK 6.x-2.2

  /**
   * Return DIV or SPAN based upon the field's element type.
   */
  function element_type() {
    if (isset($this->definition['element type'])) {
      return $this->definition['element type'];
    }
    // TODO Figure out exactly when to return a div or a <span>. Any field
    // that ever needs to be shown inline in Views UI. It needs to return
    // a div for textareas to prevent wrapping a <span> around a <p>.
    // Earl says we need to be sure that other fields we don't know
    // about won't end up wrapping a span around a block-level element.
    if ($this->content_field['widget']['type'] == 'text_textarea') {
      return 'div';
    }
    else {
      return 'span';
    }
  }

It would appear that unless the content type is a textarea is is being inclosed inside of a <span> the comments also would appear to support this:

    // Earl says we need to be sure that other fields we don't know
    // about won't end up wrapping a span around a block-level element.

So now I am not sure how to proceed from here does anyone know how I can change this without touching the core files for CCK?

theusualsuspect’s picture

I have the same problem. My images are wrapped inside those spans and I can't see them in Safari anymore, unless I add another field.

@TheresaB. You spotted the problem right. Any solutions yet?

TheresaB’s picture

Sorry, so far I have had no luck and no response. I found an issue posted about this same problem in the CCK module issues and posted there in hopes to find an answer but so far no luck.

http://drupal.org/node/369364

You may wish to add a post as well as the squeaky wheel and all that. **grins**

TheresaB’s picture

Ok I have a solution that will work thanks to dogyboy and some others. You can read the whole thing in the CCK issue "field with multiple values, not marking itself properly as block level element for views integration?".

This will work as a fix and though I still would like to know more how the CCK assigns the element_type as it is a pain to to do that for all the views.

So that anyone coming behind will know what dogboy did and how to do it for their own site;

First copy views-view-fields.tpl.php from the Views module [views/theme/views-view-fields.tpl.php] into your theme folder.

change the name to views-view-fields--my_view_name.tpl.php and them look for the following line of code:

<<?php print $field->element_type; ?> class="field-content"><?php print $field_content; ?></<?php print $field->element_type; ?>>

Then to make it easy just highlight that line of code and copy the following code;

<?php
      // Set the fields in this view to be treated as blocks
        $my_element_type = 'div';
      ?>
      <<?php print $my_element_type; ?> class="field-content"><?php print $field->content; ?></<?php print $my_element_type; ?>>
      <!--<<?php //print $field->element_type; ?> class="field-content"><?php //print $field_content; ?></<?php //print $field->element_type; ?>>-->

You will see that I included the original line but commented it out so that at a later time, if a more eloqunet solution is found, it can be changed back easily.

armandv’s picture

After having to create several views-view-fields--some_view_name.tpl.php files within my theme, I came up with a more generic solution, by scanning the $field->content for div tags if the $field->element_type is 'span'. If found, I change the $field->element_type to 'div' so that I end up with proper xhtml strict.

I copied views-view-fields.tpl.php, and changed it like so:

<?php foreach ($fields as $id => $field): ?>
<?php 
if ( 'span' == $field->element_type && preg_match('/<div/', $field->content) ) 
{
        $field->element_type = 'div';
}
?>
  <?php if (!empty($field->separator)): ?>
    <?php print $field->separator; ?>
  <?php endif; ?>

  <<?php print $field->inline_html;?> class="views-field-<?php print $field->class; ?>">
    <?php if ($field->label): ?>
      <label class="views-label-<?php print $field->class; ?>">
        <?php print $field->label; ?>:
      </label>
    <?php endif; ?>
      <?php
      // $field->element_type is either SPAN or DIV depending upon whether or not
      // the field is a 'block' element type or 'inline' element type.
      ?>
      <<?php print $field->element_type; ?> class="field-content"><?php print $field->content; ?></<?php print $field->element_type; ?>>
  </<?php print $field->inline_html;?>>
<?php endforeach; ?>

this saves me from fixing this for every new view that presents me with this problem, at the expense of a preg_match() call for every time a field is being prepared for display.

sholn’s picture

Hi there,
is there any easy way to get out of my html all these useless span?
i tried to make every possible view but i can't remove the span that contains my field, i would only show my field!
Thanks a lot!

pamreed’s picture

Why are span add to everything? How does one get rid of all the span? There cause so much problem when trying theme a cck field in views.

bengt’s picture

It seems that we have to wait - or has anyone heard anything else? - for a more permanent solution. In the meantime I followed armandv's generic solution, but I made it a little bit more generic by changing the preg_match from '/<div/' to '/<h1|<h2|<h3|<h4|<div/' (you can of course have every kind of block-element here, if you want).

Bengt

wigle’s picture

A quick but dirty fix to this is to add a closing span tag at the beginning of your field output, and then add a beginning span at the end.

</span>your output here<span>

paulvantuyl’s picture

Ha! Genius. This worked for me.