Chapter 3. Job Posting Board

This chapter outlines the two most powerful features in Drupal. Yes, we’re saying outright that the two most powerful features are fields and views. The Field module (and its corresponding Field UI module, which provides an administrative interface) comes with core and allows you to customize existing entity forms in Drupal by adding a variety of fields—such as checkboxes, select lists, file uploads, and several others—all without writing a line of code. The Views module is the natural counterpart to Field, letting you get data out of your site rather than into it. Views allow you to create pages and blocks that pull data back out and display it to your visitors. Want a paged table showing product details that can be sorted by price or manufacturer? You can build it with Field and Views. Want to display a block that lists the fans of a particular artist in a grid as a set of user photo thumbnails? You can build it with Field and Views. Anywhere there’s a list of content on your website (and most websites are almost all just lists of content in one form or another), Field and Views are the two key modules you need.

The Field and Views modules form the foundation of nearly every other project in this book and most of the Drupal-powered websites on the Internet. We’ll cover how to set up a new content type and customize the node form so that you can add any type of field for inputting data. We’ll configure a site that allows the creation of job openings, and then we’ll build an interface for browsing though available jobs.

This chapter introduces the following modules:

Field (core)

Provides infrastructure to add fields to entities

Field UI (core)

Provides the user interface to add fields to entity forms

File (core)

Provides file upload fields

References

Provides User and Node reference fields

Views

Creates lists of entities, like content and users

If you would like to participate in the hands-on exercises in this chapter, you should install Drupal using the Chapter 3: Job posting board installation profile from the book’s sample code. Doing this will create the starter website on your web server, with some basic configuration. The completed website will look as pictured in Figure 3-1 and at http://jobs.usingdrupal.com. For more information on using the book’s sample code, see the Preface.

The completed Epic University site

Figure 3-1. The completed Epic University site

Case Study

Several students on work-study at Epic University have been tasked with building a job posting website for their school. The university needs to have the site built in a short amount of time (not to mention cheaply) on its internal servers. Because of its flexible entity and field system, user management, and low cost, the students chose to download Drupal and get started building a site.

The Human Resources department requires that university faculty be able to post job openings, which include a description, department, contact person, and salary information. Users should be able to sign into the site and view both a list of all available openings and lists of openings within a single, specific department. Additionally, users should be able to apply for a specific position, and to view a record of all positions to which they’ve applied.

Implementation Notes

Drupal core provides this site with a good starting point. It provides the user access requirements and allows the creation of several different types of content, such as “job” and “application” types. Drupal’s default settings give each one of these new types only a Title and Body field. We’ll need quite a few more fields so that users can enter more data, and so that we can pull out information from certain fields to make listings of content.

Custom input forms

At the heart of the requirements for this website, textual data will need to be inserted through a variety of forms. The Field module will provide the means for users to enter data into the site. Drupal core provides several different kinds of fields needed, like a drop-down select list for the university department, or simple text fields for phone numbers and addresses. Contributed modules, like References or “Address field”, give us additional fields that let us link content and users throughout the site.

File uploads

One thing we will need is the ability to upload files to the site so that applicants can include a résumé without having to type it all into a form. Drupal core’s File module exposes a field that can provide this functionality.

Listings

Besides entering data into the website, job applicants and employers will want to view lists of potential jobs and applicants. For nearly any purpose of displaying content, the Views module can provide a listing of content in a variety of ways: a table, a list of full nodes or teasers, an RSS feed, a list of individual fields, and more. We’ll build all the necessary lists for this chapter as views, including special views that can take a user ID or department and filter down to include only relevant content.

Spotlight: Field and Field UI

The Field module provides an extremely flexible framework for creating forms to enter content. The ability to add custom fields to forms is a new feature in core for Drupal 7. In Drupal 6, all of this functionality was provided by the Content Construction Kit (CCK) module. Most of CCK is now integrated into core, but there is still a contributed CCK module in Drupal 7. The main reason for this is to provide an upgrade path for Drupal 6’s CCK fields to Drupal 7’s core fields. Since we are not upgrading, but instead building a new Drupal 7 site, we won’t need CCK for this project.

Upon installing a new copy of Drupal, you’ll see two content types provided: “Article” and “Basic page.” They both have a Title and Body, which are the basic fields provided when you create a content type. Any additional content types that are created will also contain a Title field and (optionally) a Body field.

Using the Field and Field UI modules, pictured in Figure 3-2, you may add any number of custom fields to any content type. Combined with the ability to create custom content types, core lets you create completely customized forms for adding content. Figure 3-3 shows the “Basic page” form after we’ve added a few custom fields, such as an additional text field, an image field, and a set of radio buttons.

The Field UI module provides the ability to add fields to entities, including nodes, comments, and users

Figure 3-2. The Field UI module provides the ability to add fields to entities, including nodes, comments, and users

The “Basic page” content type form, after adding custom fields

Figure 3-3. The “Basic page” content type form, after adding custom fields

Another new feature in Drupal 7 is the ability to add fields to any entity in the system: users, comments, and taxonomy terms, with more options offered in contrib through the means of modules such as File Entity or Drupal Commerce. For example, it’s now possible to add tags to users, or attach an upload field to comments.

When it comes to actually using fields, it is important to understand the various pieces involved. There are three main concepts to cover: field types, widgets, and displays.

Field Types

The type of field you choose will determine how a user will save data into your site. The field type represents the type of data that needs to be saved, such as integer, decimal, or text. It is completely decoupled from what the user will ultimately fill out and be presented with. When you’re choosing a field to add to an entity, the first decision you need to make is what kind of data is being stored “behind the scenes” in the form. Will the information entered into the form be something basic like text or numbers, or something more special like a relationship to another node or user? The field types included in core are displayed in Table 3-1, along with how those fields are represented in the database. Other modules, such as Fivestar and Date, add more field types to use. Those modules are covered later in the book, in Chapters 5 and 6, respectively. You can find a full list of available field types in the Fields category from the Drupal.org module search page.

Table 3-1. Core field types

Field type

Common uses

Boolean

A basic on/off switch, stored in the database as either 0 or 1. This is often used for yes/no or true/false data.
DecimalAn efficient way of storing numbers to a certain decimal point. Useful for currency amounts.
File

For nonimage file uploads. Stores the filename and directory location of associated files.

Float

The most accurate way of storing numbers that need a high level of precision, such as scientific measurements.

Image

For image file uploads. Stores the relationship to the file information and metainformation about the image, such as alt text.

Integer

The most efficient way of storing a number. Use for product numbers and identifiers, or whenever you’ll have an exact number of something, like track numbers on an album or number of attendees at an event.

List (float)

Used for presenting a list of options, stored as floating numbers. For example, a user’s preferred version of π.

List (integer)

Used for presenting a list of options, stored as integers. Many lists, whether they’re presenting a list of colors or favorite animals, can choose this type for lookup efficiency.

List (text)

Used for presenting a list of options, stored as text. For example, a list of U.S. states that stores two-letter state abbreviations.

Long text

Used to store long strings of text, such as biographies, that require more than a sentence or so.

Long text and summary

Very similar to “Long text,” this stores long strings of text, along with a smaller version of that text. The default Body field on core content types uses this field type.

Term reference

Used for adding categories to entities. Stores the relationship to term entities and is used to associate vocabulary terms with content. This field will be covered in more detail in Spotlight: Taxonomy.

Text

Can store a string of text. This is intended for short bits of text, like names and descriptions.

Warning

Unlike other elements of a field, its field type cannot be changed. If you need to change the type of field from text to integer (or any other conversion), you’ll need to delete the field (along with its data!) and replace it with a new field with the desired type. Therefore, it pays to think about your choice up front.

Input Widgets

Once the type of data is determined, then it’s time to think about how it should look in the form. How will people enter the data you want? In Drupal lingo, form elements are called widgets. Do you want a drop-down select list, or a group of radio buttons? Checkboxes or an autocomplete text field? Choose the widget that makes the most sense for the user entering the data. Note that the widgets available will vary based on the field type chosen.

The widget types included in core, and to which field types they belong, are displayed in Table 3-2. Many of these widgets, such as “Select list” and “Text field,” will also apply to field types added by contributed modules, and contributed modules often expose additional widget choices as well.

Table 3-2. Core widget types

Widget type

Core field type(s)

Common uses

Autocomplete term widget (tagging)

Term reference

This provides a blank text field that will search for existing matching terms as the user types letters. A user can then select one of the existing terms, or he can enter a new term, which will then be added to the taxonomy vocabulary once the form is saved.

Checkboxes/Radio buttons

Boolean, List, Term referenceUse when there are multiple options to select from; checkboxes will be used for fields that support selecting multiple values, radios for a single value only. A “T-shirt size” field makes sense as a radio button selection, whereas a “Favorite colors” field makes sense as a collection of checkboxes.

File

File

This provides an upload button that allows you to browse for a file and upload it to the Drupal site.

Image

Image

This widget is the same as the File widget with the additional feature that once an image is uploaded, a small thumbnail will appear next to the upload field. It also optionally allows for entry of “alt” and “title” attributes for a textual description of the image so screen readers and search engines can “see” it.

Text field

Decimal, Float, Integer, Text

This widget allows a single line of text to be entered, such as a name or phone number. Either plain text or formatted text entry (to support bold and italics or links, for example) is supported.

Text area (multiple rows)

Long text

Use this widget for entering a larger paragraph of text, such as a biography or a product description. Either plain text or formatted text entry is supported.

Single on/off checkbox

Boolean

Use when something can only be answered “yes” or “no”; for example, a field that asks whether a user would like to be added to a mailing list.

Text area with a summary

Long text and summary

This is similar to the “Text area (multiple rows)” widget in that it provides a large text box, but it also provides an (Edit summary) link at the top, which will open a new summary box when clicked. This allows you to enter a summary of the longer text, which is typically displayed in listing pages such as the default front page.

Select list

List, Term reference

An alternative to checkboxes and radio buttons is a drop-down select list. This widget type is useful when there are many different options to choose from and it would be cumbersome to display each one inline as a separate choice, such as a list of countries.

Displays, View Modes, and Formatters

Complementing the configuration of how field data is input, you can also determine how field data is output and displayed to end users. There are two aspects to configuring fields’ display: configuring the output of the individual field (such as where its field label is displayed and how its value should be shown), and configuring the overall way in which fields are shown when viewed in certain contexts.

Each type of entity presents one or more view modes (e.g., RSS feed, search results, teaser, or full view) and can be configured to show or hide certain fields or change their output depending on the context in which the entity is being viewed. You can either configure default settings applicable to all view modes, or override the defaults by providing a custom display setting for one or more specific view modes. By default, Drupal provides a custom display override for node teasers to change how your fields are displayed on full content (and RSS and search results pages) versus on the teaser view on the default home page. This also means, however, that if you want the fields to look the same in both view modes, you have to update both the Default settings and the Teaser settings—custom display settings do not inherit the default display settings.

In Figure 3-4, you can see the Manage Display tab for the core “Basic page” content type, which shows the Teaser custom display settings enabled. Once a custom display is enabled, a new subtab will appear in the upper-right corner of the settings page.

Manage Display settings with custom Teaser tab

Figure 3-4. Manage Display settings with custom Teaser tab

Table 3-3 contains a list of default view modes provided by Drupal core’s entities, and like everything else in Drupal, contributed modules can provide additional view modes. There are two subtabs on this page, Default and Teaser. The Default settings will control the look of the content for all view modes, except those that are checked off in the Custom Display Settings fieldset at the bottom of the page. By default, core enables one custom display: the Teaser. So with the default core settings, the changing settings on the Default tab will control how the fields look on the Full content, RSS, Search index, and Search results displays.

Content types on your site have a settings page to manage its display settings, which you can access by going to the administrative toolbar and clicking Structure“Content types” and then clicking the “Manage display” link for your desired content type (admin/structure/types/manage/<content type name>/display). Other entities expose this same screen closer to their own configuration pages. For example, the field display management screen for user accounts is at ConfigurationPeople“Account settings”“Manage display” (admin/config/people/accounts/display).

Table 3-3. Default view modes provided by Drupal core, and the entities to which they can apply

View modeEntities

Description

Default

AllThis type of display is the fallback, and will be used if no better matching view mode is found. In general, it’s best to stick to the defaults if you can, because once you’ve customized another view mode, keeping things in sync means changing the display configuration in multiple places.
Full contentNodeThis view mode is used when a node is being displayed with all of its associated data, like on the http://example.com/node/1 page.
TeaserNodeThis view mode is used when a node is being displayed in the trimmed or summary view, like on the default home page at http://example.com/node.
RSSNode

This view mode is used with a piece of content in an RSS feed like the home page’s http://example.com/rss.xml.

Search index

NodeThis view mode controls which fields are searchable. It can be useful to hide fields from the search index view mode in order to provide better search results.

Search result

NodeThis view mode controls which fields will display on a search result page.

Full comment

CommentComments do not have teasers. This view mode represents when the entire comment is being viewed, such as on a http://example.com/node/1 page.
Taxonomy term pageTaxonomy

For taxonomy terms, this view mode dictates which vocabulary fields will appear on a taxonomy listing page such as http://example.com/taxonomy/term/1.

User accountUser

For users, this view mode shows fields on the user profile, on pages such as http://example.com/user/1.

Within each display settings page, you control the output of the fields using formatters. For example, long text with summary fields can be displayed as the full text or the summary, or hidden altogether, as seen in Figure 3-5. A full list of fields and the formatting options they provide can be found in Table 3-4.

Configuring the display of a field formatter

Figure 3-5. Configuring the display of a field formatter

Other modules may add other formatters, giving you a plethora of ways to display information. The core “Image styles” feature, covered in Chapter 4, is an example; it allows the display of thumbnail or full images, and provides those display options as formatters for Image fields.

Keep in mind that the formatters available depend on the type of data, once again making it very important to choose your field type wisely. For example, set up a field as an integer, decimal, or float if you’ll be displaying numbers.

Table 3-4. Fields and the field formatters they have available

Field type(s)

Formatters available

Boolean, List (float), List (integer), List (text)

Either display the label on the field selection (default), or the actual key stored in the database, such as 0 or 1 (key).
Decimal, Float, IntegerSpecify how to show the thousands separator (decimal point, comma, space) and specify whether to show the field prefix/suffix (such as $). For float and decimal fields, specify the decimal marker (decimal point, comma) and scale (digits after the decimal point). Can also display the raw, unformatted value.
File

Files can be shown as a filename linked to the file, a table containing the file link as well as the file size, or simply the raw URL to download the file.

Image

Specify the image style (original, thumbnail, medium, large) and whether to link the image to the uploaded file or the piece of content to which it’s attached.
Text, Long text, Long text and SummaryDisplay the field contents as formatted text (default), plain text, or text trimmed to a certain character length.

Reusing Existing Fields

Once you have created a field to add to an entity, you can reuse that field in other entities. This can be a useful time saver, and also allows you to create listing pages of multiple content types that share the same field, once we start talking about Views.

There are two “classes” of configuration on fields:

  • Field-specific settings, which specify the field type and other options that dictate its database storage, such as the field length and the number of values it can store.

  • Instance-specific settings, which dictate options used only on this field in the context of a particular entity or content type. Examples are its field label, the type of widget to present to admins, and whether or not the field is required.

Reusing a field on a different entity requires you to keep the same field type and name, as well as anything else under “[field] settings,” but you can customize the field for each different instance by using the “[entity type] settings” for the field. You can see how this looks on a Department field on a Job content type in the configuration screens shown in Figures 3-6 and 3-7.

The Job Settings section indicates how this field will look and behave only on the Job content type. The Department Field Settings section determines the global settings for this field, no matter which content type it is used in. In this example, we have a Job content type with a Department select list field. We can reuse the Department field as many times as we like, but the Department field settings, which in this example determine the list of departments to choose from, will be the same across all instances of the field. However, we can change, per instance, settings such as the label, and whether it is required, the help text, and the default value.

Reusing fields can be very helpful if you need to use the same information across multiple entities. However, it can also be restrictive if you’re trying to customize elements such as the allowed values for the field per instance. Make sure you only reuse fields when the instances are really identical.

Field settings that are specific to the content type

Figure 3-6. Field settings that are specific to the content type

Field settings that are global for all uses of this field

Figure 3-7. Field settings that are global for all uses of this field

Hands-On: Job Content Type

To get started with our job posting website, let’s think about the different content types needed to build all the functionality that we require. The site requires two different types:

Job

Description and details of a particular job opening.

Job application

An application for a particular job that provides details about the applicant.

We will need to relate job applications back to the appropriate job openings, as well as relate jobs back to the appropriate contact person. The node reference and user reference fields provided by the contributed References module, mentioned earlier in the chapter, will be an essential tool.

To build this site, we’ll need to go beyond the default “Basic page” and “Article” content types offered by Drupal core. When you’re building out content types in Drupal, it’s best to start with a mental picture of what the form looks like that you’re trying to build. Figure 3-8 shows a sketch of both the job and job application forms that we’re shooting for.

A mockup of the forms required for the job website

Figure 3-8. A mockup of the forms required for the job website

The Job content type will contain all the information we need to store about a particular position that’s available at Epic University. It will need the following core fields:

  • Job Title (the core node title field)

  • Description (the core node body field)

  • Department (a text list field)

  • Salary (an integer text field)

Let’s walk through the steps to create this new content type with the core fields we have available. We’ll get to noncore fields later in the chapter.

  1. If you haven’t already, install Drupal using the Chapter 3: Job posting board installation profile from the book’s sample code. See Downloading the Book’s Source Code for more details.

  2. All core field-related modules are enabled by default in the standard installation of Drupal, so all of the modules we need should be enabled already. Double-check by going to Modules (admin/modules) from the administrative toolbar. Confirm that the following modules are enabled, and click “Save configuration”:

    • Core package:

      • Field

      • Field SQL Storage

      • Field UI

      • File

      • List

      • Number

      • Options

      • Text

  3. Create the new content type by going to the administrative toolbar and clicking Structure“Content types” (admin/structure/types). Click the “Add content type” link at the top of the page (admin/structure/types/add).

  4. Using the settings indicated in Table 3-5, create a new content type called Job. We repurpose the Title field for Job Title simply by changing the label. When completed, your screen should look similar to Figure 3-9.

    Table 3-5. Settings for the Job content type

    Field

    Value

    Name

    Job

    Description

    A currently available position.

    Submission form settings

    Title field label

    Job title

    Comment settings

    Default comment setting for new content

    Closed

Adding a new Job content type

Figure 3-9. Adding a new Job content type

  1. Click the “Save and add fields” button to save your work. After submitting the form, the new content type will be created, and you will be taken to a page to begin adding your custom fields.

    Note

    If you save the content type by clicking the “Save content type” button instead of the “Save and add fields” button, you will be taken back to the main content types screen (admin/structure/types). You can begin editing the fields by clicking the “manage fields” link (admin/structure/types/manage/<content type>/fields) for the content type you wish to work with. That will take you to the same location as the “Save and add fields” button would.

  2. Before we add our first field, let’s change the label for the Body field so it makes more sense for our use case. Click the “edit” link in the Operations column for the Body field. Change the Label to say “Description” instead and click the “Save settings” button, and you will be returned to the “Manage fields” screen (admin/structure/types/manage/job/fields).

  3. Use the settings from Table 3-6 and pictured in Figure 3-10 to complete the “Add new field” form to add a new select list for the Department field. You need to select the field type before you can select the widget type. Once you have selected the field type, the widget type drop-down will populate with the options you have available for that specific field type.

    Table 3-6. “New field” settings for the Department option

    Field

    Value

    Label

    Department

    Field name

    department

    Select a field type

    List (text)

    Select a widget

    Select list

    Warning

    It’s worth spending a couple of minutes thinking about what type of data a field will store before selecting the field type. Once selected, the field type can’t be changed. If you make a mistake, you must delete the field and create a new one with the correct field type.

    The “Add new field” form for the Department field

    Figure 3-10. The “Add new field” form for the Department field

  4. After clicking the Save button, on the next page, you’ll be able to edit the global field settings. In the case of list fields, this means adding items to the select list. Use the values from Table 3-7 and pictured in Figure 3-11 to populate the options a user may select. Click the “Save field settings” button to proceed.

    Table 3-7. Configuration for the Department field

    Field

    Value

    Allowed values list

    Administration

    Arts

    Athletics

    Business

    Education

    Health Sciences

    Sciences

    The field settings configuration form for the Department field

    Figure 3-11. The field settings configuration form for the Department field

    Note

    Notice in the help text for the allowed values list, it mentions entering fields in the format of “key|label.” This format—e.g., “edu|Education”—is useful if the department has a standard abbreviation or code that you’d like to store. Specifying a key will also ensure that the label (Education) can be changed independently and will not affect any of the existing field data pointing to that field. To ensure this safeguard, if keys are not specified for list values, the Field module will automatically generate them for you. If you go back to edit this field value later, you’ll notice the options have all been changed to “Education|Education” (and the like) on your behalf. The key of a list also determines the field type of list field you want; “1234|Education” would be better as a “List (integer)” field.

  5. Now we can finish up our configuration by adding some help text for our users. In the Help text field, add “Select the department in which this job belongs,” as shown in Figure 3-12.

    Job settings for the Department field

    Figure 3-12. Job settings for the Department field

    Note

    You will notice that the settings you just added on the previous Field Settings screen are also at the bottom of this Job Settings screen. The job settings that you enter, like the help text, will apply only to the Department field in the Job content type. The field settings that are entered will be applied everywhere that you use this Department field, even in other entities. If you are using the same field in multiple entities, you should pay close attention to these settings and understand that changing field settings will make changes across all of your content types.

  6. After saving the new field by clicking the “Save settings” button, you should be returned to the “manage fields” tab (admin/structure/types/manage/job/fields). We can now add the Salary field. Fill in the settings for the new field from Table 3-8. We’ll add the salary as an integer, but if you want to include cents in the salary, you can use a decimal field instead.

    Table 3-8. Settings to create the Salary field

    Field

    Value

    Label

    Salary

    Field name

    salary

    Select a field type

    Integer

    Select a widget

    Text field

  7. Click Save to create the Salary field. There are no field settings for an Integer field, so click the “Save field settings” button to proceed at the next screen. Finish setting up the field with the options from Table 3-9 to provide some help text, make the field required, and prefix the salary with a $ (dollar sign) so it looks like a dollar amount. Click “Save settings” when finished.

    Table 3-9. Configuration for the Salary field

    Field

    Value

    Job settings

    Required

    Checked

    Help text

    Enter a yearly salary for this position.
    Minimum0

    Prefix

    $

  8. Finally, before any users can actually create pieces of job content, they’ll need to have permission to create and edit jobs. Add permissions for the new content type by going to the administrative toolbar and clicking PeoplePermissions (admin/user/permissions). Check the options shown in Table 3-10 and click the “Save permissions” button.

    Table 3-10. Permissions for the Job content type

    Permission: node module

    anonymous user

    authenticated user

    editor

    administrator

    Node

    Job: Create new content

      CheckedChecked

    Job: Edit own content

      

    Checked

    Checked

    Job: Edit any content

       Checked

    Job: Delete own content

      

    Checked

    Checked

    Job: Delete any content

       Checked

Spotlight: References

The References module is a contributed module that allows you to create relationships between nodes and/or users. When you download References, you will see that you actually have a package of several modules: References, Node Reference, and User Reference. References is the central module and is required by the other two. The Node and User Reference modules provide the actual fields that you can use to add to your site. In Drupal 6, these modules were included as part of the main CCK package.

Creating a reference field comes in very handy when you have content that has a relationship to another piece of content. A classic example of this would be a music site. You can have three content types: Artist, Album, and Song, which are obviously related to each other, but each is a unique kind of content that has different fields. If we use a Node Reference field in these content types, we can identify which Album node a Song node “belongs” to, and likewise we can identify which Artist node an Album “belongs” to. Using References, we can reuse the information we already have (Artist and Album nodes) instead of having to re-enter those values each time we create a new song. Once we create these references, we can easily display that information on the content type itself, and we can use that relationship within Views to create custom lists of related content. So we can have an Artist node that displays all of the albums for that artist, and the Album nodes can display all of the songs, or we can use Views to list all of the songs by a particular artist. You can do the same thing with users on your site using the User Reference module.

Note

While it’s not 100% feature-compatible at the time of this writing, keep an eye on the Entity Reference module in the future. This module goes one better than References and creates a generic field that can form references between any two entity types. Or, if your needs call for even more complex relationships, check out the Relation module, which makes relationships entities so you can add relationships to the relationship itself. Whoa.

Hands-On: Adding a Reference Field

Now we need to add a primary contact for this job position. This will usually be the person creating the entry, but we’ll allow the user to enter any of the possible faculty members on the site. This will be done as a “User reference” field, provided by the contributed References module. References is included in the source code that accompanies this book, so if you are using the source code, you can just enable the modules. If you are not using the source code, you should get a copy of the References module and add it to your site, as explained in Chapter 2.

  1. First we will need to enable the modules we need. In the administrative toolbar, click Modules (admin/modules) and enable the following modules:

    • Field package:

      • Node Reference

      • References

      • User Reference

  2. Navigate back to Structure“Content types,” and click the “manage fields” link next to the Job content type (admin/structure/types/manage/job/fields). Enter the values from Table 3-11 into the “Add new field” form, and then click Save. Note that if the site grew to include hundreds of faculty members, switching the widget type from a select list to an autocomplete text field might be a good idea, but for now, with our small site, a select list will work fine.

    Table 3-11. Settings to create the Contact field

    Field

    Value

    Label

    Contact

    Field name

    contact

    Select a field type

    User reference

    Select a widget

    Select list

  3. Configure the field settings so that only users of the “editor” role (to which faculty members are assigned) and Active status can be referenced. This narrows down the list of potential users that can be selected. Click the “Save field settings” button.

    Note

    If you’re using the book’s source code, this “editor” user role was already set up for you during installation, along with the “editor” user and several other sample faculty members. You can assign the “editor” role to additional users via the People (admin/people) menu.

  4. In the Job Settings section, set the help text to “Select the faculty member who is the primary contact responsible for hiring this position.” Click “Save settings” when you are done.

When finished, your completed Job content type should look as pictured in Figure 3-13.

Job content type with Department, Salary, and Contact fields

Figure 3-13. Job content type with Department, Salary, and Contact fields

Hands-On: Customizing Field Display

For usability, it’s often important to display forms and page contents in a specific order, and to add formatting so that it’s more clear what data is being presented. The following steps will take you through some minor customizations to the way fields are displayed.

Let’s take a look at what all of our hard work has accomplished so far. Navigate to “Add content”Job (node/add/job), from either the Shortcut bar or the Navigation menu. It should look as pictured in Figure 3-14.

The Create Job form with no display customization

Figure 3-14. The Create Job form with no display customization

This works for basic data entry, but there are a few things that we could do to make our job posting board more intuitive for our faculty members:

  • Reorder the fields on the data entry form so that the department is selected before the job description is filled out.

  • Make minor adjustments to where field labels appear and how their values are output on job postings.

  • Hide certain fields—such as Contact—on the Teaser view of the job post so that readers must read the entire description in order to obtain more information.

This section will cover how to make these sorts of cosmetic changes to fields.

  1. First, let’s reorder the fields on the form so that they make more logical sense. In the administrative toolbar, go to Structure“Content types” and click “manage fields” next to the Job type (admin/structure/types/manage/job/fields). Drag the handle on the left side of each row and arrange the table so that it is in the following order (shown in Figure 3-15), and then click the Save button when finished:

    • Job title

    • Department

    • Description

    • Salary

    • Contact

    Field order for the Job content type

    Figure 3-15. Field order for the Job content type

  2. The Job content type is now nearly complete. Let’s see what our form currently looks like. Log in as editor, enter the password oreilly, and create a new Job piece of content by clicking “Add content”Job (node/add/job) in either the Navigation block or the Shortcut bar.

  3. Fill out the values in Table 3-12, or feel free to make up your own. Now that we’ve reordered the fields, the form should look similar to Figure 3-16 (if you are logged in as the “admin” user, you’ll see several more options that are hidden from other users). Click Save when you’re finished filling in the fields.

    Table 3-12. Settings to create the Contact field

    Field

    Value

    Job Title

    Alumni Director

    Department

    Administration

    Description

    Epic University is looking for an Alumni Director. The position will require keeping track of graduate contact information as well as organizing alumni social events.
    Salary

    50000

    ContactMarty Johnson

Taking a look at the content after it’s created, we’ll see that it’s not entirely pretty. Figure 3-17 shows the default output of our Job type when we view the content. The department is still listed underneath our description; the labels are included above each field, making the page longer than it needs to be; and the salary could really use a comma. Fortunately, we can use Field Formatters to change the display of the job content a bit more to our liking.

The Job form as seen by a user in the “editor” role

Figure 3-16. The Job form as seen by a user in the “editor” role

Default output of the Job content type

Figure 3-17. Default output of the Job content type

  1. Log back in as user admin, password oreilly. In the administrative toolbar, click Structure“Content types” and click the “manage display” link next to Job (admin/structure/types/manage/job/display), which will take you to the display options for the fields in the Job type.

  2. First we’ll clean up the labels and field order. Update the form to use the values presented in Table 3-13, and drag them into the order specified in the table. We’ll leave the Format column with its defaults. Click Save when finished.

    Table 3-13. Default display field settings for the Job content type

    Field

    Label

    Department

    Inline

    Description

    <Hidden>

    Salary

    Inline

    Contact

    Inline

  3. To add a comma to the Salary field, we’ll need to go deeper into that field’s settings. Click the gear icon button all the way to the right of the Salary field row, as shown in Figure 3-18. Set the “Thousand marker” to Comma, and click Update. Don’t forget to hit the Save button at the bottom of the form when you’re done!

    Display field settings for the Job content type

    Figure 3-18. Display field settings for the Job content type

  4. After saving the changes, take a look at the Job piece of content a second time. The new, cleaner look is shown in Figure 3-19.

Now you can see that our labels are displayed next to the values, rather than on a separate line. A comma is automatically placed in the correct location for the Salary field. Nice!

Job content after configuring the field display

Figure 3-19. Job content after configuring the field display

The last step is to fix up our Teaser display as well, since that has its own custom settings and won’t automatically inherit the defaults we just set. We can also make some subtle changes in the display for that view mode.

  1. Let’s go back to our display settings. In the administrative toolbar, click Structure→“Content types,” click the “manage display” link, and this time click the Teaser subtab (admin/structure/types/manage/job/display/teaser).

  2. Currently, the Description field is the only one visible, and the rest of the fields are listed as Hidden. Let’s move the Department field to the top of the list, with Salary below Description. Ensure that the Contact field is moved down in the Hidden section at the bottom of the page to prevent the field value from displaying altogether. Make people read the full job description before they see who to contact!

  3. Now change the Salary field to use a comma, just like we did before, by clicking the gear icon for the field, changing the “Thousand marker” field to Comma, and clicking Update.

  4. Finally, we should make our labels behave just as we did for the default display. Change the Label setting to Inline for the Department and Salary fields.

  5. Once you’ve made all of your changes, make sure you save the form. It should look like Figure 3-20. If you return to the site’s home page, the Alumni Director position should now show Department and Salary information.

    Note

    If you want even more flexibility over your content layout, check out the Display Suite module. With Display Suite, you can divide the content area into regions such as left, right, header, and footer, and have full control over exactly where and how your fields appear. See an introduction at http://tutr.tv/t5821.

    Teaser display settings for the Job content type

    Figure 3-20. Teaser display settings for the Job content type

Hands-On: Job Application Type

Now that the university is able to create job positions, it would be helpful if prospective employees could submit résumés to the positions in which they’re interested. We’ll create another content type for this purpose, called Job Application.

  1. Return to the main content type settings page by heading to the administrative toolbar and clicking Structure“Content types” (admin/structure/types). Add another content type by clicking on the “Add content type” tab at the top of the page.

  2. On the “Add content type” page, fill in the form with the values from Table 3-14. Again, we’ll easily create the first two fields (“Title” and “Introductory message”) by reusing the Title and Body fields provided by Drupal core.

    Table 3-14. Settings for the Job content type

    Field

    Value

    Name

    Job Application

    Description

    An application for a job position

    Submission form settings

    Title field label

    Title

    Publishing options

    Promoted to front page

    Unchecked
  3. After you submit the form with the “Save and add fields” button, the new content type will be created. Click “edit” next to the Body field and change its label to “Introductory message.” Save when finished.

  4. Use the settings from Table 3-15 to add a new node reference field for the job type. This will connect a particular “Job application” node with the Job node.

    Table 3-15. Add field settings for Job node reference

    Field

    Value

    Label

    Job

    Field name

    job

    Select a field type

    Node reference

    Select a widget

    Select list

  5. Click Save and select the Job content type on the “Content types that can be referenced” field at the field settings screen, to limit the select list only to job content. Click “Save field settings” to continue.

  6. On the Job Application settings screen, check the Required field checkbox so that all applications are associated with a job posting. Click the “Save settings” button to complete adding the field.

  7. The last thing required for our job application type is to allow users to upload a résumé or some other file with their application. We’ll use a file field, which is provided by core with the File module. Add the Résumé file field using the settings from Table 3-16 and then click Save.

    Table 3-16. Add field settings for the Résumé file field

    Field

    Value

    Label

    Résumé

    Field name

    resume

    Select a field type

    File

    Select a widget type

    File

  8. On the next screen, leave the default settings and click the “Save field settings” button.

    Note

    The upload destination defaults to Public, but other contributed modules can provide additional “upload destinations” for file fields. For example, the AmazonS3 module provides a way to upload files to the Amazon Simple Storage Service rather than to Drupal itself. Handy for large files!

  1. Fill out the Job Application settings with the values in Table 3-17 and click “Save settings.” We want to restrict the types of file extensions that may be uploaded to just document files, and also specify that all files uploaded through the widget reside in a resumes subdirectory of the main Drupal files directory for better organization. The File module also allows control over the visibility of the file on the application itself. The provided settings will force the file to always be listed, without the possibility of being overridden. However, there are options that allow for use cases that require that sort of flexibility.

    Table 3-17. Field settings for the Résumé file field

    Field

    Value

    Job Application settings

    Required field

    Checked

    Allowed file extensions

    pdf doc docx txt rtf pages odf

    File directory

    resumes

    Résumé field settings

    File displayed by default

    Checked

    Note

    The list of supported file extensions is included automatically below the file field when it is displayed, so there’s no need to duplicate that information in the field help text.

  2. Now we’ve added all the fields needed. Order the fields on the “Manage fields” tab as follows and click the Save button:

    • Title

    • Job

    • Introductory message

    • Résumé

    When finished, your content type should look as pictured in Figure 3-21.

    Completed job application type

    Figure 3-21. Completed job application type

  3. Finally, add permissions for the new content type by going to the administrative toolbar and clicking People, then the Permissions tab (admin/people/permissions). We want logged-in users to be able to manage their own job applications, and for editors to be able to manage any of the applications. Check the options shown in Table 3-18 and then click “Save permissions.”

    Table 3-18. Permissions for the Job Application content type

    Permission: Nodeanonymous userauthenticated usereditoradministrator
    Job application: Create new content CheckedCheckedChecked
    Job application: Edit own content CheckedCheckedChecked
    Job application: Edit any content  CheckedChecked
    Job application: Delete own content CheckedCheckedChecked
    Job application: Delete any content  CheckedChecked

That finishes the configuration of the form for the Job Application content type. Let’s take a look at the finished form as a user in the “authenticated user” role. After logging in with the username user and password oreilly, create a new application by clicking “Add content”Job Application (node/add/job-application) in the sidebar. The form should look as shown in Figure 3-22.

Note

The user user was created for you automatically when you installed Drupal from the book’s source code. If you installed a different way, create a normal user with only the “authenticated user” role assigned.

The job application form, as seen by any authenticated user

Figure 3-22. The job application form, as seen by any authenticated user

Because job applications won’t be as visually important as job listings, we’ll skip configuring the display options for this content type. But if you’re feeling sparky, you can still make these changes by logging back in as the administrator, going to the administrative toolbar and clicking Structure“Content types,” and then clicking the “Manage display” link for the Job Application content type (admin/structure/types/manage/job-application/display). After a user creates a new job application, it should look something like Figure 3-23.

A job application piece of content

Figure 3-23. A job application piece of content

An important thing to note in Figure 3-23 is how our node reference field (Job) appears when given a value. The default behavior is a link to the original piece of content that is referenced. Clicking on the Alumni Director link from this application will take us back to the Alumni Director job. There are other ways to display node reference fields as well, which can be explored in the “Manage display” tab on the Job Application type (admin/structure/types/manage/job-application/display).

Note

At this point, it’d be a good idea to populate your site with some content. Log in as either admin or editor with the password oreilly and create several pieces of job content at “Create content”Job (node/add/job). It’s also a good idea to create a few applications as user, applying for a few different job positions. Having several pieces of content will help with the next section.

Spotlight: Views Module

The Views module provides listings of data on your site: users, comments, nodes, and more. Any listing of data provided by the Views module is called a view, which we’ll always refer to in all lowercase to distinguish it from the Views module, which is capitalized. Figure 3-24 shows examples of some of the listings that can be built with the Views module.

Several types of views created by the Views module are visible on Grammy.com

Figure 3-24. Several types of views created by the Views module are visible on Grammy.com

Creating a basic view entails selecting the fields you would like displayed (node title, author name, image, etc.), how you would like that list to be filtered (only display “story” node types that are published), how you would like the listing to be sorted (newest stories on top), and what you would like the list to look like when it’s displayed (a block showing a bulleted list of headlines).

In more technical terms, Views is a visual SQL query builder. When you build a view, you are essentially constructing a query that Views will pull from your site database. However, the Views module has significant advantages over a handcoded query. Some examples:

  • Views handles not only generating the query logic, but also the wrapping display logic. Flipping a display from a simple bulleted list to a table with sortable columns to even an events calendar is a matter of a few clicks.

  • You don’t have to write any code just to make content listings, nor do you have to update code to make subsequent minor visual tweaks to it.

  • Modules will tell Views about their fields; you don’t need to know anything about the underlying database structure, and you are insulated in case this structure should change behind the scenes between module updates.

  • The same view can be used in several places on the site, as blocks, pages, feeds, and other types of listings.

  • Results can be split into multiple-page listings or use sortable table columns, AJAX pagers, or filtering drop-downs to allow visitors to “drill down” to the content they want.

  • All views have support for caching results, for a performance boost.

More than anything else, Views can significantly speed up the development of your site, without your having to learn module development or a single line of PHP. Views can form the backbone of outputting content on your site.

The typical way to create a new view is to go through a one-page wizard that sets up the most common settings used in views. You can either stop there and use the results of the wizard, or you can continue with a more advanced configuration of the basic view that has been created so far. Figure 3-25 shows the wizard interface. The full Views interface is pictured in Figure 3-26.

Note

If you install the “Advanced help” module, you will get access to the built-in documentation for Views (and other modules that use it to display documentation). In the Views interface, you will notice this as small gray circles with a question mark next to various elements on the page. If you click these question marks, a help page will pop up with more information.

The wizard interface for building a basic view

Figure 3-25. The wizard interface for building a basic view

Data Types

When building a view, the first thing that you will need to determine is exactly what sort of “stuff” is going to compose your list. In the background, Views is building database queries and, just as if you were writing some SQL by hand, you need to start with an idea of what the central data in your query is going to be. You have a lot of different kinds of data in your Drupal site. Content and users are probably the two most easily recognized and most often used, but you can also build lists of taxonomy terms, files, comments, and more. You need to select your data type when you start building your view, which you do in the wizard, where it states Show and provides a select list of data types you can list, as shown in Figure 3-27.

Warning

You will notice that once you select a data type, you can’t change it in the main Views interface, as you can for the other settings you select on the wizard page. The view name and data type are key information, and the only way to change those settings is to build the view over again from the start.

The full Views setting interface

Figure 3-26. The full Views setting interface

Selecting a data type for building a view

Figure 3-27. Selecting a data type for building a view

Once you select your base data type, the interface will provide the correct options to build your list for that data type. Different kinds of data have different properties that Views can use. You can also tie in additional information from other data types as you build your view, using relationships. For example, I may want a list of content on the site, but that list can be enhanced further by gathering more information about the users who created the content and adding the user data to the view as well. We’ll talk more about relationships and how to use them later, in Relationships.

Displays

A display determines how a view will be presented to the user. A view can have multiple displays, and can even create several pages listing the same content in different ways. The upper-left corner of the Views interface lets you choose which display you are editing. Figure 3-28 shows adding a new display to a view.

Adding a new display

Figure 3-28. Adding a new display

By default, there are four different kinds of displays, each serving a particular purpose. Other modules may also add extra display types:

Attachment

Think of attachments as essentially subviews: a supplementary display that can be attached above and/or below other types of displays. This display type can be helpful for giving a view context or adding a glossary when your view is being filtered. An example could be a view displaying a list of tracks beneath a view displaying albums.

Block

You can position views exposed as blocks in sidebars or any region from the Blocks configuration page by going to the administration toolbar and clicking StructureBlocks (admin/structure/block).

Feed

The Feed display type creates a customizable RSS feed to which users may subscribe using an RSS reader. Feeds can both receive their own URL and be attached to any block or page display.

Page

Makes a page with its own URL in which the view occupies the main content.

The Views module provides many exciting options to easily configure the display of your content. The settings for the first display you create will also be the default settings for any future displays; however, each display can have its own settings that override the view defaults. To change any value within the Views interface, click the option represented as a link, and the configuration for that option will appear in a pop-up modal screen. Figure 3-29 depicts the settings for all displays versus an override for a specific display, along with an example of italicized text being used to indicate an overridden value.

Configuration when overriding a default value

Figure 3-29. Configuration when overriding a default value

Warning

Pay very close attention to whether the font for an option in the Views administration screen is italicized. Italics indicate that a setting is being overridden for that particular display, meaning that changes to it will only affect the given Page or Block. You must specifically override settings on displays; otherwise, they will affect the defaults—and thus all other non-overridden displays—regardless of which display is currently selected.

It’s also important to pay attention to the particular display you are editing, as the settings change slightly between display types. Some of the most important configuration options for a view are available only when you are configuring a particular display. For example, to set a URL for a Page view, you have to be configuring a view’s Page display. The URL is presented as an option within the Page settings, displayed in the middle column of the interface. The display-specific section for a Page view is shown in Figure 3-30.

The available settings may change, depending on the display type that is being edited

Figure 3-30. The available settings may change, depending on the display type that is being edited

One other thing to be aware of in the Views interface is how you add and rearrange the data settings. There is an “add” button on some sections for adding items. You will also notice that the “add” button sometimes has a small down arrow next to it. If you click the arrow instead of the word “add,” you will see more options, like “rearrange” for the ordering of fields, or “and/or” for determining the logic of your filters. You can see an example of this interface in Figure 3-31.

Adding data items and accessing additional actions

Figure 3-31. Adding data items and accessing additional actions

Pieces of a View

The main Views interface has a lot of settings, and it has been designed to provide the most often used settings right up front, while hiding the more advanced and less used settings to keep the interface as organized as possible. However, there’s still a lot of information to fit in there! The interface has three main columns. The first column, on the left, contains basic information and the most commonly used criteria to build the view’s query. The second column, as pointed out earlier, contains display-specific settings, in addition to a few other elements surrounding the view. The third column contains a collapsed fieldset where all of the advanced settings are kept.

Here is a rundown of each section on the Views administration page, pictured previously in Figure 3-26.

Title

The Title setting will set the title above the view when it is displayed. It is most commonly used to add a header and a page title element to a page display. So you would, for instance, get an h1 header element at the top of the view, and see the same title in the browser’s title bar when on that view page.

Format

A format is how Views knows what markup to produce when displaying your view. By default, you will have several options—Grid, HTML list, Jump menu, Table, and Unformatted list—which are printed as HTML. However, other contributed modules can add to this list and provide non-HTML options, like XML or CSV, for example. The default HTML will be “Unformatted list,” which will output each row of the view result in an HTML <div>. You can easily change to one of the other formats, which will change the overall HTML structure. Each of the formats has additional settings where you can further tweak the HTML, by clicking the Settings link next to the format name.

Under the Format setting, there is a Show link, which dictates how each row returned in the view is styled. This is where you will determine if you want to just have the full Drupal content rendered, or if you would like to control things more by having it output individual fields that you hand-select. The default for the Content data type is Content, which by default will display the view’s selected nodes in a listing much like Drupal’s default home page. But the most commonly used setting for most views is Fields, for more granularity over what exactly shows up in the view.

Row styles also provide additional configuration options, such as what view mode to show the content in and whether to show links and comments, in the case of a Content row style. For Fields row styles, you can specify the wrapping HTML elements to use around the values, whether certain fields should be displayed inline (next to each other) or on top of each other, and what separator characters (if any) should be placed between field values.

Fields

A field represents a piece of data to display in your view. Some examples of fields are the node title, a user’s email address, the image attached to an article, a taxonomy term, or pretty much any piece of data within Drupal.

Each field provides a number of configuration options, including the ability to customize or hide the field’s label, specify what Formatter it should use to output its value, use custom HTML and CSS around the field, and rewrite the field value so that, for example, it links to a different page.

Filter criteria

By default, the Views module will show all of the data—users, comments, or nodes, depending on the base view data type—available on your website. Filter criteria is used to further restrict the list of records being returned in a view. Some common filter criteria includes showing only nodes that have their Published flag turned on, only users within a specified role, or only nodes of a particular type, such as our Job or Job Application nodes.

You also have the option of exposing filter criteria to site visitors, which provides a user interface to let users choose what content should appear in listings. An exposed filter for node title, for example, would provide a text box that allows users to search for content containing a certain word, and an exposed filter for Department would provide a select box for users to see jobs only from the Arts department. You can also expose filter forms in a block under the “Exposed form” section under advanced settings.

Sort criteria

Once you’ve narrowed down results from your database and have the fields you want to display, you can use sort criteria to determine the order in which those results show up. Some examples are sorting by the created date, node title, or author username. On each sort criteria, you can choose whether it should sort ascending (A–Z) or descending (Z–A).

As of Drupal 7, sort criteria (like filter criteria) can also be exposed, to allow site visitors to fiddle with the ordering of results.

Contextual filters

Filter criteria will always filter the view in exactly the same way each time it’s viewed. For example, a filter criteria of “Content: Promoted to front page (Yes)” will only ever show content that’s been promoted to the front page.

However, sometimes you don’t know exactly how you want to filter the results coming back from a view until the time that it’s displayed. For example, in a scenario where you want to make a listing of content that appears on users’ profiles, you wouldn’t want to have to make a separate view for each user on your site: one filtered by user ID 1, one filtered by user ID 2, and so on.

Contextual filters are the dynamic version of filter criteria. They allow you to create a single view, and filter the results based on the context coming in from outside—for example, the user ID from the page URL.

The “context” part of contextual filters usually comes from the page URL. If your view is displayed at the URL http://example.com/my_view, URL parts after my_view would be taken as context values. For example, in the URL http://example.com/my_view/10, the number 10 would be the first context value. You can have as many context values as you want in your view; just keep adding more URL parts.

In addition to context values that are at the end of the URL, you can also place context values in the middle of a URL by using the % symbol in the view’s Path configuration. This feature can be helpful when you want to utilize some of the existing paths in Drupal, such as user paths, which might look like http://example.com/user/10/my_view. We still want 10 to be the first argument, but it’s now in the middle of the URL. By specifying a URL path for the view as user/%/my_view, the symbol is swapped with the contents of the URL and passed into the view as the first piece of context. If this is over your head right now, don’t worry—we’re going to walk you through an example of this kind of argument in the section Hands-On: The Views Module.

Relationships

When you need to include data from an object that’s not directly available (like a user’s information) inside a listing of content (which is based on nodes), a relationship lets you retrieve the object information that is related to the listed content. In relational databases, a view relationship could be considered the equivalent of doing a JOIN in SQL. If the “Require this relationship” field is checked, the query will change from a LEFT JOIN to an INNER JOIN, resulting in better performance. However, you can only do this if you’re sure all of the records you’re showing have a correlating record in the data being related.

We’ll set up an example of a relationship where a job application is related to a particular piece of job content. The user creates a piece of content (an application) that is related to another piece of content (the job). Using a Views relationship, we can create a listing of content that includes information from both the application and the job itself.

Header, footer, and no results behavior

Views also lets you customize the view’s header and footer (what appears above and below its results), as well as what should happen if the view returns an empty set of results. You can either put straight-up text in these areas (like “Welcome to our job listings page” or “No jobs found. Please try again later!”) or embed another view in these areas.

Hands-On: The Views Module

OK! Enough conceptual mumbo-jumbo; let’s start getting our hands dirty with Views!

The requirements of our site include two particular views. One view is frontend-facing, showing all the available jobs to users of the site. Faculty users (more specifically, users in the “editor” role) will use the second view to review the list of applicants who have applied to various jobs.

The first step to using the Views module is to enable it. The Views module has two parts: the Views module itself, which handles the low-level “plumbing,” and the Views UI module, which presents the screens used to configure the views. Additionally, “Advanced help” is an optional module that provides useful inline help for modules such as Views.

  1. In the administrative toolbar, click “Site building”Modules (admin/build/modules) and enable the following modules:

    • Chaos Tool Suite package

      • Chaos Tools

    • Other package

      • Advanced help

    • Views package

      • Views

      • Views UI

Jobs View

The “jobs” view will provide a listing of jobs at Epic University, categorized by department. The completed view will be similar to the one pictured in Figure 3-32.

A sample page from the jobs view, listing jobs in the Sciences department

Figure 3-32. A sample page from the jobs view, listing jobs in the Sciences department

  1. Get started by visiting the Views configuration page by going to the administrative toolbar and clicking StructureViews (admin/structure/views).

  2. Click the “Add new view” link at the top of the page, as shown in Figure 3-33, and populate the form with the values from Table 3-19. This screen is designed to set up the most common things used in a view. Your screen should look as pictured in Figure 3-34. These initial settings will provide us with a view that shows a listing of jobs, with its information displayed in a table, and a pager to move from one page of results to another if there are more than 10 items. It will also have a menu item in the Main Menu, which leads to a page showing the view. Lastly, we are adding an RSS feed so people can follow the latest job postings with an RSS feed reader.

    Add a new view

    Figure 3-33. Add a new view

    Initial view information

    Figure 3-34. Initial view information

    Table 3-19. The Jobs view configuration values

    View setting

    Value

    View name

    Jobs

    Description

    Checked; “A list of available positions at Epic University”

    ShowContent of type Job sorted by Newest first

    Create a page

    Checked (default)

    Create a block

    Unchecked (default)

    Page settings

    Page title

    Available positions

    Path

    jobs (default)

    Display format

    Table of fields

    Items to display

    10 (default)

    Use a pager

    Checked (default)

    Create a menu link

    Checked; Menu: Main menu; Link text: Available positions

    Include an RSS feed

    Checked; Feed path: jobs.xml (default)
  3. After clicking the “Continue & edit” button, Views takes you to the main view-building interface, where we will tweak some of our settings to refine the view. Scroll down to the bottom of the page, and you’ll see a live preview of what your view shows so far. Excellent!

  4. When we created the view, we selected the Table display format, and the wizard automatically filled in that we would use fields. It didn’t let us choose which fields, though, and by default it only provides the Title field in the view. However, we definitely want more information than that. Let’s correct this problem by adding a few fields to the view. We want to display the Title, Post date, Salary, and Contact for each job.

  5. Click the “add” button in the Fields area to start adding new fields. Include the fields from Table 3-20, as pictured in Figure 3-35. To speed up entry, you can select Content from the Filter selection to filter the list of available fields by only those pertaining to that group, or start entering characters in the Search field to limit the results. Note that we already have our Title field, so we just need to add the other three.

    Table 3-20. Fields for the Jobs view

    Fields: Add Fields

    Value

    Content: Contact

    Checked

    Content: Post date

    Checked

    Content: Salary

    Checked

    Fields for the Jobs view

    Figure 3-35. Fields for the Jobs view

  6. After you click the “Apply (all displays)” button, Views will display the configuration forms for each field, one by one, to allow you to configure each field’s options. When you’re finished entering each of the values from Table 3-21 and pictured in Figure 3-36, click the “Apply (all displays)” button to proceed to the next field’s settings. The values listed in Table 3-21 assume you will leave the rest of the fields’ default settings in place and only make the modifications indicated in the table.

    Table 3-21. Individual field configuration for the Jobs view

    Defaults: Configure field setting

    Value

    Content: Contact

    (Leave the defaults)

    Content: Post date

    Date format: Time ago (with “ago” appended)

    Content: Salary

    Thousand marker: Comma

    Field configuration for the Jobs view

    Figure 3-36. Field configuration for the Jobs view

  7. Click the drop-down arrow next to the “add” button in the Fields section, select the “rearrange” item, and drag the fields in the following order, as pictured in Figure 3-37:

    • Content: Title

    • Content: Post date

    • Content: Salary

    • Content: Contact

    Rearrange fields for the Jobs view

    Figure 3-37. Rearrange fields for the Jobs view

    Once you have rearranged the fields, click the “Apply (all displays)” button to save your changes.

  8. Now that our view has fields, you should save the view by clicking the Save button. If this button is grayed out, be sure to finish editing whatever field you’re editing; then the button will be activated again.

  9. At this point, we can pause and take a look at our view so far. If you scroll down the view edit screen, at the bottom, you will see a preview area. It automatically updates as we change the settings for the view. Our view currently looks a lot more table-like, as pictured in Figure 3-38 (with some sample content in it).

    The Jobs view preview

    Figure 3-38. The Jobs view preview

  10. Our view is coming along nicely. One thing that we did not include was a Department field in this listing, because our requirements actually call for a directory-type listing. That is, the first page of our Jobs view should display a list of departments, and then clicking on the department should provide a list of jobs inside. Because it would be tedious to create a view like this for each department, we’ll accomplish this requirement with a contextual filter, a very powerful Views feature.

    To get started implementing this directory-type listing, we’re going to go into the Advanced section of the Views editor. Click on the Advanced fieldset to open the settings, and then click the “add” button next to Contextual Filters. As before with fields, you can search or filter to narrow the list of items. Select “Content: Department (field_department)” from the list and click the “Apply (all displays)” button. Then enter the settings from Table 3-22, as shown in Figure 3-39.

    These settings will look like total gobbledygook at the moment, so let’s step through them. What we’re after is a directory at http://www.example.com/jobs/<department> which, if no department is specified, will show a list of departments along with the total number of jobs they offer.

    The “When the filter value is not in the URL” section indicates what the view should do when the URL http://www.example.com/jobs is accessed, rather than http://www.example.com/jobs/athletics. Here, we are asking it to display a list of department names in ascending order. The Summary style will display the titles of the various departments, along with the number of jobs within that department next to it. This type of view can be very useful for directory listings. The Views module also allows you to control how the dynamic URL and title are displayed. The “%1” in the Title looks a bit funny; this will be replaced by the department name dynamically when the page is viewed (%1 means “the first context value for this view”).

    Finally, we do some path transformations to keep URLs consistently lowercase and dash-ified, even if the “real” department name contains capital letters and spaces.

    Table 3-22. Contextual filters for the Jobs view

    Setting

    Values

    When the filter value is not in the URL

    Display a summary (checking this will expose a bunch of other settings, but they can be safely ignored)

    When the filter value is in the URL or a default is provided

    Override title: Checked (in the text field that appears, enter “Jobs in the %1 Department”)

    More

    Case: Capitalize each word

    Case in path: Lower case

    Transform spaces to dashes in URL: checked

    Contextual filters configuration for the Jobs view

    Figure 3-39. Contextual filters configuration for the Jobs view

    Be sure to save the view when you’re done.

Note

We added only one contextual filter in our Jobs view. But you can add as many contextual filters as you like. They don’t even have to be the same type. This way, you can get multipage structures, each drilling down additionally on the items that should appear in a list.

We’re now finished with the Jobs view! The final view screen should look as pictured in Figure 3-40. Take a look at our view by closing the overlay and clicking the new “Available positions” link in the Main menu. After we add this contextual filter, our view contains a nice hierarchical structure! It should be similar to Figure 3-41.

Completed Jobs view configuration

Figure 3-40. Completed Jobs view configuration

The root level of the Jobs view, with a summary display contextual filter

Figure 3-41. The root level of the Jobs view, with a summary display contextual filter

Clicking on any of the options will take you to a filtered listing within that category, such as in Figure 3-42. Pay attention to the URL also as you move between pages. It should be similar to http://www.example.com/jobs/administration or http://www.example.com/jobs/athletics. This is the way arguments work in Views: the path we specify displays the summary view, then any “directories” (such as administration) under that URL are taken as arguments.

Inside the Filtered view, when the context “sciences” is passed in

Figure 3-42. Inside the Filtered view, when the context “sciences” is passed in

This concludes our introductory view, where we’ve used several features of Views. This example used a Page display, added some fields, and used contextual filters in a simple manner. In our next example, we’ll create a view that uses multiple displays, and gets a little bit trickier.

Applications View

The Applications view will serve both as a tool for administrators and as a reference for users. It will provide the following displays:

  • A listing of all job applications in the entire system as a single page

  • A listing of all applications for a particular job, displayed as a tab on the job page

  • A listing of applications filled out by the currently logged-in user, displayed as a block in the sidebar

Taking all these pieces together, the final view should display something similar to Figure 3-43.

The multiple displays of the Applications view

Figure 3-43. The multiple displays of the Applications view

Create the view and default display

In this view, we’ll be setting up several displays and then overriding the defaults within each display. By setting up a large amount of the configuration in the default display, we’ll save work when we need to change properties that are common to all displays.

  1. Start by getting to the Views administration area by going to the administrative toolbar and StructureViews (admin/structure/views). Click the “Add new view” link, and enter the settings from Table 3-23 into the wizard, then click “Continue & edit”.

    Table 3-23. Add view settings for the Applications view

    View setting

    Value

    View name

    Applications

    Description

    Checked; “A list of submitted applications, by job or user”

    Show

    Content of type Job application sorted by Newest first

    Create a page

    Checked

    Create a block

    Unchecked

    Page settings

    Page title

    Applications (default)

    Path

    applications (default)

    Display format

    Table of fields

    Items to display

    10 (default)

    Use a pager

    Checked (default)

    Create a menu link

    Checked; Menu: Navigation menu; Link text: Applications (default)

    Include an RSS feed

    Unchecked (default)
  2. Now we’ll set up some default fields. Click the “add” button in the Fields area. Check off the fields described in Table 3-24 and click “Apply (all displays).” Then configure each field’s settings, clicking “Apply (all displays)” once again after each screen.

    Table 3-24. Default fields for the Applications view

    Defaults: Field

    Values

    Content: Job

    (leave the defaults)

    Content: Post date

    Label: Application date

    Date format: Short format: 12/04/2011 - 9:30

There is one more field that would be very useful in this view: the name of the user who submitted the application. If we look for the username in the list of fields we can use, though, we won’t find it. The closest field in the list is “Content: Author uid,” and the help text underneath it states “The user authoring the content. If you need more fields than the uid add the content: author relationship.” The uid is only a number, like 4 or 206, and isn’t really that helpful. We do want more fields than the user ID number—we want the name—so we will need a new Views module trick that we haven’t used yet: Relationships. Figure 3-44 shows a diagram of how relationships work. All of our Job Application nodes have an author uid associated with them. We can use that ID to connect with the rest of the user information in the database, and then pull out the bits we want once we’ve created the connection.

If two objects share a bond, Relationships can pull in data from one to another

Figure 3-44. If two objects share a bond, Relationships can pull in data from one to another

  1. Using relationships is a two-part process.

    First, you must identify the relationship—that is, tell Views what your connector piece is, and second, you will need to use that relationship to add the fields or other data that you want to the view. Let’s create a new relationship we can use. Open the Advanced fieldset to expose more settings, and click the “add” button next to Relationships. “Select Content: Author” and click the “Apply (all displays)” button. Since all content will have an author, we can make the resulting query more efficient by checking the “Require this relationship” checkbox. Click “Apply (all displays)” once more, and that’s all there is to it. We have added in the relationship, and now we can start using it.

  2. Click the “add” button in the Fields section once again, and this time you will see more options than before. There is now a whole group of fields available in the User group. Select the User: Name field and click “Apply (all displays).” You will see that it is using the relationship we just created. Change the field’s Label to Applicant Name and click “Apply (all displays)” again.

  3. We now have all of the fields that we want for our view. Click the down arrow next to the “add” button and select “rearrange.” Put the fields in the following order and click “Apply (all displays)”:

    • Content: Post date

    • Content: Title

    • (author) User: Name

    • Content: Job

  4. Now we need to change one last, very important setting. The default access to this view is set to allow anyone with the “View published content” permission to see the view, but we want to allow only “editor” members on the site to have access to review all the applications. This is also why we put the menu item for this view in the Navigation menu and not the Main menu, meant for all users. In the Page settings section, click the “Access: Permission” link. Use the settings from Table 3-25 to restrict access to this display and click “Apply (all displays).” When you’ve finished, the settings should look as pictured in Figure 3-45.

    Table 3-25. Page display access restrictions for the Applications view

    Settings

    Values

    Access restrictions

    Role

    Role

    editor
    The Applications view so far

    Figure 3-45. The Applications view so far

    Warning

    Restricting access to the view only prevents unprivileged users from accessing the view display at http://www.example.com/applications; it does not prevent an unprivileged user from typing in http://www.example.com/node/4, where node 4 is a job application that is not hers. Protecting this kind of node-level access control requires the use of a node access module. See Taking It Further for some suggestions on resolving access concerns.

  5. Save the progress on the Applications view by clicking the Save button.

This concludes the default configuration of the Applications view. We have a basic view of applications on the site, which are displayed in a page, with a menu item in the Main menu, as pictured in Figure 3-46.

The Applications view page display in action

Figure 3-46. The Applications view page display in action

Create the Job Tab display

We’ve created a page containing all the applications on the entire site. Although this might be helpful for watching incoming applications, it’s not entirely helpful for our jobs’ contact people, who will be primarily interested in only the applications posted to one job. To fill this need, we’ll make a display that limits the applications to just one job, using a contextual filter. We’ll also need to create a new relationship to connect the application to the job being applied for so the contextual filter has something to work with. To make this page easy to find, we’ll add it as a tab on the job node pages (see Figure 3-47).

The Applications view displayed as a tab on a job node

Figure 3-47. The Applications view displayed as a tab on a job node

If you’ve left the Views administration area, return to it by going to the administrative toolbar and clicking AdministerStructureViewsApplicationsEdit (admin/structure/views/view/applications/edit).

  1. Click the “+ Add” link in the Displays bar, as shown in Figure 3-48, and select Page.

    Adding a new Page display to the Applications view

    Figure 3-48. Adding a new Page display to the Applications view

  2. The new display gets the name Page by default. To help distinguish it from the original Page display we created, we’ll rename it to Job Tab, because this page will be displayed as a tab on job nodes. Click the Page link next to “Display name” just below, change it to Job Tab, and then click Apply.

  3. To display the information required on this tab, we will need to override our default settings. We need to have a relationship to the job to which the applicant is applying, and a contextual filter to bring in the job ID. However, these settings are specific to this one display, and should not affect the default page we already set up.

    Fortunately, Views solves this with its display overrides concept. At the top of the configuration screen for each of our Views elements, there is a drop-down preceded by the word “For.” This defaults to “All displays” with the assumption that we want to update the settings across all of our view’s displays. To limit our changes to just this display, we need to select the override option, as pictured in Figure 3-49.

    Override settings for a View

    Figure 3-49. Override settings for a View

  4. First, let’s add a relationship to the application’s job so we can pull the job’s elements into our view. Open the Advanced fieldset, click the “add” button for Relationships, add the settings from Table 3-26 (shown in Figure 3-50), and click “Apply (this display).”

    Table 3-26. Default relationships for the Applications view

    Defaults: Relationships

    Values

    Content: Job (field_job)

    For: This page (override)

    Require this relationship: Checked

    Once you have applied your changes, you will see that you have an active override in the Views editor, indicated by the section title (Relationships, in this case) being italicized, as pictured in Figure 3-51).

    Relationship configuration for the Job Tab

    Figure 3-50. Relationship configuration for the Job Tab

    Overriding the Relationships portion of a view

    Figure 3-51. Overriding the Relationships portion of a view

  5. Similar to the Jobs view that we configured earlier, we can filter down the listing of applications by adding a contextual filter to the display. We’ll add a contextual filter that filters the list of applications to a single job node. Click the “add” button for “Contextual filters,” select “Content: Nid,” and use the values from Table 3-27. Remember to override these settings for just this display. The Content Nid contextual filter allows us to filter by one particular job’s ID. Here we’re using another feature of Views’ contextual filters: a validator. Views will check the node ID passed in to the URL and verify that it belongs to a job node. Click “Apply (this display)” when done.

    Table 3-27. The Job Tab “Content: Nid” settings for the Applications view

    Settings

    Values

    For

    This page (override)

    Relationship

    field_job

    When the filter value is not in the URL

    Display contents of “No results found”

    When the filter value is in the URL or a default is provided

    Override title: Checked; “Job Applications for %1”

    Specify validation criteria: Checked

    Validator: Content

    Content Types: Job

    Validate user has access to the content: Checked

  6. We set our view to “Display contents of ‘No results found’,” but this is blank by default. Let’s add something more useful there. Click the “add” button next to No Results Behavior (right under Relationships). Select “Global: Text area” and enter the following text: “No applications have been submitted.” Then, click “Apply (all displays).”

  7. Now that we’ve set up an argument for this display, we need to give it a URL. Use the settings from Table 3-28 to set up the Page settings and click Apply. We don’t need to worry about overriding here, because these settings are always per display.

    Table 3-28. Job Tab display page settings

    Job Tab: Page settings

    Values

    Path

    node/%/applications

    Menu

    Type: Menu tab

    Title: Applications

    Similar to using %1 in the title of the contextual filter, we’re using the percent symbol to specify that the first context value will be in the middle of the URL. You can use this approach to add tabs to user pages also, such as user/%/my_display, or any other page in Drupal with a dynamic path.

  8. And finally, we no longer need the Job listed on this display; it would be redundant, as we’ll be looking at the job directly. Click the drop-down arrow next to the “add” button in the Fields section, and select “rearrange.” Override this section for this display by changing the For field to “This page (override).” Then click the “remove” link for the Content: Job Job field, and click “Apply (this display)” to save your changes.

    Warning

    If you want behavior specific to one display and not others, be sure to change the For setting to “For: This page (override).” The Views module’s settings default to affecting all displays within that view. You can end up accidentally deleting this field from more than one display if you’re not in override mode. If that happens, you will need to add the field back to the main Page display, and then remove it again from the Job Tab display.

  9. Click the Save button to save the view, which should now look like Figure 3-52.

    Applications view with new Job tab

    Figure 3-52. Applications view with new Job tab

We’ve now added a tab to all job nodes (for users in the “editor” role). Visiting a node that has applications should look similar to Figure 3-47, shown earlier.

Create the Applications block display

The last display that we’re going to assemble will be available to all users of the site. It will be a block that will show all the job applications that the currently logged-in user has submitted on the site. We’ll also change the style of this display from a table to a list layout, because it will need to be displayed in the narrower sidebar column. The final display will look similar to Figure 3-53.

The front page with the User Applications display as a block in the right sidebar

Figure 3-53. The front page with the User Applications display as a block in the right sidebar

If you have left the Views configuration screen, return to the Applications view by going to the administrative toolbar and clicking StructureViewsApplicationsEdit (admin/structure/views/view/applications/edit). We’ll start by adding a new display to this view:

  1. Click the “+ Add” link in the Displays bar and select Block from the display list.

  2. Now we’ll need to override some settings. Click the Title link to see the configuration screen, change For to “This block (override),” and change the title to My Applications. Click “Apply (this display).”

  3. Change the Format to an unordered list by clicking the Table link in the Format section, and once again changing For to “This block (override),” and selecting “HTML list” as the format. Click “Apply (this display).” We can keep the default configuration, so just click “Apply (this display)” again to complete the change.

  4. Now configure a description on the block that will show up in the block administration area. Under “Block settings,” enter a block name of User Applications and click Apply.

We’ve now set essentially three names or titles for this block. Here’s a rundown of where each title will be displayed:

Display Name

Used within the Views interface as the name of the display. Shown in the Displays bar at the top of the Views editing screen.

Title: Title

Used as the block title when it is displayed to the end user.

Block settings: Block name

Used to refer to the block when arranging blocks by going to the administrative toolbar and clicking StructureBlocks (admin/build/block).

Because this is a block that will live in the sidebar, we’ll want to display far fewer fields so that it fits nicely in the narrower region of the page. To do this, we’ll need to override the Fields area of this view.

  1. Click on the down arrow next to the “add” button in the Fields section and select “rearrange.” Select “This block (override)” and then click the “remove” link for the “Content: Post date Application date” and “(author) User: Name Applicant Name” fields. Click “Apply (this display)” to save your changes.

  2. Configure the remaining fields as indicated in Table 3-29. Since we already did an override in the Fields section, by removing a few fields in the previous step, you will notice that the configuration for these fields defaults now to “This block (override).” Once you override any part of a section, everything in that section is considered to be in override mode.

    Table 3-29. Block fields in the Applications view

    Block: Field

    Values

    Content: Title (Application title)

    Create a label: unchecked

    Content: Job (Job)

    Create a label: unchecked

    Formatter: Title (no link)

  3. Reorder the fields by clicking the down arrow next to the “add” button and selecting “rearrange,” so that the job comes first, then the title of the application.

  4. Because we need to limit this display to job applications by the current user, we need to add a filter to the display. We’ll leave the two existing filters in place—“(Content: Published (Yes)” and “Content: Type (= Job application)”—and add a single new filter for User: Current. Make sure we are using an override by selecting “This block (override)” then check off the User: Current filter and click “Apply (this display).” Select Yes for “Is the logged-in user” and click “Apply (this display).” This step will allow the block’s contents to change dynamically depending on who the currently logged-in user is.

  5. One last item, which is easy to overlook, is that our poor regular users on the site will not be able to see the view. We have the permissions set up to only allow access for editors on the site. In the Block Settings section, click the Role link next to Access, select “This block (override),” then change the selection to Permission. The permission defaults to “View published content,” which is fine, so click “Apply (this display)” once again to finish.

  6. Save the view, which should now look like Figure 3-54. Your configuration for the User Applications block display is now complete.

    The completed Block display for the Applications view

    Figure 3-54. The completed Block display for the Applications view

  7. By adding a new Block display, we’ve added a block to the Drupal site. Before it is visible anywhere, though, we need to enable the block. In the administrative toolbar, click StructureBlocks (admin/structure/block) and scroll down to the Disabled section to find your new block, User Applications. Place it in the Sidebar Second region and save your changes.

Whew! After that whirlwind tour of views, you should now see a sidebar block showing any jobs you’ve applied for.

Taking It Further

The basic job website that we’ve built only touches on the surface of the capability of Field and Views. There are a lot of possibilities for extending the functionality of this job site by adding more fields to both the Job and Job Application content types. Here are a few modules that could be used to take things a bit further with our job board:

Automatic Node Titles

This module provides support for creating title templates for nodes. For example, rather than having users manually enter a title for their applications (which may result in nonsensical things such as “Hire me!”), this module could ensure that all application titles follow a standard format automatically, such as [author-name] – [job-title].

Node Reference URL Widget

This module adds a new field widget for node references. With this, we could display a link on our Job content that says “Apply for this job,” and the link would take people to the application form with the correct job already selected so they don’t have to figure out which one to select from the list.

Content Access and private files

Right now, all job applications submitted to the site are public and searchable even by anonymous users. That’s no good, since résumés are bound to contain sensitive information. Content Access is one example of a node access module, and can limit viewing of job applications only to site editors. When coupled with Drupal core’s private files feature, configurable at ConfigurationMedia“File system” (admin/config/media/file-system), you can specify that file fields are able to save uploaded files to the private files directory instead.

Field Permissions

Another way to protect certain private application information from displaying to unprivileged users, the Field Permissions module can selectively block fields from being edited or viewed, depending on the visitor’s role.

Summary

This chapter taught you how to use two of Drupal’s fundamental “building block” modules: Field and Views. These modules constitute the cornerstone of Drupal’s power and are used extensively throughout the rest of the book. Field is used to model your website’s content by adding extra fields to hold different properties, and Views is used to display lists of your website’s data.

Besides the basic features of these modules, this chapter also introduced you to the methodology for Drupal site building. Rather than installing monolithic packages, in Drupal each module provides specific functionality, and works together with other modules to enhance their functionality. As we created fields for our different content types, References was working together with the core Field module. While making listings of content, Views retrieved information provided by both core modules and References. This sort of cooperation between modules serves as the foundation for the rest of the book, as more modules join the party and give new shape to our sites.

Here are the contributed modules that we referenced in this chapter:

These are some other resources that we referenced and community resources for learning more about the new concepts introduced in this chapter:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset