Using Views to generate an MLA bibliography

Once you're comfortable using Views to pull together lists, tables, and visualizations of data from individual nodes, users, and taxonomies, you can make use of some of the advanced Views settings to pull in data from nodes that are referenced using a Node Reference field, and use information from the path (for a page display) or the current page (for a block display) to limit your view results to information relevant to a particular context. As an example, let's take the task of generating MLA citations for books, on a site that contains Book, Person, and Publisher content types.

NOTE: If your project involves bibliographic data, you should consider using the Biblio module to manage that data. It will automatically provide MLA citations (in addition to a number of other formats), as well as the COinS metadata that Zotero can ingest. The Biblio module has upsides and downsides; the latter include the fact that it doesn't integrate with Feeds for data import.This example comes from a knowledge base project that's not bibliography-centric: people and publishers are as important as the scholarly products, and consequently have their own content types. The Biblio module is an awkward fit, so re-creating the features they needed using Views was a better solution.

Let's start with three content types and their fields:

Person content type

  • First name (text)
  • Middle name (text)
  • Last name (text) - required
  • Personal webpage (link)
  • Short biography (long text)
  • Photo (image)

Publisher content type

  • Name (Drupal Title field)
  • Location (Location field)
  • URL (link)
  • Email (email)
  • Short description (long text)

Book content type

  • Title (Drupal Title field)
  • Author (node reference to Person content type, multi-value)
  • Publisher (node reference to Publisher content type)
  • ISBN (text)
  • Year (integer)
  • Pull quotes (long text, multi-value)
  • Tags (term reference)
  • Cover art (image)

For reference, consider the formatting of an MLA citation: Nabokov, Vladimir. Lolita. New York: Putnam, 1955. Print.

To create such a citation for a book stored in this Drupal database, you need to pull in data from all three of the content types: the publisher's location is only stored in the Publisher content type, and the constituent parts of the author's name are only stored individually as part of the Person content type.

Basic view settings

When you create a new View (Structure > Views > Add new view, or admin/structure/views/add), you want to show Content of type Book. Assuming you want to make the citation appear on the Book node (rather than on a page by itself), uncheck the option for Page, and check the option for Block. (Once you've created this view, you can specify where you want the block to go at Structure > Blocks, or admin/structure/block) For Display Format, choose Unformatted list of fields. From there, choose "Continue & edit".

For MLA monograph citations, the number of authors does make a difference. The easiest approach is to start with a view Display targeting single-author monographs, and clone and modify it for additional authors. Even a single-author monograph requires you to set up Relationships in order to pull in data from the author and Publisher nodes. Click on Advanced settings in the far right column to access Relationships.

Relationships

This area of the Views configuration allows you to indicate that you want to be able to access data stored in a different node than what you're currently displaying. In this case, even though you've filtered your results to Book nodes, if you create relationships for the node reference fields within the Book content type that point to other content types (ie, the Author field and the Publisher field), you can access the data stored in the First/Middle/Last Name fields within the Person content type, and the Location field for City within the Publisher content type. Without these relationships, you'll only be able to display the (inseparable) full name of the author, and the name of the publisher-- which are the only things actually stored in the Book content type, whose content you're displaying.

Add a relationship, and look for Content: Author (field_author). Do NOT choose Content: Author-- that refers to the Drupal Node Author (ie, the user who added the book to the database) and will instead give you access to fields in their user profile. To make sure you've chosen the right field, look for one that says "Appears in node:book" underneath.

On the configuration screen for this relationship, you may want to give the relationship a more meaningful identifier and administrative title (accessible under the "More" toggle), because you're going to have to add this same Content: Author (field_author) relationship multiple times, once for each of the (potential) first four authors of the monograph. Let's use "author_1" for the identifier and "Author 1" for the administrative title. To indicate that you want to pull values from the Person node for the first author listed for the book, set the Delta value to 1. The Delta value refers to the order in which a particular entry occurs in a multi-valued field: the first author added has a Delta value of 1, the second has a value of 2, etc.

You need to set up four different relationships, each with a different Delta value (1-4). Even though the MLA citation format only shows the names of up to three authors, you need to add the fourth relationship in order to check and see whether a fourth author exists, in which case you'll set the view to display "et al" after the first author.

In addition to the authors, you also need to pull in the city the book was published from the Publisher node. Add another relationship for the Publisher node reference field, Content: Publisher (field_publisher). Set the Delta value to 1, so your bibliography listing doesn't look strange if the publisher has, for example, locations in New York and London.

Before moving on to the next configuration step, you should see the following relationships:

  • Author 1 (configured as Content: Author (field_author), identifier author_1, delta value 1)
  • Author 2 (configured as Content: Author (field_author), identifier author_2, delta value 2)
  • Author 3 (configured as Content: Author (field_author), identifier author_3, delta value 3)
  • Author 4 (configured as Content: Author (field_author), identifier author_4, delta value 4)
  • Content: Publisher

When you configure each of the author relationships, you can toggle down "more" and use a different value for each administrative title (e.g. mirroring the identifiers), to make it easier to see what you've configured at a glance.

Filters

We're starting with creating a citation for a single-author monograph, which means we have to add filters to block all monographs with more than one author.

Already, due to the Views module default behavior and the initial view configuration, you should see two filters: one for Content: Published (yes) and Content: Type (Book). Add a new filter for Content: Last name. Because this filter is going to be different for each of our displays, look at the very top of the configuration overlay (it's easy to miss) and change "All displays (except overridden)" to "This block (override)" before adding the filter. You know it's correct when the "Apply" button changes to "Apply (this display)". On the settings screen for this filter, choose "author_2" in the Relationship drop-down, and for the Operator, choose "Is empty (NULL)", and again select "Apply (this display)". This filter looks to see if the last name of the second author is null, and if not (ie, if it's a single-author book), it displays the book. This could be problematic if you have any authors without last names, but the last name field is required in the Person content type, so that cannot happen.

Fields

At this point, the view should be displaying the titles of all books with only one author. Because MLA citations require more information than the title, we need to add more fields. All of these fields are going to be relevant regardless of the number of additional authors, so you can add them without changing the "All displays (except overridden)" setting.

  • Content: Last name
    • The following configuration settings apply to the last, first, and middle name fields.
    • For Relationship, choose "author_1"
    • Uncheck "create a label"
    • If you don't specify the relationship, this field will always be blank, because you've filtered your results to the Book content type, and the Book content type doesn't have this field. Specifying the relationship allows you to pull in the value from the Person node corresponding to the Person node specified in the author node reference field.
  • Content: First name
  • Content: Middle name
    • The MLA citation format requires that the middle name be represented only by an initial, so you need to toggle down Rewrite Results. Check "Trim this field to a maximum length", and specify that length as 1. Uncheck "Trim only on a word boundary" and "Add an ellipsis" before applying the settings.
  • Location: City
    • For Relationship, choose the relationship referring to the publisher
    • Uncheck "create a label"
  • Content: Publisher
    • Uncheck "create a label"
    • Formatter: title (no link)
  • Content: Year
    • Uncheck "create a label"
    • For "Thousand marker", choose "none"
    • The "Thousand marker" setting is only an issue if you've used an integer field for the year. If you've installed the Date module, and created a Date field that only stores a year value, you won't have to specify this setting.
  • Global: Custom text
    • Uncheck "create a label"
    • The value for the custom text field should be " Print." (Leave off the quotation marks, but include the space in front of the word.)

Now, for each book with a single author, you should see an unformatted list of fields, one per line, with all the data you need.

Rearranging fields

Click on the little down arrow next to the "add" button for fields, and choose "rearrange". Drag and drop the fields into the following order:

  • Content: Last name
  • Content: First name
  • Content: Middle name
  • Content: Title
  • Location: City
  • Content: Publisher
  • Content: Year
  • Global: Custom text

Format

  • In the Format area of the view configuration, click on "Settings" in the line "Show: Fields | Settings".
  • Check the checkbox for every field, under "Inline Fields", and apply to all displays.

Note: if you add more fields later (e.g. if you clone the display, and add another set of first, middle and last name fields and use the "author_2" relationship, to do a listing for two-author books), you'll need to go back to this area of the configuration and check the boxes for the new fields, too.

All the fields for each book should now be on the same line, but the data is in the wrong order, and is still missing a lot of formatting and punctuation. Also, you may notice that even though you didn't put a space in the "Separator" field, all fields are separated by a space. In this case study, even if you use field rewriting (described below), you'll run into problems with single-author works where the author lacks a middle initial, because a space will appear before the period that occurs after the author's name.

The fact is, this relates to an issue with how Views handles inline fields. This thread in the Drupal forums makes it clear that the developers have no intention of changing that, or making it an option that's easy to control within the Views UI. That thread also has suggestions for how to modify your theme template with some easy PHP to resolve this problem.

This won't be a problem for most views, but for this case study, let's assume you've added the theme template described in the thread above. Adding that template removes the spaces between fields, which means that in most cases you'll have to add it back in (there is, after all, both a comma and a space between an author's first and last names in an MLA citation), but this time you'll control where and when it appears.

Rewriting fields

Most of the fields need to be rewritten, to replace the space that was eliminated in the theme template, and to add punctuation.

  • Content: First name
    • In the field configuration display, toggle down Rewrite results and check "Rewrite the output of this field". In the field below, put in the text between the curly braces, including all spaces and punctuation: {, [field_first_name]} (ie, put in a comma, space, and the replacement pattern for the first name field.
    • Note: It's important that you get the field name right, so if you're unsure, scroll to the bottom of the text are and toggle down "Replacement Patterns", which will show you the values you can use.
  • Content: Middle name
    • Rewrite the results as { [field_middle_name]} (ie, put a space then the replacement pattern for the middle name)
  • Content: Title
    • Rewrite the results as {. <em>[title]</em>.} (period, italics, replacement pattern, close italics, period)
    • Note: If it weren't for the fact that you need to insert a period at the end of this field, you could italicize the title using the "Style Settings" toggle-down in the field configuration, by checking "Customize field HTML", and selecting "EM" from the drop-down list. Because a period is needed after the title, though, you have to use "Rewrite field" anyways, and you might as well put the italics there.
  • Location: City
    • Rewrite the results as { [city]:}
  • Content: Publisher
    • Rewrite the results as { [field_publisher],}
  • Content: Year
    • Rewrite the results as { [field_year].}

Rewriting fields: a different approach

Rewriting every single field is time-consuming, especially when there's more fields than a single-author monograph (e.g. a multi-author article in a multi-editor collection). As an alternative, you can skip all those rewrites and instead check the "Exclude from display" box for every field. This will hide all the fields, resulting in an empty view. Next, add a "Global: Custom Text" field, and enter

[field_last_name], [field_first_name]. <em>[title]</em>. [city]: [field_publisher]. [field_year]. Print

This doesn't work well if you're not sure your data is 100% consistent. For instance, if you forget to enter the location of a publisher, your citation will look like Lolita. : Putnam, 1955. Print. You'll need to add a filter to ensure that the middle name field is empty, then clone the view display and replace the filter with a filter that checks to make sure the middle name field is NOT empty, and modify your "Global: Custom Text" field to include [field_middle_name] in the right place. While this approach does save you work insofar as you don't have to rewrite each field, it leads to a proliferation of view displays (and, ultimately, blocks to enable and position), with two displays (one with and one without the middle name) for each variant (one author, two authors, etc.) In light of this, it's probably the less good solution.

Contextual filter

Now you have a view showing an MLA citation for the 10 most recent single-author monograph in the database (or, as many as you've specified under the Pager configuration), but you need a "contextual filter" to indicate that you only want the block generated by this view to display the citation for the book whose node the user is currently looking at.

When you're using Views to create pages, the contextual filter can get its value from the path (the URL). When your view creates a block, you generally need to specify a default value that tells the view what data to use as the contextual filter. The best way to indicate that you want to base the output of a block's content on the node where the block will be displayed is using the "Content: Nid" contextual filter.

For a block display, Drupal immediately warns you when you add this contextual filter "This display does not have a source for contextual filters, so no contextual filter value will be available unless you select 'Provide default'." To do this, click the "Provide default value" radio button, and choose "Content ID from URL". Conveniently, this does NOT mean that you have to configure the path to include the content ID value: your block will still display the right value if you've created a nicer-looking path alias (e.g. mysite.org/books/current-book-title). Then, choose "Apply (all displays)".

Adding a contextual filter will eliminate your ability to automatically preview all results. In order for any results to appear, you need to add a Book node ID to the "Preview with contextual filters:" field underneath all the Views configuration options.

If you edit any Book node and look at the URL, it will show you the node ID as part of the path (e.g. node/123/edit). Be sure you've chosen a node with a single author, otherwise you (correctly) will see no results, because of your filter settings. Because it limits the number of results you see, thereby reducing your opportunities to spot problems caused by inconsistent data, you should add contextual filters last when you're configuring views.

Title & Display Name

One final thing you may want to configure is the title for the block, which will appear in whatever stylized way block titles usually appear in, depending on your theme and the region you choose. By default, Views will use the name of the view, which might not be the best option in all cases.

You may also want to make the display name more specific, changing it to something like "Book citation, 1 author" since you'll be cloning this display to modify the view to accommodate additional authors.

Enabling the block

Go to Structure > Blocks and assign "View: Citation, 1 author" to the region where you want it to appear. You can optionally configure it to only appear on Book nodes (using the Pathauto settings you've created for that content type), but it's not actually necessary, since the view won't appear without a valid contextual filter, and a valid contextual filter can only be provided (in this case) by a single-author Book node.

Modules: