Theming a Specific Content Type

Let's start by taking a look at the content type that was defined by CCKContent Construction Kit - a Drupal module that allows you to create new content types.

In this picture we see "Name" and "Type"; notice what it says underneath those fields:

  • Name - "The human-readable name of this content type."
  • Type - "The machine-readable name of this content type."

In order to set up the themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look., we need the "Type."

We also need to make note of what we called the "body" field. In this case, it's called "Description."

When we go to "Manage fields" we see this display. The "Name" column is what we need. However, there is one lie here: there is no field called "body filter." This is an unfortunate display of an internal form technique.

Okay, now we have the information we need to start the themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look. for this content type.

In your favorite text editor, start a new file. It's going to contain both HTMLHyperText Markup Language - the coding standard for a web page. and PHPRecursive acronym for "PHP: Hypertext Preprocessor" - is a widely-used Open Source general-purpose scripting language that is especially suited for Web development and can be embedded into HTML.. And let's start with some basic stuff that will allow us to apply CSSCascading Style Sheet - a hierarchical means of specifying how to format HTML elements on the page later if we need to.

<div class="content agency">
</div>
<div class="clear-block clear"></div>

What this does is say "Here comes the content for this node and it is also known as 'agency.'" I chose to use the "machine readable" content identifier, however you may call it anything you like. "Content" is a Drupal

Drupal

An open-source content management system that is used on this site and is taking over the world. standard, so you really want to keep that. The second line will just end that division. The third line is not always necessary, but since our content has pictures that may vary in size, it's a good idea to force the browser to return to "ground zero."

Well, I suppose now you want some actual content to show up? Picky, picky.

This content has a picture with it, and a CCKContent Construction Kit - a Drupal module that allows you to create new content types "Image" field uses the ImageCache moduleAn add-on, or extension, to Drupal to provide additional functionality; written in PHP.. We'd like to put the picture up high and on the left. As a matter of fact, it might be nice if even the company name (title) was even with the top of the picture and to the right of it as opposed to above it. This is not a problem, but does tell us that it should be the first thing we want to display.

We are now inserting stuff after the first <div> tag above.

The ImageCache moduleAn add-on, or extension, to Drupal to provide additional functionality; written in PHP. provides a theming function that can be pretty handy, so let's use it.

[BTW, the 'echo' function is slightly faster than the 'print' function so I use it even though most themers seem stuck on 'print.' Either will work.]

<?php echo theme('imagecache', 'thumbnail', $node->field_logo[0]['filepath'], $node->title, $node->title, array('align' => 'left', 'hspace' => '10')); ?>

What we've asked for here is to use the display setting called "thumbnail" (use what ever you call yours) to set the size. I'll explain the data field ("$node->field_logo[0]['filepath']") in a moment. The next two "$node->title" parameters say to use the company name for both the "alt" and "title" attributes. And finally, we have an array that tells ImageCache to add the attributes 'align="left"' and 'hspace="10"' to the IMG tag.

Okay, now that we have the picture inserted, it's time for the title. It is fairly standard Drupal

Drupal

An open-source content management system that is used on this site and is taking over the world. practice to use the <h2> tag for this. It is entirely up to you, but that's what I will use here.

The entire node object is available to us in the themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look. and it is called, by Drupal

Drupal

An open-source content management system that is used on this site and is taking over the world. standards, "$node." Within the node object the title (in our case, the company name) is called, strangely enough, "title." It is therefore referenced as "$node->title."

<h2><?php echo l($node->title, 'node/'. $node->nid, array('title' => t('View agency')));?></h2>

Another "standard" drupal

Drupal

An open-source content management system that is used on this site and is taking over the world. practice is to have the node title be a linkThe technique which points to another page, anywhere on the Internet, from the current page. to the node itself so that it can be viewed in its "raw" form or edited if you have the permission to do so. So I've used the "l" ("linkThe technique which points to another page, anywhere on the Internet, from the current page.") function. You can read more about this function here.

For my example here, I've created a table to format the data. You may do this, or use <div> tags to format it with CSSCascading Style Sheet - a hierarchical means of specifying how to format HTML elements on the page. Some themers like to use definition lists. You are free to use whatever constructs you want. Just be careful that you don't accidentally break your themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look..

In my example, I used the CCKContent Construction Kit - a Drupal module that allows you to create new content types_Address moduleAn add-on, or extension, to Drupal to provide additional functionality; written in PHP., so I'll explain how its fields are named, since they differ a bit from the other CCKContent Construction Kit - a Drupal module that allows you to create new content types types. The address moduleAn add-on, or extension, to Drupal to provide additional functionality; written in PHP. allows for multiple addresses; these are part of an array called "field_address" so the first (or only) address is zero (0), the second is one (1), and so on. This moduleAn add-on, or extension, to Drupal to provide additional functionality; written in PHP. provides several sub-fields whose labels don't necessarily match what is displayed on the entry/edit screen. The field that shows as "Address" is known internally as "street1;" "Address continued" is "street2;" and "Apt/suite number" is simply "apt."

I could not get these fields to use the content formatter ("content_format" function). I don't know if this is good or not, but it's working. More "normal" CCKContent Construction Kit - a Drupal module that allows you to create new content types fields have a safe "view" element available.

<tr><th>Address</th><td>
<?php
 
echo $node->field_address[0]['street1'];
  if (
$node->field_address[0]['apt']) { echo '; '. $node->field_address[0]['apt']; }
  if (
$node->field_address[0]['street2']) { echo '<br/>'. $node->field_address[0]['street2']; }
  echo
'<br/>'. $node->field_address[0]['city'] .', '. $node->field_address[0]['state'] .' '. $node->field_address[0]['zip'];
  if (
$node->field_address[0]['country'] != 'US') { echo '<br/><big>'. $node->field_address[0]['country'] .'</big>'; }
?>

</td></tr>

Notice that I used a little logic to suppress blank lines and to stick the city, state, and Zip code fields together (in US format). I also don't show "US" since I am in the USA and, knowing our postal workers, it would confuse them.

Now, except for the "body" (in our case "description") field, all the other data I have encountered so far is handled the same way. If you refer back to your "manage fields" display for the field names there are only a few more things to know.

A with the "address" above, CCKContent Construction Kit - a Drupal module that allows you to create new content types allows all fields to be single or multiple, so they are always part of an array with the name shown on the "manage" screen. For example, the telephone number is "field_agency_telephone" as we defined it. Also as above, the first element is numbered zero (0), the second is one (1), etc. In our case, we don't really allow multiples, but a simple "foreach" loop could be added to do so.

CCKContent Construction Kit - a Drupal module that allows you to create new content types provides a content formatter, but you don't need it. Each field array has a sub-field known as 'view' that is what the content formatter would produce, but it's already done for you. This is the "safe" way to display the data. An added bonus is that things like email addresses and hyperlinks are already properly formatted for you.

Putting this together, then, means that the "best" way to reference a field is "$field_name[0]['view']," where field_name is the name from the "manage" screen.

<tr><th>Phone</th><td><?php echo $node->field_phone[0]['view'];?></td></tr>
<tr><th>Email</th><td><?php echo $node->field_email[0]['view'];?></td></tr>
<tr><th>Web site</th><td><?php echo $node->field_website[0]['view'];?></td></tr>

Okay, almost done; only one more field to worry about: the "description" (or body) field. This one doesn't follow any scheme that I can fathom, so you have to just take it on faith. This field is referenced as "$node->content['body']['#value']". I've seen some posts that suggest that "$node->description" should work, but it doesn't for me.

So, let's put the whole example together, hopefully as I've described the process:

<div class="content agency">
<?php echo theme('imagecache', 'thumbnail', $node->field_logo[0]['filepath'], $node->title, $node->title, array('align' => 'left', 'hspace' => '10')); ?>
<h2><big><?php echo l($node->title, 'node/'. $node->nid, array('title' => t('View agency')));?></big></h2><br/>
<table border="2" cellpadding="5">
<tr><th>Address</th><td>
<?php
 
echo $node->field_address[0]['street1'];
  if (
$node->field_address[0]['apt']) { echo '; '. $node->field_address[0]['apt']; }
  if (
$node->field_address[0]['street2']) { echo '<br/>'. $node->field_address[0]['street2']; }
  echo
'<br/>'. $node->field_address[0]['city'] .', '. $node->field_address[0]['state'] .' '. $node->field_address[0]['zip'];
  if (
$node->field_address[0]['country'] != 'US') { echo '<br/><big>'. $node->field_address[0]['country'] .'</big>'; }
?>

</td></tr>
<tr><th>Phone</th><td><?php echo $node->field_phone[0]['view'];?></td></tr>
<tr><th>Email</th><td><?php echo $node->field_email[0]['view'];?></td></tr>
<tr><th>Web site</th><td><?php echo $node->field_website[0]['view'];?></td></tr>
</table>
<?php
 
if ($node->content['body']['#value']) {
      echo
'<p><big>'. $node->content['body']['#value'] .'</big></p>';
  }
?>

</div>
<div class="clear-block clear"></div>

While I initially developed this on the Bluemarine themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look., it worked without change on the Garland themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look., except I needed one small addition to my CSSCascading Style Sheet - a hierarchical means of specifying how to format HTML elements on the page: ".agency table {width: auto;}". This is because the Garland themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look. has the annoying habit of ignoring my "width" attributes and forcing 100%.

And Finally...

The time has come to save your work and see if it's right.

Save the file into your active themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look. folder as "node-content_type.tpl.phpRecursive acronym for "PHP: Hypertext Preprocessor" - is a widely-used Open Source general-purpose scripting language that is especially suited for Web development and can be embedded into HTML." where content_type is the internal content type name that you made note of in the first step.

Showing a List of the Nodes

The siteA logically grouped set of content - also web site. already had Views, so that allowed me to use that moduleAn add-on, or extension, to Drupal to provide additional functionality; written in PHP. to select the content type, although I think it's an overkill.

But the fields are already selected in the themeFor web sites, this refers to the "look and feel" of the site. It is also used to describe the code to produce that look., so what do I need to do in Views? Well, I found that all that's needed for a "teaser view" is to select any (one) field in the node, such as the title, and you will get the correctly themed node. You might also want to provide a sorting order, but that's not the point here.