Theming a CCK node

sivaji's picture

In this blog post i would like to cover a bit about Theming a CCK node. CCK the Content Construction Kit is a drupal contrib module, provides features to extend the fields of drupal nodes.

My goal is to create a product listing directory using CCK / Views and to theme the node similar to the wireframe shown below. I assume the readers are familiar with creating CCK node and page views to list it.

listing-wireframe.png

To proceed with this i am going to use a node type called listing and turquoise theme created by us.

The fields of the listing nodes are as below

  • Product Name - Node Title
  • Description - Node body
  • Product image - CCK Image field
  • Company Name - CCK Text Field
  • Company Address - CCK Location Field (includes phone and fax)
  • Website - CCK Link Field
  • Email - CCK E-mail Field

I have created a sample listing type node whose default theme looks as below
before-theme.png

Fields title and its values appears on below the other. My interest is to have it something similar to the wireframe above.

To override the default node theme we need to create a node-[type].tpl.php where type is machine name of node type. In our case it is "listing" so lets create a node-listing.tpl.php by duplicating node.tpl.php

$content is the variable which holds the HTML of the region (displayed within a box in above image) that we need to theme.

Now we need to replace $content with our own code which will renders the node as per our wireframe. To proceed with this we need two helper module here devel and contemplate.

contemplate module will help us to find the code that need to be replaced instead of $content and devel to find the variables which prints the HTML of individual fields.

Install devel and contemplate module. Navigate to admin/content/node-type/listing/template path. The HTML obtained from Contemplate module corresponding to full view of Listing node is as follow

<div class="field field-type-filefield field-field-listing-product-image">
  <h3 class="field-label">Product Image</h3>
  <div class="field-items">
      <div class="field-item"><?php print $node->field_listing_product_image[0]['view'] ?></div>
  </div>
</div>

<div class="field field-type-text field-field-listing-company-name">
  <h3 class="field-label">Company Name</h3>
  <div class="field-items">
      <div class="field-item"><?php print $node->field_listing_company_name[0]['view'] ?></div>
  </div>
</div>

<div class="field field-type-link field-field-listing-website">
  <h3 class="field-label">Website</h3>
  <div class="field-items">
      <div class="field-item"><?php print $node->field_listing_website[0]['view'] ?></div>
  </div>
</div>

<div class="field field-type-email field-field-listing-email">
  <h3 class="field-label">E-mail</h3>
  <div class="field-items">
      <div class="field-item"><?php print $node->field_listing_email[0]['view'] ?></div>
  </div>
</div>

<div class="field field-type-location field-field-listing-company-address">
  <h3 class="field-label">Address</h3>
  <div class="field-items">
      <div class="field-item"><?php print $node->field_listing_company_address[0]['view'] ?></div>
  </div>
</div>

Replace the above code in the place of $content i.e the above HTML should go under <div class="content"> tag

We need to make two changes in the above code

  • All the Literals in drupal need to be passed through the t() function. So make sure the field titles like website, E-mail etc. is passed through t() function.
  • In the above code Description field which is a node body is missing, add it below "Product Image".
  •   <div class="field field-type-textarea field-field-listing-description">
          <h3 class="field-label"><?php print t('Description') ?></h3>
          <div class="field-items">
              <div class="field-item"><?php print $node->content['body']['#value'] ?></div>
          </div>
        </div>

    Now we have HTML file which renders the node we can decide the order in the node elements to be rendered. And using CSS we can control the height, width and position of individual elements. Now we need to create a new CSS file say node-listing.css. The CSS file need to be loaded whenever a listing type node is displayed.

    To do this we need to add drupal_add_css() function on the top of node theme file node-listing.tpl.php.

    drupal_add_css(drupal_get_path('theme', 'turquoise') . '/node-listing.css');

    Here the final code that replaces $content

        <div class="field-image-description">
          <div class="field field-type-filefield field-field-listing-product-image">
            <h3 class="field-label"><?php print t('Product Image') ?></h3>
            <div class="field-items"><?php print $node->field_listing_product_image[0]['view'] ?></div>
          </div>
          <div class="field field-type-textarea field-field-listing-description">
            <h3 class="field-label"><?php print t('Description') ?></h3>
            <div class="field-items"><?php print $node->content['body']['#value'] ?></div>
          </div>
        </div> <!-- end field-image-description -->
        <div class="field-address-contact">
          <div class="field-address">
            <div class="field field-type-text field-field-listing-company-name">
              <h3 class="field-label"><?php print t('Company Name') ?></h3>
              <div class="field-items"><?php print $node->field_listing_company_name[0]['view'] ?></div>
            </div>
            <div class="field field-type-location field-field-listing-company-address">
              <h3 class="field-label"><?php print t('Address') ?></h3>
              <div class="field-items"><?php print $node->field_listing_company_address[0]['view'] ?></div>
            </div>
          </div> <!-- field address -->
          <div class="field-contact">
            <div class="field field-type-link field-field-listing-website">
              <h3 class="field-label"><?php print t('Website') ?></h3>
              <div class="field-items"><?php print $node->field_listing_website[0]['view'] ?></div>
            </div>
            <div class="field field-type-email field-field-listing-email">
              <h3 class="field-label"><?php print t('E-mail') ?></h3>
              <div class="field-items"><?php print $node->field_listing_email[0]['view'] ?></div>
            </div>
            <div class="field field-type-email field-field-listing-phone">
              <h3 class="field-label"><?php print t('Phone') ?></h3>
              <div class="field-items"><?php print $node->field_listing_company_address[0]['phone'] ?></div>
            </div>
            <div class="field field-type-email field-field-listing-fax">
              <h3 class="field-label"><?php print t('Fax') ?></h3>
              <div class="field-items"><?php print $node->field_listing_company_address[0]['fax'] ?></div>
            </div>
          </div> <!--end field-contact -->
        </div> <!-- end field-address-contact -->

    and the CSS file node-listing.css

    .field-image-description,
    .field-address-contact {
      overflow: hidden;
    }

    .field-address {
      float: left;
    }

    .field-field-listing-product-image {
      float: left;
      padding-right: 24px;
    }

    .field-contact {
      float: right;
    }

    Here the final output of the themed node.

    after-theme.png

    WoW !! This looks pretty Good !!

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
Image CAPTCHA
Enter the characters shown in the image.