A Single Node on Multiple Dates in Drupal


If you’ve ever used the Date module in Drupal 7, you’re probably familiar with the many features available.  

One component that was specifically necessary for a recent project was the ability to have multiple dates on a single node or recurring events.  The Date module makes this easy enough by providing Date Repeat API and Date Repeat Field modules in the packaged download.

Setup a Node for Recurring Events

When these modules and their dependencies are enabled (you’ll also want to enable Date Views), add a new date field to a content type.  To allow the recurring date rules to be applicable to the content type, select ‘yes’ from the Repeating Date options.

The image below represents an example of a new event that will take place every Friday for the next eight weeks.

When you go to Manage Display for this content type, there are a few options available for presenting the date information on event pages.  You can choose to show or hide the repeat rule, set a certain number of values and so forth.

List the Upcoming Events

The following will explain how to build a basic unordered list of upcoming events for an events page.  A new view will be created as a block and placed on this node.  In this view, add a date field and set the values as necessary.  The one thing that is crucial here is to uncheck “Display all values in the same row” under Multiple Field Settings.  This will allow the results to show the same event with each date as a separate result.

Protip: Remember, you can set custom date/time formats under Configuration > Regional and language > Date and time > Formats that can be used for default or custom date types.

Set this block via context to display on the events page and navigate to this node to see this list of upcoming events.

Looks like what we wanted!  Although, when one of these recurring event links are clicked, it displays all of the dates in which the event happens.

It’s possible to manipulate this in Manage Display; however, there’s no option for displaying the particular date that had been accessed by the user.  It would be a clearer user experience to only showcase the date that the user had clicked through.  Since the node content will always remain the same for this event, it seemed overkill to have something like a node repeat/duplication module.  Instead, creating custom link paths that contain a relative date query proved easy and quick to implement.

Rewrite Title Results with a Custom Path

In the events view that was previously created, add two more fields and exclude them from the display.  A Content: Nid field and an extra Content: Date field will be used for the title path instead of the original link.  Rearrange the fields so that these two additions are above the title field. This will allow their replacement pattern tokens to be accessed.

Edit the Content: Title field.  Be sure to uncheck “Link this field to the original piece of content” in this field to make sure that the view can get a custom link.  Under Rewrite Results, check “Output this field as a link” and add the replacement URL in the Link path.  Set the path as node/[nid]?date=[field_date_1] - be sure to check that your replacement patterns are correct by clicking on the Replacement patterns drop down to see their token names.

Save the view.  There is now a date query appended to the node path based on the date format option.  In the view, you can change this format under “Choose how users view dates and times” on the excluded date field.

Add a preprocess_field to the theme’s template.php to check if a query has been set.  If it has, empty out the original field array and replace with the date query value.

[prism:php] function theme_preprocess_field(&$variables) { $element = $variables['element']; if (isset($element['#field_name']) && $element['#field_name'] == 'field_date') { // Check if date value is set in query string. if(isset($_GET["date"]) ) { // Remove original data from array. $variables['items'] = array(); // Set variable from query date. $queryDate = $_GET["date"]; // Output date value. $variables['items'][0]['#markup'] = $queryDate; } } } [/prism:php]

Now, when a user selects an event from the list, the event’s page pulls the date set in the query string.  If the user were to access this page without the query string, they would get the fallback of what’s been set in the Manage Display default of this content type.

And there you have it! It would be great to see this become something that can be set within the UI in a future release, but this method helped solve the problem quickly, keeping all of the event's content editable in one place.