New Podcast

Posted Tuesday, July 27 at 2:29 pm

Ryan Price and Mike Anello recently talked with Jacob Redding (jredding), author of Beginning Drupal as well Treasurer and Interim General Manager of the Drupal Association.

Download Podcast 41
DrupalEasy_ep41_20100727.mp3
Syndicate content

NEWSLETTER

Stay informed on our latest news!

Syndicate content

Testimonial

On March 11th I attended the first DrupalEasy Workshop in Orlando, Florida. I'm an experienced web developer who has recently picked up Drupal as a tool for helping to build high quality content-driven websites. Mike and Ryan were excellent teachers - they gave a thorough overview of a complex topic in a short space of time, and provided plenty of resources for us to continue learning. The workshop is essential for anyone who has previously configured a basic Drupal site and wishes to take their skills to an advanced level. I would not hesitate to recommend DrupalEasy.com training and hope to attend more workshops in the future.

Who are we?

DrupalEasy is the collective expertise of Ryan Price and Michael Anello, who joined forces to provide training and consulting services worldwide. Read all about them and what they can do.

What is Drupal?

Drupal is a free, super-powerful content management system for sites that require information posting and collection, including blogs, forums, videos, photos, and databases of information. We think it is the best platform available. Here's why...

Why Drupal?

More and more savvy organizations are going with Drupal for content management, and its no mystery why. It’s free, flexible, and easy to maintain for small or large volume sites. Learn more...

Theming Nodereference - or - Reusing Complex Data in Drupal

No votes yet

This is your moment, you've decided to step up and make a job board for your local Drupal User Group. You spend some time thinking about everything you'll need, including the job listings themselves. You'll want to gather the standard info, like job title and job description, salary, experience, the works. When it comes to gathering company info, your instincts make you take a few extra moments to plan.

If you think about this from the perspective of the person posting 6 or 7 jobs, she would end up having to type (or at least copy and paste) the business' contact information each time. If you think about collecting 3 or 4 fields for each business, then that's about 20 extra form fields for the user to fill out. If she then decides to change the info, let's say she made a typo, she now must click through each edit screen 6 or 7 times. That amounts to hundreds of clicks and several hundred repeated keystrokes.

job content type with company info baked in

There must be a better way. A nodereference can help your users.

Once finished, you will have two nodes, one for a job and another for a company, and yet you will still display the information about the company inside the job listing.

final themed job listing

By the end of this tutorial, you should understand what a nodereference is for, how to create and use one, and finally, how to use template files to theme the output of the nodereference and get the most out of the relationship.

What's a Nodereference?

Nodereference comes bundled with the Content Construction Kit, or CCK. A nodereference lets you keep a collected set of reusable data inside a Drupal node, and then "reference" that node in interesting ways. In this case, a job posting will reference a company. Other examples could be a conference session referencing a meeting room, a house referencing a neighborhood, or a boy's profile referencing his mother (and she has a mother, so we can find out the grandmother too). Several contributed modules can use the relationship created by a CCK nodereference in interesting ways, as you will see later.

On top of saving your users' time, a nodereference will also help keep your data clean from a computer science perspective. In CS classes they talk an awful lot about database normalization: in brief, you don't want to keep multiple copies of the same piece of data around; normalization is good for users and computers. One way to introduce database normalization in a Drupal site is by using a nodereference.

Set up both content types first

To get the Job/Company relationship set up, you will need to create both types from the Admin > Content > Content Types screen, starting with the company type. Name the new type Company, replace Title with Company Name, and replace Body with About this Company. Now click on Manage Fields next to the newly created Company type, and add a file field with an image widget for the company logo.

company content type's fields

Next return to Admin > Content > Content Types and create the Job Listing type, replacing Title with Job Title, and Body with Job Description. Add an Integer field for the Salary and a text area for the Required Experience, now get ready to make a decision:

When adding a nodereference, you need to decide on the widget used during node creation. You can change your mind later, but normally each situation will call for a certain widget:

Select list
if you don't have too many nodes to choose from, this can be a great choice; the user can see all of her choices at once and make a decision on which node to reference;
Check boxes/radio buttons
if you need to refer to multiple nodes at once, checkboxes can help; and/or if the list of possibilities is even smaller than needed for a select list (5 to 9 at most), then radio buttons may be your choice;
Autocomplete
this widget works very similar to a freetagging taxonomy selector or the Authored by: field at the bottom of a node form; you start typing, and Drupal will display a list of node titles that match the text you entered; you often only need to type a few letters to find exactly what you need, however, this requires the user to have some idea of what she is looking for; you also have the option to choose whether to search inside the node's titles, or only at the beginning;

In this case, the user entering a job listing will know the name of her company, so an Autocomplete widget should work just fine for you.
create the company nodereference field
Another selection you need to make is the kind of node you want your field to reference. Since this field is just to draw a relationship between a job listing and company, choose the Company checkbox. Now when your user types in the autocomplete field, she will only see names of companies that match, not every node on the site.
limit the nodereference to companies
At this point your job listing content type should have fields for Salary, Experience, and Company, all ready for input.
fields for the job listing type
Now go ahead and add some test content — make sure you add at least one company before you add a job, to get the full effect. When you get to the Company autocomplete field, you should see one or more choices appear as you type.
Drupal's autocomplete widget
And that's it! Your job listing now lists all the company info AND the job-specific information... oh, no it doesn't! All it shows is a link to the company node, that's no fun!
the unfinished job listing
The very quickest way to solve this problem is by visiting Admin > Content > Content Types > Job Listing > Display Fields. Here you will see a list of all the fields added by CCK, with columns for Label, Teaser, and Full Node. Don't worry about the Exclude checkboxes, but also don't check them unless you know what you're doing.

Your goal here is to get the company logo and description to appear on the job listing page, so under Full Node for the Company field, choose Teaser.
display fields for the job listing
OK, so now you should be good to go, right? Go take a look at your Job listing node now... Ouch! There are now 2 "submitted" strings, and 2 sets of links that say Add a comment. Will it be back to the drawing board? No, it's just time to create a theme file.
displaying the teaser for company in the job listing

Creating a Template File to Theme the Teaser

In Drupal you can apply a different template file in several different situations simply by using the proper file name. In this case, you want to change what is happening to Company nodes only when they are displayed as a teaser, like when the teaser is shown on the job listing. You can do a lot with the Display Fields, but you won't be able to get rid of the links for the company (Add a comment, 4 views) without a small bit of code. The key distinction here is that you may want the submitted string and the links on the full node, so in order to make a special case for the teaser, you need to create a template file.

In the file system, (that is, in FTP or on your hard drive) navigate to your theme's folder under the sites/all/themes directory. In the theme's folder, you should see a node.tpl.php file. Copy this file and name the copy node-company.tpl.php. How do you know what to name these files? There is a page on the Drupal Handbook about naming templates.
node-[type].tpl.php

If you're using a theme that has sub-themes, the process is almost identical. You simply may need to copy the node.tpl.php from another folder.

If you open up the file, you'll see a line of code checking for the teaser:
if ($page == 0):

When a node is displayed on its own page (like node/17), the value of $page
will be 1. When a node is displayed as a teaser, the value of $page will be 0. You
can now use this knowledge to change the behavior of Company nodes' teasers.

Locate the following conditional:
if ($submitted):
Now add some logic to check for teaser:
if ($submitted && ($page != 0)):
In this case you don't want the $submitted string to appear on teasers.

Apply the same logic for links:
if ($links):
After you add the extra logic:
if ($links && ($page != 0)):

Also, make a quick visit to Admin > Content > Content Types > Company > Display Fields and change the Label for Company Logo to <Hidden>. You may also want the logo to link back to the company node, so under Teaser, select Image linked to node if you like.

Now, take a look at the final product! See how it shines? You've saved your users time and wasted effort, normalized your database, and didn't make any compromises.
final themed job listing

Now go and read Mike's article about Nodereference and Views to make some more amazing stuff.

Clearing the Theme Registry

If for some reason you don't see your changes to the template immediately, don't blame yourself. The theme registry may be at fault. As part of Drupal 6's caching an performance scheme (i.e. to keep the site fast and responsive), Drupal will not always scan for new template files and functions on every single page load. During theming, this can sometimes mean that changes do not appear immediately, so just make sure to clear the theme registry after adding a new theme function or template file. Please try one of the following before you bang your head against the keyboard:

  1. On the Administer > Site configuration > Performance page, click the "Clear cached data" button.
  2. If you have Admin Menu module installed, under the icon in the top left, choose Flush all caches > Theme registry.
  3. With devel block enabled (comes with Devel module), click the "Empty cache" link.
  4. The API function drupal_rebuild_theme_registry.

Trackback URL for this post:

http://drupaleasy.com/trackback/192

1 comment

Paul Matthews wrote 24 weeks 8 hours ago

Nice post, helped me

4

Nice post, helped me understand noderefs. Cheers!

Add your comment

The content of this field is kept private and will not be shown publicly.
 
Syndicate content