Nov 26 2013
Nov 26

Our library is always open…*almost always.  Things happen (like Thanksgiving, Christmas, New Years) and sometimes we even have extended hours and we stay open even longer. Altogether, we have ~ 14 weeks/year that have “non-standard” hours.

In the past, we had to manually managed our weekly hours by updating a single, static piece of panel content.


You can probably imagine the problems we had trying to maintain this accurately – every week that we had deviated hours the desk supervisor had to submit a request for us to change them. We might be busy with other projects, might not get to it right away, the hours on the home page might be wrong, the desk supervisor might have to submit another request, and then pretty soon they might have to ask us to change it back to the regular hours…

Too much hassle.

We knew we needed dynamic content, and because our homepage was built as panel page, we were ready to pump a view into the hours pane. The question was how to set up the content so that we wouldn’t have to touch it…at all.

We landed on a combination of the office hours and scheduler modules.

Office hours gives us an “Office hours” field type. Since we want to display hours on our home page in weekly chunks, we create a “Weekly Hours” content type and add that field.

weekly hours content type

And we set the default values for this field to the library’s standard opening hours – usually when we have a week with weird hours, it’s only going to affect a couple of days so this helps cut down on data entry.

default office hours field settings

Then the scheduler module kicks in – the content type must be configured to allow nodes to be scheduled for publication. Check a couple boxes and start adding content.

scheduler options of content type

Since the goal here is for us not have to touch the hours (at all) we enlisted the desk supervisor to enter the data – with a couple of tweaks to the permissions table and a 5 minute demo (add node >> toggle hours >> set publish date for sunday evening before given week >> set unpublish date for sunday evening of given week >> click save) he was good to go. In all, he added 10 “Weekly Hours” nodes, including one with the library’s standard opening hours, because that was as far in advance as the library had planned its opening hours.

scheduling data

With the content added, we were able to start manipulating views so that we could display it on the homepage. Since all the nodes (except for the one with standard hours) had an unpublish date, we could configure a view to output only nodes of the type “Weekly Hours” that are published, sorted by the post date descending, displaying one at a time. That way, when a week of non-standard hours is published, it’s displayed in place of the standard hours, which were published previously but are never unpublished.

view for current hours

By creating a block display and setting it to only output the “Office hours” field, we should be all set. If there’s any simple formatting, re-ordering, etc. that you want to do to the hours, you should check in the field settings in the view. The office hours module has substantial integration with views, and gives you a lot of flexibility in how you want to display the hours.

highly flexible field settings for office hours

After that, we view block into a panel and it takes care of itself – here’s the final result on our homepage:


One cool feature that we may implement for mobile is the current hours display. In the view configuration for the office hours field we can set the number of days to show – by setting only the next open day to be displayed, you’ll get a view that can be formatted something like, “The library is open today from: [*]”

current hours today display office hours module
Nov 22 2013
Nov 22

Ever since we launched our site re-design, we’ve had a pretty steady flow internal change requests – add links, change fonts, re-style buttons, adjust layouts, modify permissions, etc.

We were trying to process these requests through a ticketing system that we built on our staff intranet in Drupal 6 – it basically allowed us to toggle tickets between open/closed and send emails when we were finished. With requests piling up (some of which overlapped with one another and/or were vaguely articulated and/or were out of our control anyways) this system wasn’t cutting it. We decided to scrap it and develop a new workflow in Drupal 7 with three questions in mind:

1) How can the requestor  clearly communicate what it is they actually want us to do
2) How can we clearly communicate what it is we’re actually doing
3) And how can we, as the general put it, start “hitting a small nail with an awfully big hammer”

The first two issues were solved easily enough: we enabled comments on the “Web Request” content type. When someone creates a node of that type, we can sniff out what they need with some probing in the comments area. The comments allow for transparent dialogue, so long as you have an effective method for distribution.

Enter the awfully big hammer…

Using a combination of rules, views, display suite and user reference fields, we gave node authors the ability to create email lists specific to the requests they create. With the click of a button they can message as many of their colleagues as they choose, giving them the gift of email at every step of the request.

Here’s how we did it:

First we created a form – we set up a content type for “Web Requests” – we were going to use entityforms but couldn’t since we needed commenting. We added fields for the data we wanted to collect (request title, details, link, and screenshots). We also created administrative fields (for things like UX data, project tagging, etc.) that are only visible to the web team, and therefore don’t appear on the node/add form that requestors use.


The most important field (for the email list) is the user reference field – what we termed “Stakeholders” is a selection of users of a given role formatted as checkboxes, with no restriction on the number of values.


The stakeholders appear on the form listed by name – that works for the users filling out the form, but not for rules, which will need their email addresses. Using display suite, we can configure a custom output for the stakeholders field when it is used as a token. In the “Manage Display” screen, you can specify custom display settings. Since we’ll be using tokens in the rules and views configurations we want to customize that to get the user’s email.


So the token display for the field needs to output [user:mail]


With the content type and fields configured, we’re ready for rules.

We want “Stakeholders” to be notified when a new request is created. So, we add a rule that reacts on saving new content and triggers an email message. By adding a condition that states that the content has the stakeholder field, we can get the token (mentioned above) and use that as one of the recipients for the email. But the email action will only pass through one of the values. That means only one person will be emailed, and that’s not good enough – we need everyone getting these emails. Rules allows us to loop actions, but not without a view that contextually displays content, which in this case is a list of stakeholder email address.

So we create a new view of content – the only field we need is a stakeholders field that has a custom formatter of tokenized text and outputs [user:mail]


The next step is to set a contextual filter that acts on the content node id (nid) – this should generate a list of stakeholder email address per node. Preview it to make sure by passing the view a nid.


In order to call the view in rules, we have to give it a rules display. This also allows you to specify row variables – the important thing in this case is that we use the rendered result and the data type is text.


With the view in place, we can go back to the rule we created and call it as a views loop.


Add the email action to that loop and you’re set.


Each event that triggers an email will have its own rule, but you can use the same view/view loop structure for all of them, except comments. To get the stakeholder addresses to work in an email that’s set off by a comment, you have to create another view. This will be a view of comments that is configured almost identically to the stakeholder view, but with a relationship that joins comments to content so that you can use the nid filter.


About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web