Developing an events calendar

This started as an outline for a quick presentation at the local Drupal users’ group. Turns out I had more to say.

The Current Situation

Our current campus events calendar is a set of half a dozen Google Calendars. Each calendar has a manager; some of the calendars are “open”, which means that people can submit information using a web-based form and then the manager either adds the item to the Google Calendar or asks one of our students to. Sometimes events are duplicated with conflicting information.

Featured events on our home page are managed entirely separately from the rest of the calendars. Sometimes the events have been in the campus calendar. Sometimes they haven’t!

The Academic Calendar at a glance is managed separately from both of those. This information is core to student life, but isn’t handled in a consistent way across all of the calendaring systems.

Campus holidays are listed not just in those three locations, all managed separately, but also as a separate list on the Human Resources site.

What we built was a single Drupal-based calendar to integrate all of these systems.

The Content Type

The fields are organized into tabs with Field Group.

The description has a very lightweight WYSIWYG with CKEditor: just bold, italic, lists, and links. We’re using Media to manage the image and flier fields; at the outset I’m being very simple with those, since it’s a new feature for the campus calendar. All of the images will be displayed using a single simple image style.

The Date field includes a repeat option, which can be tricky to use in Views but works pretty well most of the time. I ended up adding an “Academic Quarter” field for some specific events; it’s a kludge, in my opinion, but academic calendars really don’t match anything else out there.


This isn’t really a Drupal thing so much as it is a user research thing. I discovered pretty quickly that the Google Calendars weren’t going to work as categories. In particular, I wanted to generate the Academic Calendar at a glance automatically, but the Academic Google Calendar had too many superfluous events. In fact, we discovered that there were literally two different definitions of “Academic Calendar”!

After looking at all of the calendars and their descriptions, we decided instead to run a card sort. We printed out cards with about 75 randomly selected events and had groups of students organize them into sets. After looking at the results and trying a few things, I ended up creating a two-dimensional Taxonomy system: categories and formats.

The Academic Calendar at a glance is then a View built on an intersection of those: “Deadlines” that are either Holidays or Academic events. We’ve also given users filtering tools so they can drill down to find what interests them.

To make sure we’re using consistent descriptions, the page describing the categories and formats is actually built with Views and Insert View, displaying the taxonomy term descriptions. For my own ease of use, I added edit links, too.

Importing Events

The Date iCal module in combination with Feeds made it really easy to import all of our Google Calendars, which was great for testing out ideas. I also built a sort of rough bulk editing view for adding information to the imported items, which was mostly used by me and by our student workers.

I also create a CSV import format specifically for bringing in a bunch of dates related to academic quarters, so that we can import them all at once instead of creating them one at a time. On this one I used Feeds Tamper to set the category and published state.

Roles & Rules

By using the CAS module with the Workbench Moderation module, anyone on campus can now submit an event directly, but calendar managers will approve them before they go live.

So we have three roles: authenticated, which is anyone who can log in through CAS, calendar approval, which more or less matches the old set of calendar managers, and administrator, which is a few people in our office.

We’re using Rules to handle notifications for the calendar managers. Any time someone who isn’t a calendar manager or admin submits an event, an email will go out to all of the calendar managers.

That same Rule also shows a message when an event is submitted, explaining the moderation process.

The Calendar Module & Styling Dates

We’re using the Calendar module to handle the daily and monthly pages. I like how it builds a calendar, but I have some frustrations: I have not yet figured out whether it’s possible to make the days clickable on the monthly calendars, which made the mini-calendar pretty much useless. Also, styling the calendars can be pretty tough: there’s a lot of awkward specificity to overrule if you want it to look different from the defaults.

Similarly, the built-in markup in Date fields is odd at best and we’ve had to work around it quite a bit. I’m hoping to look at overriding the markup with template functions, but I’m not super-happy about that.

Views, Views, and More Views

As I mentioned, the daily and monthly pages are Calendar views. The holidays are a pretty simple table view, restricted by category and grouped by year.

If you haven’t done much work with dates in Views, this is a place where creating date formats comes in really handy. The date is added twice: one time to display it in the format we want, in the other formatted as just a year for grouping.

The academic calendar at a glance does something similar, but with a more complicated category selection criteria and no grouping. But I created a contextual filter so that there’s pages for each quarter. A weird thing about academic quarters is that they sort of overlap: people start registering for the next quarter while the current one is still happening. So sometimes you want to see the flow of dates, and sometimes you want to see just a single quarter’s information. This hits both options.

The events by category page is a simple listing grouped by month with an exposed filter. I’m using Better Exposed Filters to get checkboxes. There’s a bug in the most recent versions of Views for Drupal 7, by the way, that exposes some Views editing text to visitors. The way around it for now is a template function.

We also have a pretty simple View for highlighted events. On the calendar site, it’s a list, but we also have an XML feed using Views data export that will be used in our current CMS to display those events on the home page and on the current students page. The highlighted events are those marked “Promoted to front page”, since that’s pretty easy and built in.

There isn’t a good way to separate out the ability to moderate from the ability to promote without adding another module, so for now we’re going to manage socially. There’s only a few calendar managers: we can tell them not to touch the button, and we can check on it pretty easily.

Features, Git, and Continuous Integration

This is our first project working with our colleagues in Application Support on having a development to production workflow. We’ve got a Feature built for the calendar’s structure, including all the things you can set with Strongarm.

In the test site, I’m making changes and trying new ideas, then recreating the feature with a new version number.

Then I commit it and push to our internal Gitlab site – which is also where we have all of the theme changes, both the CSS that the designer has been working on, and the template changes I’ve been working on. All of the commits happen on the dev branch.

Dave set up a deploy script to make all of those changes live on the test server, so once the commit is pushed, it fires off the script.

Then I go to Gitlab and make a merge request when I’m ready for all those changes to go into the production site. I approve my request J and then it’s in production. It’s been pretty smooth so far and I’m pleased with the process.

Next Steps

Next week we’ll be doing training with the calendar managers and a separate training and meeting related to the Academic Calendar(s). We’ve actually decided not to do a final iCal import for the last couple of weeks of entries specifically so that the calendar managers can get some practice and familiarity.

I’m working on a short write-up for calendar visitors to help them understand the changes. I’m also prepping some redirects and changes to our existing CMS to go live on the day of the switchover.

The week after next, we should be able to go live. After that we’ll be keeping an eye on things and listening for both problems and ideas. I imagine we’ll have a few weeks of tweaking and updating; there’s always things you don’t find until something is in front of people!

Modules Mentioned

  • Better Exposed Filters
  • Calendar
  • CAS
  • CKEditor
  • Date
  • Date iCal
  • Features
  • Feeds
  • Feeds Tamper
  • Field Group
  • Insert View
  • Media
  • Rules
  • Strongarm
  • Taxonomy
  • Views
  • Views data export
  • Workbench Moderation

Out of the box layout

what I’m hoping to get out of this: gotchas I may not have considered in building the theme, things I might want to share with Justin & Naomi.

[full disclosure: not 100% listening, because I’m trying to get my screenshots together.]

Fieldgroup is in fact the bomb. (he’s using “div” in order to have something for theming. So this is on Manage Display. I should talk to Justin about that maybe for some of the more complex content types. Faculty profiles, maybe? Can also add classes to those divs in a fieldgroup under manage display. (I feel like maybe that’s something I’m already doing somewhere?))




what I’m looking for: I’m not really sure TBH.

forming/storming/norming/performing — this actually clicks with the confab presentation — and I think we can add that awareness to our work sessions! Because we want them to conform to our process, but we also have to feel out their anxieties and interests.

and I want to grab this stat about verbal vs vocal vs body language for my presentation as well, for that section on active listening.

“common frame of reference” — that’s why we added the intro/kick-off, and that’s what a lot of the question-asking is about, building a frame of reference. and that’s why the questions should be as low-level as possible, because you’re trying to understand their frame of reference, and listening to find out the underlying issues.

“what’s the gap?”

retrospective — that’s the word I was looking for yesterday! (we should totally do more of those.)

“don’t argue about the experience” — “you shouldn’t be mad” — can’t talk people out of that feeling.

interesting note from audience from book “how to talk to your children so they will listen …” – don’t tell people they don’t feel a thing. (I HAVE FEELINGS ABOUT THIS.)

the 6 basic feelings: happy, sad, mad, afraid, ashamed, confused (also: surprise? disgust? words & pics don’t quite match.)

YUP, I definitely want to bring in some of the therapy tools to my confab talk.

CRM integration

what I’m hoping to get out of this: what are some possibilities for integrating? What should I be looking for?

make it easy for editors to build pages/forms and connect them to the campaigns in the CRM

avoiding tightly coupled systems

at the one end, just link to the forms built in the CRM, and at the other, actually building a CRM in Drupal

finding the habitable zone.

using “Users” to manage sessions, without actually giving them a login?! the hell.

entity registration (module)

fields to represent CRM integration

form block (module) to put user registration on lots of different content

a kind of “guest” user with a long session lifetime

I’m not sure if any of THIS is appropriate to our uses, but its intriguing.

drop-down field for “lead source” and then details, including a campaign ID. (the lead sources sync, but could be just as simple to give editors access to Taxonomy)

when the form is filled out, it also sends a POST to create them in the CRM. (so the important thing to know is how to do the POST. From there: cake?)

“the end user watching the video would never see [the CRM’s] interface” (HELL YES)

Form API post-submit handler (could probably also do this in webform interface?)

There’s a whole thing of a sorta-blank form with a button? I’m not 100% that I get it, but ok.

[long discussion of de-duping]

be careful of the cache_form table if using their system, could get out of control?

they use hidden fields to send that stuff in the form, rather than doing it all server-side with the post-submit handler, etc. (stuff I wouldn’t even know what to do)

they’ve also thought about creating a queue and doing batch, but the downtime just wasn’t enough to justify the work. have a logging system in case of a failure.

[lost track for a sec, I think something about analytics tracking urls?]

context form alteration seems intriguing. (there’s other modules mentioned in a slide)

How to audit Drupal sites

what I’m hoping to get out of this: what are some cool tools for making sure I’m not messing it up?

“views cache bully”?

site audit – drush. can produce html reports.

doesn’t check usability & UX (obvs!) or design (including accessibility) or the actual content.

the HTML output is pretty sweet, TBH…but it does require shell access, so that’s maybe an issue?

module: unused_modules – things that can be safely deleted.

module: security_review

cacheaudit has some overlap with site audit, but does some slightly different ways of looking at what is and isn’t cached.

[slides with a bunch of generic PHP cleanup/audit tools, maybe send to Dave/Jamie?]

GitStats (does Gitlab integrate some sort of statistical analysis?)

ESLint is in D8, FWIW. — that’s the one Justin uses, yes?

Nice slide on the structure of an audit report. is for reviewing custom modules? if you want to post them to

nice audience recommendation of

there’s a version of site_audit available already for D8.

Build awesome search pages with Solr

what I’m hoping to get out of this: some understand of what Solr is, how it works, and/or what we might get out of using it over Google Site Search







Search API vs actual Solr module: more flexible? Also has more options? I’m a little confused TBh.

[slide about installing Solr — his handwaving feels a lot like mine for tomorrow’s presentation.]

There’s also a bunch of hosted Solr options, if I want to try stuff out.

Can include/exclude specific fields from being indexed. (“Compound fields”, which includes the body field! are available through an extra expando-box.)

(I’m glad he said this was a run-through. It feels really rough. But watching this, I’m wondering if I should move away from the screenshot method vs actually running a live demo, because it is a lot easier to understand this way.)

Interesting gotcha of having to make sure to index the full content. If you’ve got it set to index as items are edited/created, then it isn’t being indexed with cron.

Interesting stuff in the Search database advanced config, as far as highlighting, etc.

Sounds like the layout is adjusted through Panels vs Views? (I try to avoid Panels, because of previous bad experiences, but in some instances it’s ok: I’m already doing that to override the My Workbench default.)

Honestly: are facets really useful for most people most of the time?

Primary performance savings is on the indexing (which is important) vs the display.

But the sorting of results (by pub date or something else) using Views is sort of intriguing.

Aaaaaaannnnnnd then his computer crashed.

“Aggregated fields” — can use to combine fields into a single indexed *thing* — “like field collections”

This session really feels unfinished. (Like, I actually feel really prepared compared to this!)

Can bundle into Features, but then add an override (there’s a module, search api solr override?)

One place where faceted search might be useful: pages vs directories.

Potentially useful blog post on troubleshooting.

PNW Drupal Summit: The Drupal Development Pipeline

what I’m hoping to get out of this: specific tips that will help us in getting to a really great live site.

curious idea of using codepen for demoing components to clients.

“you could have up to 200 developers [later: ‘guys’ :\ ] working on a D8 site w/out stepping on each other’s toes” (I don’t understand why, tho.)

discussion of tags, header hierarchy: but without discussion the editor experience? how odd. (most of our issues with poor use of headers come from things editors do.)

estimating: 130%


this “developer tools” slide is a venn diagram overlap with my presentation tomorrow.

Semantic Versioning

modules to look at

  • “smart trim”
  • “stage file proxy”
  • nodequeue (“curated list of content”)
  • metatag
  • redirect 403 to user login (does this work at all with CAS? what would the alternative be?)
  • something about Entity Custom Modes (or whatever that’s called) — and improved caching when creating views with custom mode view something something. [would this help with the Workbench Access every page views?]

Drupal Coding Standard? [does this matter at all for us]

custom environment module for stopping yourself from accidentally emailing all the people or whatevs on the dev site. (Dave does something like this, I think?)

use AdvAgg on production sites

I kinda hate the term “post-mortem”, but I think something like that would be a good idea.

Quick notes on Drupal usability testing

At work we’re in the process of converting from our current CMS (proprietary system which I will not name) to Drupal. One of my big goals is making a really great experience for our several dozen (maybe 100+) editor-authors. I’ve been eagerly following work by Eileen Webb (her UX Burlington keynote is amazing) and Johanna Bates (forex, this great piece on authoring homepages) on the topic, and particularly on implementing with Drupal.

Yesterday we did usability testing with three of our editors. We got a nice mix, both in their overall tech-savviness and in which parts of the current system they use regularly. (We have two separate setups, one for the “old template” and one for the “new template”.) Justin was the person in the room with them — because I’m waaaaaay to close to it — and one of our student workers, another site editor, Susan, and I were observing. It was a fairly short test because of time constraints, only about a half an hour. We picked the most common tasks based in part on our experience and in part on a survey we did back in the spring.

  • Explore the dashboard (Workbench, in our case) and look at the pages in the fake site they’d been assigned.
  • Update some text based on a Word document. (Advanced: add bullet point and correct the spelling.) The text was in our “Primary Content” field.
  • Add some links to some existing text; some of the linked content was in Drupal, some was not. The text was in our “Secondary Content” field.
  • Upload an image and style it to match the main design.

The final task was going to be uploading and linking to a PDF, but there’s still too much wonkiness with that and Media CKEditor. But we did ask if there was anything else that they would do normally that we hadn’t asked them to do, and that did come up twice, so the follow-up to that was to ask them to explore how they might do that.

Here’s what we discovered really needed work:

  • If you’re using the CAS module for authentication, logging out via the Admin menu doesn’t actually log out of CAS! After the first test, we discovered we had to close Firefox entirely and reopen.
  • Nobody sees vertical tabs. I know people are really into them in Drupal editing screens, but for those secondary content links, it was way too hidden for the first two users. I switched it to horizontal tabs before the third user came in, and wow was that better. Our student worker noted that it was a much better match for how people’s eyes move across the screen. I’m inclined to agree.
  • Styling terminology needs to be pretty verbose. A style labeled “Image” in the CKEditor Styles drop-down was a bit  vague.
  • For our uses, alt text really needs to be required, and one of our testers skipped that but entered the title text, which is kind of pointless.

Other than that, it was really successful! They got the hang of the basics right away and expressed a lot of happiness about how “clean” and “simple” everything looked.

(Also: people who deal with lots of documents really want to be able to upload multiple documents. They can’t in our current system, but one of our testers uploads quite a bit of Excel, and other quite a bit of both PDF and Excel. They both found their way to the (broken, because libraries) multiple uploading functionality, but couldn’t use it. I’ll definitely be testing that in more detail.)

And the stuff that needed work: it’s all done already.

  • The simplest way to handle the CAS logout issue is to set a Rule: when a user logs out, redirect them through /caslogout. I feel like this needs to be added to the CAS module documentation.
  • Horizontal tabs FTW.
  • Justin changed “Image” to “Image Right-Aligned” — we’ll see how that plays out next time around.
  • Structure > File Types > Image > manage fields. Remove Title and make Alt Text required.

I know there’s still more complex stuff coming, and I have work to do wrangling Media CKEditor to handle documents the way I want them, but overall I’m really really pleased. These folks walked in without any training in using Drupal as editors, and walked out having accomplished the very most common tasks they need to do to be successful.

PS: making fake website content is just too much fun.

A little thing about Workbench

Today I talked about Workbench (a suite of Drupal modules) at the Olympia users group. Here’s the notes I wrote to get ready. I’m posting it here for my own reference and in case it’s of interest to anyone else!

Also, here’s the links I posted to

Workbench is several different things. But one aspect of it is a way to better manage the author experience. I’m really big on author experience right now, because these folks are the people using Drupal the most but they don’t “do” Drupal. And because it’s so flexible, it’s up to us to make it a good time for them and to make their day a little nicer.

The main Workbench module provides a really nice page for getting around in reviewing and creating content.

On My Workbench, I can see all the pages I have access to and the things I edited most recently. There’s also a spot that can be used for custom help or site news. I have a tab for creating new content, too.

So from here I can see all of my content and create new things. Which you could do with the built-in Dashboard, but Workbench also has an Access module and a Moderation module, and those give you more options.

Workbench Access allows you to limit who can edit which pieces of content, and to let a group of people all work together on their own content.

This is what it looks like when I’m logged in as an average site editor. In this case, I’m set up to edit the “advising” section of the site. My toolbar only gives me access to My Workbench, and when I go there, it’s just the content for my site section. I can also edit content that someone else in my group created.

As an administrator, it’s pretty easy to set or review access for the different sections. I can either go to the Workbench Access settings and see that “advising” has one editor, or I can go to the “user” profile and see that they’re set to the “advising” section.

In our case, we’re also using Workbench Access to set some standard content that differs between sites. If anybody’s curious, I’d be happy to talk about it another time. [ed: there was actually a LOT of interest in that, so I ended up talking about it for a while. There’s some crazy Taxonomy+Views stuff going on to make it work.]

Workbench Moderation provides a way to work with draft content and to have review states for content. I’m going to switch over to a draft of a Calendar that students and staff can submit to and then specific staff can review and post.

As a student, I belong to a group that’s hosting an event on campus. I can log in and go to the Post an event link, which is just a normal node entry form. They can save it, but they can’t edit it. I’m still working on some tweaks so they know what’s going to happen next.

What’s going to happen next is that the staff member who reviews these items is going to go to their workbench. I’m working on integration with the Rules module so they get an email, but let’s just say they have a regular time to check. Joe here is already logged in, and on his workbench he has a tab called Needs Review and here it shows the events that Jane has submitted.

The other thing you can do with this that I don’t have a demo for is if you have changes that you know about but can’t show to the public yet, you can create a new draft and save it while still leaving the old version visible. You can also use Workbench Moderation to look back at the history of changes to a piece of content.

So I’m finding Workbench and its modules really useful for making a site that is friendlier for our authors and editors.

Notes on Features (the Drupal module)

I’ve been noodling around with Features*, but I finally sat down and watched the video series (I’ve gotten all the way thru Ch 8), then set up a tiny test site to try things out. I’ll probably be using this same project to try out Migrate, FWIW.

Some things I cleared up in my own head:

  • After you initially create a Feature, you should install it on the site where you created it! That makes it waaaaaaay easier to incorporate updates.
  • Recreate = make a new export zip file with all the code
  • Revert = go back to the code version of the feature (and hey, sometimes that includes NEW code from an export, because old stuff that you already set looks like an override when the new code comes in)
  • drush features-update [featurename] is like Recreate, but works directly on the code in the module folder.

Also, what I did for my test project was one local repository for the code, not in a site, one repo for the dev site, and one for the live site, all coordinated through an origin on GitHub. Which takes some wrangling with Tower (omg command line git) but can be done.

Also also, “is there Features support?” is one of my new module criteria. I’m not 100% sure how I feel about that.

* I think I first heard about Features at a PNW Drupal Summit in Vancouver BC in 2010. Took me until literally this year to actually really understand what the hell it’s for, and why it’s kinda magical. I wish there were more intros for button-clickers (site builders) out in the wild, because there’s a pretty big conceptual leap for non-developer types IMHO.