As I struggle to theme my first view with Drupal 6 and Views 2, I’m seriously missing the old Theme Wizard :( I’ve read in these forums that Views 2 no longer needs a Theme Wizard, because theming in Drupal 6 makes everything ridiculously simple. But the Theme Developer doesn’t write plug-and-play Views templates, which is exactly what the Theme Wizard did.

I started with the following template, views-view-fields--tischlerkurs.tpl.php:

<?php foreach ($fields as $id => $field): ?>
<?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; ?>

<span class="field-content"><?php print $field->content; ?></span>
  </<?php print $field->inline_html;?>>
<?php endforeach; ?>

As a designer, I find the above template too inaccessible, so I started to make the template more designer friendly and Theme Wizardish. I now have something similar to the following:

<div class="MyDiv1">
<?php print $row->node_data_field_kurs_beschreibung_field_kurs_bild_value; ?>
</div>

<div class="MyDiv2">
<span class="MyLabel">Label 1</span>
<?php print $row->node_data_field_kurs_beschreibung_field_kurs_von1_a1_value; ?>
</div>

<div class="MyDiv3">
<span class="MyLabel">Label 2</span>
<?php print $row->node_data_field_kurs_beschreibung_field_kurs_bis1_a1_value; ?>
</div>

As you can see, the above template is simply a matter of pluging in desired fields and adding whatever additional styles and content I choose. However I now have a problem with the output. Apparently $row only outputs the raw result object from the query. So instead of my date fields displaying “Thursday, 11. December 2008 “ , I end up with this “2008-12-11T00:00:00 “.

Can someone please explain to me how I can best achieve a plug-and-play template with processed output? Thank you for your time.

Comments

merlinofchaos’s picture

Status: Active » Closed (works as designed)

Yea, use the $field array instead of the $row array. Why is this hard? Isn't it freakin' obvious? Also, read the advanced help; there's a doc in there that tells you what to do.

C'mon, people. This isn't freakin' rocket science.

Keeling’s picture

I read the advanced help and I searched the forums to no avail. And although I’m not a rocket scientist, I consider myself to be an intelligent person :) Furthermore if I found the answers to be “freakin’ obvious” I would never have posted the questions to begin with.

That being said, I assumed that when you say use the $field array instead of the $row array that my template should not contain this:

<?php print $row->node_data_field_kurs_beschreibung_field_kurs_bis1_a1_value; ?>

…but rather this:

<?php print $field->node_data_field_kurs_beschreibung_field_kurs_bis1_a1_value; ?>

But this returns no result at all, and that freakin’ sucks.

merlinofchaos’s picture

Sigh. No, the keys in the $row object are not the keys in the $field array. I'm sorry, but if that's not obvious to you, then you have a whole lot to learn about templating and variables. Especially since you even figured out what the keys in the $row array are, it should have been safe to assume you can use that same methodology to figure out the keys in the $field array.

Let's walk through this and look at the original code you posted. Since we know this works, this is the place to start.

<?php foreach ($fields as $id => $field): ?>

Hey look, it's the $fields array.

Now let's look at some of the code that it's using:

<label class="views-label-<?php print $field->class; ?>">
  <?php print $field->label; ?>:
</label>

Ok, so we know that $field->label is the label for that particular field.

<span class="field-content"><?php print $field->content; ?></span>
  </<?php print $field->inline_html;?>>
<?php endforeach; ?>

And we now know that $field->content is probably the main content for the field.

Well, actually, we know all this because we can read the documentation that's in the template:

 * - $fields: an array of $field objects. Each one contains:
 *   - $field->content: The output of the field.
 *   - $field->raw: The raw data for the field, if it exists. This is NOT output safe.
 *   - $field->class: The safe class id to use.
 *   - $field->handler: The Views field handler object controlling this field. Do not use
 *     var_export to dump this object, as it can't handle the recursion.
 *   - $field->inline: Whether or not the field should be inline.
 *   - $field->inline_html: either div or span based on the above flag.
 *   - $field->separator: an optional separator that may appear before a field.
 * - $row: The raw result object from the query, with all data it fetched.

Hey, look at that! $row: The raw result object from the query, with all data it fetched.. Raw data. So, what you got out of the $row array was documented, right there in the template.

What's missing? The ids. Here, let me pull from another part of the documentation:

The IDs used to fetch items from the array, id $row['title'] can be quickly and easily looked up on the Theme: Information page. Once a field has been added to the view, its ID will not change, but note that if there are two "title" fields in a view, one will be 'title' and the other will be 'title1', in order to prevent namespace collisions.

Now, probably what's messing you up here is that the example I used is for a different template; that template is actually putting items in the $row array and not $fields because it needs a different data structure. Now, that shouldn't have been a problem, because the data each template uses is clearly documented at the top of each template. So instead, you have to look into the $fields array.

Now, this is the part where I'll admit things get annoying. The documentation suggests using drupal_set_message, but you can't use drupal_set_message with the $fields array because it has the handlers in it and that causes a giant recursive mess that drupal_set_message can't quite deal with. Luckily, the above quote offered an alternative method. Let's go look at the theme: information page.

Field Node: Title (ID: title): views-view-field.tpl.php, views-view-field--fugazi--title.tpl.php, views-view-field--page.tpl.php, views-view-field--page--title.tpl.php, views-view-field--fugazi--page.tpl.php, views-view-field--fugazi--page--title.tpl.php, views-view-field--page-1.tpl.php, views-view-field--page-1--title.tpl.php, views-view-field--fugazi--page-1.tpl.php, views-view-field--fugazi--page-1--title.tpl.php

Note that the ID for that field is clearly marked for you. In the case of this field, it's "title". So if you happen to have this field in your setup, you can confidently assume that the data you need is in:

$fields['title']->content

Now, all of that *is* documented. I only required a LITTLE bit of patience, reading, and a little grasping at the data.

As near as I can tell, all you did is look in the $rows array, you ignored the documentation IN THE VERY TEMPLATE that you're messing with, and you come here posting issues.

I have now spent half an hour of my time explaining Was it worth it? To me, no. That's half an hour lost. To you? Probably not, you're just going to be pissed off at me for being a condescending jackass. I admit it, I am being one, because I'm angry that I spent hours and hours making sure everything is documented, and you claim to have read it all carefully, yet missed really important bits that are right in front of you when doing this stuff. So please don't be surprised that this makes me angry. You made this much harder for yourself than it had to be.

merlinofchaos’s picture

And since I know this will keep coming up, here's the documentation I distilled out of this that has been added to Using templates document in CVS:

The basic fields template

The most common template people will need to rewrite is the "simple" views-view-fields.tpl.php, which is the template used by the Fields row style and all it does is display a simple list of fields. However, it is not that simple to the user. Because the template can't inherently know what the fields are, it has to go through an array in a loop.

This loop isn't very handy when you really want to have fine control over the template by placing your fields precisely where and how you want. Relax, though; if you know what your fields are, you can rewrite this. If you end up writing your own HTML, the only part that is really important is the content for each field. We know from above that you can get the ID for each field on the Theme: Information page from the view. In the header for the template, we can see that the fields are all in the $fields array, and each field is an object. That leads us to this:

<php print $fields['some_id']->content; ?>

Assuming you replace some_id with an id found on the theme: information page, this code will print the content for that field. You can also get the label and some other data about the field, as well as the raw information. Complete details for what is available are documented directly in views-view-fields.tpl.php.

Keep in mind that if you rewrite your templates using this, you'll need to maintain this template whenever changes are made to the fields of the view; while this isn't generally recommend, sometimes it's necessary to get the kind of control you might ultimately need.

Keeling’s picture

Thanks Merlin of Chaos. You’re the freakin’ man!

I actually find your detailed, condescending jackass response not only very helpful but also entertaining. Maybe if you would use this tone in all of your documentation, then I would better understand this module :) Thanks again.

C'mon, people. This isn't freakin' rocket science.
- merlinofchaos

summit’s picture

Bookmarking, and he can write also :):)
greetings, Martijn

ccmd00d’s picture

bookmarking

drew-2’s picture

Thank you merlinofchaos and Keeling - I found the above useful!

I can access an image field as $fields['field_photo_fid']->content. However, that prints the image with the built in defaults - what I want is to have finer control where I can for example, manipulate the image size.

How do I access the image source, so that I am able to write my own html?

Thanks in advance :-)

merlinofchaos’s picture

Unfortunately accessing the source data of a given field varies from field to field and the only way to answer that will be to study the handler, particularly for things like images where data isn't merely being pulled from a field.

rokr’s picture

Just want to say thank you for #3, merlinofchaos!

cheers, Ronald