Friday 17 April 2009

Showing Lists of Events in Drupal 6

I wanted to have a page in Drupal that showed upcoming events for the Parent Advisory Council of my son's school, with a tab making it easy to show past events. The idea was to have one place to go to find out about upcoming events, or to find previous events so you could get materials from the event (e.g. handouts provided by speakers).

Drupal has a pretty good module for showing calendars, but it shows them on day, week or month views in a calendar. My users wanted to see a list of events. Our events are more spread out, so a list or table view is actually easier to work with.

So to summarize, we want:
  • A menu in Drupal's primary menu for "Events"
  • The menu takes the user to a page that shows upcoming (in the future) events
  • There is a tab on the page for "All Events". Clicking the tab shows all events, paged with 20 events per page
  • There is also a tab for "Upcoming Events". Clicking it takes you back to just the future events
  • Events have to have a start and end time, and may have an additional description and attachments (e.g. agenda, minutes, hand-outs)
The high level overview of what I did is:
  1. Install and enable some contributed modules
  2. Create a "content type" for events. This defines what information you're going to store for each event
  3. Define a "view" and two "displays" for the view. The view and its displays are partly a query of the information you want to appear, and partly the definition of the menus that get you to the information. The format of the information is defined by your theme, which I won't talk about in this post
  4. Put the menu in the right place
  5. Create some events and test it out. Testing is really important. It's almost impossible to get this right the first time
A small warning before you get started: The smallest error in anything can lead to very bizarre behaviour, or simply to some part of the page not showing up, with no apparent connection to the error. It took me days to get this working (with a lot of side-tracks into Drupal esoterica). Don't expect to get it right the first time, even with detailed instructions.

Here's what I did. I don't guarantee that I've covered every single thing, so please let me know by commenting on this story if I missed anything. (I assume you know how to do Drupal basics like install modules.)
  1. Install the Content Creation Kit (CCK), Views, Date, and Advanced Help modules. Date module version 6.x.2.1 won't work for the use case we're trying to implement. The filter relative to a date (e.g. "now") is broken, which means you won't be able to show upcoming events. Use date-6.x-2.x-dev (see http://drupal.org/node/426990) until the fix gets rolled into the release version
  2. Enable the "Content" part of CCK
  3. Enable all parts of Date except "Date Locale" and "Date Tools", unless you want them for other reasons. Also, if you're running on PHP5 you don't need "Date PHP4"
  4. Enable the "Views" and "Views UI" parts of Views
Now, create the content type for events:
  1. Administration-> Content Management-> Content Types
  2. Click on the "Add content type" link at the top of the "Content types" area
  3. Enter the name "Event" and type "event". There are many options to set, and the help text is pretty self-explanatory. Under "Workflow settings", "Attachments", make sure they're enabled (since we said that was a goal of what we're doing). Most of the other options depend on your needs, although under "Workflow settings" it's likely you'll want to turn off "Promoted to front page" under "Default options"
  4. Click the "Save content type" button at the bottom of the page
  5. Click on "Manage fields" beside the Event content type
  6. Under "Add", "Existing field", select "Datetime: field_event_datetime..." You may have to scroll down to see the existing fields. If you don't see an existing field called "field_event_datetime", then create one under "Add", "New field"
  7. Click "Save"
  8. You will be presented with another page allowing you to set a bunch of options. Set them according to your needs
  9. Click "Save"
Now create the view. You really should read the Drupal Views documentation, which you have available because you installed the Advanced Help module. Read it now. Click on Administer-> Site building-> Views and you'll be given a link to the documentation near the top of the "Views" area

Now, here's my summary of what's important in the Views documentation:
  • A view can have several displays. The display determines where the view is seen, and can also override some parts of the view's default settings. In the rest of this post, I use "view" and "display" in these specific meanings
  • Set up the common aspects of the view first in the Default display. In our case, that means the output format (a table), the fields to be viewed, and some of the filters
  • Be very careful when editing non-default displays to click "Override" before editing anything that you want to be unique to the display. If you don't explicitly click "Override", you'll change the default which will affect other displays that use the default value
So what we have to do is:
  1. Create the view
  2. Set up the default for the view the way we want it
  3. Create a "Page" display for the "Upcoming Events" tab
  4. Move the menu to the right place
  5. Enter some test events
  6. Check that the "Upcoming Events" tab works
  7. Create another "Page" display for the "All Events" tab
  8. Check that the "All Events" tab works
Here are the steps:
  1. Administer-> Site building-> Views
  2. Click the "Add" link at the top of the "Views" area
  3. Put "event_list" in the "View name" field, and "Event List" in the "View tag"
  4. Make sure the "View type" is node and click "Next"
  5. This brings you to the Views UI page. I found this page to be extremely unintuitive. You have to be patient and always remember to scroll down after clicking on something, because many links simply change what's displayed below what's likely visible when you click on the link
Set the defaults for the view:
  1. Under "Basic Settings", click "Unformatted" under "Style". Scroll down. You'll see some radio buttons. Click "Table" and click "Update". Ignore the error message that appears about no fields defined. We'll get to that later
  2. Beside ""Use pager", click "No". Scroll down. Select the "Mini pager" radio button and click "Update"
  3. Beside "More link", click "No". Scroll down. Select the "Create more link" check box and click "Update"
  4. Under "Fields", click on the "+" beside "Fields"
  5. Scroll down. Click on the check boxes for "Content: Event Dat and Time... From date". Don't check the box for the corresponding "To Date" field. Both are included in the "From date". Click on the check boxes for "Node: Body", "Node: Title", and "Upload: Attached files". Click "Add"
  6. You'll now be presented with a number of pages to allow you to set options for each field. For "Event Date...", accept the defaults by clicking "Update"
  7. For "Node: Body", accept the defaults by clicking "Update"
  8. For "Node: Title", click the "Link this field to its node" checkbox and click "Update"
  9. For "Upload: Attached file", click the "Link this field to download the file" checkbox and click "Update"
  10. Now, put the fields in the order you want: Click the up and down arrows by "Fields". Scroll down. Drag "Title" up to the top and click "Update"
  11. Set the sort order: By "Sort criteria", click the "+". Scroll down. Select "Content: Event date and time" and click "Add"
  12. In the next page, select "Ascending", so the next event will appear at the top of the list. Click "Update"
  13. Choose the nodes you want to display, specifically the published event nodes. Click the "+" beside "Filters". Scroll down. Select the checkbox for "Node: Published" and "Node: Type" and click "Add"
  14. On the page for "Node: Published", click the "Yes" radio button and click "Update"
  15. On the "Node: Type" page, click the "Event" checkbox under "Node type" and click "Update"
  16. Click "Save". We have our default view set up.
Create the "Upcoming Events" page:
  1. Click the "Add Display" button (the drop down box above it should read "Page" already)
  2. Under "Basic settings", click on "Page" beside "Name". Scroll down. Type in "Upcoming Events" and click "Update"
  3. Click on "None" beside Title. Scroll down. Click "Override". Enter "Upcoming Events" and click "Update"
  4. Under "Page settings", click on "None" beside "Path". Scroll down. Enter "events/upcoming_events" and click "Update"
  5. Click on "No menu" beside "Menu". Scroll down. Select the "Default menu tab" radio button. Enter "Upcoming Events" under "Title". Click "Update"
  6. On the next page, click on the "Normal menu item" radio button, and enter "Events" under "Title". Click "Update"
  7. Click on the work "Filters". Scroll down. Click on "Override" and then "Update". This overrides the filter selection but makes a copy of the two filters that we set as default
  8. Click on the "+" beside "Filters". Scroll down. Click on the checkbox beside "Date: Date (node)". Make sure you get the right one. There are three fields that start with "Date:". Click "Add"
  9. Scroll down until you see a heading that says "Date field(s)". Select the checkbox beside "Content: Event Date and Time... From date". Click "Update"
  10. On the next page that appears, under "Operator", pick "Is greater than or equal to". Under "Date default", enter "now". Click "Update"
  11. Click "Save". Note that after clicking "Save" you're again editing the default settings, not the upcoming events display. Be careful to select the display you mean to edit. I got that wrong lots of times
Set up the menus correctly:
  1. The above puts the menu under the site navigation menu. We want it under the Primary Links menu. Click on Administer-> Site building-> Menus
  2. Click on "edit" beside "Events"
  3. Under the "Parent item" heading, select "" from the drop-down list
  4. Click "Save". The "Events" menu will show up at the end of your primary menu. Drag it to the appropriate place in the list and click "Save configuration"
Create an event to test what you have so far:
  1. Go to "Create Content"
  2. Click on "Event"
  3. Enter an event on the your current day or sometime in the future. It should be self-evident how. Watch that you end date is after the start date. The user interface doesn't automatically do it like some other programs do. Click "Save"
  4. Enter another event with a date in the past. Again, make sure the end date is the same as the start date
  5. Click on the "Events" menu on your primary menu. You should see the one future event you just entered, but not the past event
If the event doesn't show up, see the troubleshooting tips at the end of this post.

Create the "All Events" page:
  1. Click on Administer-> Site building-> Views
  2. Select "edit" for the "Event List"
  3. Click the "Add Display" button (the drop down box above it should read "Page" already)
  4. Under "Basic settings", click on "Page" beside "Name". Scroll down. Type in "All Events" and click "Update"
  5. Click on "None" beside Title. Scroll down. Click "Override". Enter "All Events" and click "Update"
  6. Under "Page settings", click on "None" beside "Path". Scroll down. Enter "events/all_events" and click "Update"
  7. Click on "No menu" beside "Menu". Scroll down. Select the "Menu tab" radio button. Enter "All Events" under "Title". Click "Update"
  8. Click "Save". Note that after clicking "Save" you're again editing the default settings, not the upcoming events display
Test again:
  1. Click on the "Events" menu
  2. You should see the table with the one future event. You should also see two tabs for "All Events" and "Upcoming Events"
  3. Click on "All Events". You should see both events in the table
  4. Click on "Upcoming Events". You should see just the future event again
Here are some troubleshooting tips:
  • If the events aren't sorting the way you think they should according to the display's "Sort Criteria", click on the little gear beside "Style" under "Basic Settings". Scroll down. If the radio button under "Default Sort" is anything but "None", the sort here will override the sort in "Sort Criteria". Click on the radio button beside "None"
  • With the Date module circa March-April 2009, you have to install a patch or you'll get error messages when creating events. Get the patch here and how to install it is here
  • If the menu doesn't appear on the primary menu, or the tabs don't appear, make sure the paths for each display are below the same name as I showed above. In other words, the display paths should be of the form "x/y" and "x/z", even though the user will never navigate to "x"
  • Recheck all your settings. This is tedious but essential. In my experience, any one being wrong can cause a mysterious and seemingly unrelated failure
  • Be sure that you didn't accidentally change the defaults instead of overriding them, or didn't accidentally override something that should be taken from defaults. Values taken from the default display are in italics when looking at other displays
I hope this helps someone.

25 comments:

diego said...

hi, I'm doing the same in a website, but I have the problem that events are filtered from the posting date, not the end/start date of the events. For example: older events (after the finishing date) are still visible.

Larry Reid said...

Diego, I think I missed something. I'm using calendar-6.x.2.x-dev. Unfortunately, I didn't tag the ticket ID for this bug, so it'll take me a few minutes to find it. When I do I'll post the link to it and update my original article.

Larry Reid said...

Easier to find than I thought: Look at http://drupal.org/node/426990 and make sure you're using calendar-6.x.2.x-dev until the fix gets rolled into the release version.

I'll fix the original post now.

Larry Reid said...

Sorry. In the above comments, all references to the Calendar module should read the Date module. Use date-6.x-2.x-dev.

Megan said...

Hi, I am trying to follow your guidelines to fix our problems of showing future events. I assume that the Advanced Help module should also be activated?

My real problem is when I try to add a field to the content type ... I can't find "Datetime: field_event_datetime..." in the existing field dropdown. Any idea why or what I can do?

Larry Reid said...

Megan, I don't know why you can't see that field in the drop down. Can you post a list of all modules you have active including the version number? I'm guessing that I might have missed a module in my original post, or that the version you're using is either too old or too new.

And yes, you can enable Advanced Help as well.

Larry Reid said...

Megan, try installing and enabling the Calendar module. I don't have time to build a test environment right now to confirm my suspicion, so if you're in a rush you can try it yourself. If not, I'll try this either later today, or next Tuesday. If you try it, post a comment telling me whether that helped. Thanks.

Anonymous said...

Hi Larry,
I tried installing the Calendar module and enabling it, but still no "Datetime" fields appear in the dropdown list. Only "File" and "Text" options.

I wonder where there is a missing check mark!?

Larry Reid said...

Megan, I think this is something you should take up with the people who support the various modules (Calendar, CCK and Date are the main suspects). If that doesn't help, please send me an e-mail via: http://jadesystems.ca/contact with your return e-mail and I'll work on this Tuesday.

Anonymous said...

Hi Larry,
I had a bit of time and found the error and it is stupidly simple. I was following your instructions a little too blindly.

You write:
6. "Under "Add", "Existing field", select "Datetime: field_event_datetime...""

Actually, I had to add a new field, not an existing one, then it worked and the options were available.

Thanks for the help and the tutorial. It was a great help and everything is working now as I want it to.

Megan

Larry Reid said...

Megan, I'm glad it's working for you. Thanks for the feedback. I'll see if I can rewrite that section to make it clearer.

J said...

Hi!

I've been trying to get this working and it's HALF working. I'd like to show only dates that are upcoming, but it looks like my date filter for the block isn't working.

It's showing events greater than or equal to the current date, AND also all events for the current month. I'm no SQL expert, but from the look of the query, it's saying find events which are equal to NOW OR are equal to "the current month"

(it might not say that at all, I really don't know what I'm doing ;) )
I'm stumped.
I've pasted the query generated by the view here. If you have any idea how I can fix this, I'd be eternally greatful.

(For testing, I set it to only show dates = now, and not greater than or equal to now. (granularity day) But whatever I use, it always shows the current month events, and resets each month to the new current month!)

http://pastebin.com/m150d2afa

J said...

As is always the way, I ask for help and suddenly work out what I've been doing wrong.

I had the granularity set to month in Arguments for the "From Date". Sheesh, too many places to change so many settings that look the same! Thanks anyway, and great tutorial. :) I'm learning...

Larry Reid said...

J: We all have that experience. I'm glad you found the problem, as I wouldn't have been able to help for a few days.

I agree with your feeling that there are too many places to set parameters. I think the Views and Date and Calendar people have provided great tools, but there's still an opportunity for someone to put another level of automation on top to package the normal use cases, like a list of events.

Unknown said...

Thanks - had a similar problem and this cracked it. It also made me understand views and - although indeed unintuitive - showed me the sophistication of Views!
One small problem I still have: when I create 'repeat events'(ie every wednesday or so) it creates all the evenst with all the events inside every event. So i get an event on Wednesday which contains the event on this Wednesday, netx week Wednesday, etc etc).
Any ideas?
Thanks for the help & tutorial!

Rgds, Ronald

Larry Reid said...

Sorry, I haven't worked with repeating events, and I probably won't be working on my events website again. Anyone else know what to do?

Anonymous said...

Hi, I have followed all the steps and I am stuck on the step where the menus need to be set up.

The link isn't appearing on the primary menu, despite the fact of me following the path settings in your instuctions, please help.

Thanks

Sreenadh said...

Good post Larry. Thanks. I was also trying to do an upcoming event block.
Got stuck at repeating events. Here is the solution.

@Larry Reid, @Ronald
Distinct: yes (see below)


Name: Defaults
Title: None
Change settings for this styleStyle: Unformatted
Change settings for this styleRow style: Fields
Use AJAX: No
Use pager: No
Items to display: 10
More link: No
Distinct: Yes
Access: Unrestricted
Caching: None
Exposed form in block: No
Header: None
Footer: None
Empty text: None
Theme: Information

Unknown said...

Thanks - got that far eventually (sorry i didn't post it).
The one thing that did it: in the date-timefield there is a setting 'Display repeat rule' or 'Hide repeat rule'. Guess what it does... :-)

Thierry said...

Thanks a lot, exactly what I needed and even more. I took me one hour but it worked on first test. Now I need to dive into templating.

Thierry said...

Thanks a lot, exactly what I needed and even more. I took me one hour but it worked on first test. Now I need to dive into templating.

Unknown said...

I want to thank you for the article. It helped me a lot. I use it for a news page and archive news page.

Drupal Development Company said...

Nice drupal event list.

allricjohnson said...

really awesome article. i am just learning Drupal development. i think it will help me a lot. very helpful and informative. Thank you for sharing.

Drupal Web Development

Unknown said...

Awesome blog,very well explained.

Glad to read your blog.keep posting.i have bookmarked your blog.

Drupal Development