With the ExpressionEngine calendar functionality explained, let’s dive into the code. In this chapter I’ll cover the implementation of the Event Calendar index template. From a coding perspective I’ll show how to do the basic implementation, and then use an embedded template with embedded variable to get around the “no custom field” limitation of the weblog:calendar tag. This chapter will also lay some groundwork for using EE’s relationships to tie events to ministries.
Preview the Results
Before getting your hands dirty with the code, take a look at the completed calendar index on the sample site. I want you to make sure it’s what you’re after before proceeding. You can see that EE generates the calendar view, and if you look at either July or August of 2008 there are entries that show up that display a linked title. At the moment the link doesn’t go anywhere - that requires a detail template that I’ll cover in the next chapter.
If you mouse over a link, you should get the browser title pop-up that displays a bit more information about the event—the start time, the duration and the location.
That’s roughly half the calendar functionality I’ll be covering in this series. The other half will be the detail template (that the title will link to) and implementing an events RSS feed.
If that works for you, keep reading…
Overall Implementation Steps
- Create events weblog
- Create events custom field group
- Add fields to the group
- Enter content
- Create events template group
- Update embeds/main_nav
- Update stylesheet/styles
- Add code to events/index
- Create embeds/event_rollover_title
Create an Events Weblog
Event calenders in ExpressionEngine are powered by a standard weblog - so I’ve created a new weblog and named it “Events”, with a short name of “events”.
Create an Events Custom Field Group
Events have their own unique data structure, so a new field group is required. Create an “Events” custom field group.
Add the following fields to the group. I’ve listed the field name, label, type, size and formatting options for the fields I’ve added:
- event_duration, Event Duration, Text Input, 3, None
- event_location, Event Locations, Drop-down List, manually populated, None
- event_cost, Event Cost, text input, 4, none
- event_contact_name, Event Contact Name, text input, 128, none
- event_contact_phone, Event Contact Phone, text input 128, none
- event_contact_email, Event Contact Email, text input, 128, none
- event_details, Event Details, text area, 6 rows, XHTML
And One More
While planning this section initially I was going to tie together events and ministries using categories. I’m going to do a bit of a direction change and use relationships instead. Using categories only nets me being able to show related events on Ministry category pages—so if you view the Ministries for Singles I’d be able to pull the upcoming events for singles - but I see a couple of issues with that approach. The design of the Ministries index template doesn’t allow for another content type to display and I don’t want to go down the path of a category-specific template. Using categories also doesn’t easily allow me to pull ministry-specific events to a ministry detail page—and I think that’s a more helpful connection than the category level tie-in.
Relationships will let me create a direct connection between an event and a ministry. I’ll be able to use that connection to link from a ministry detail page to an event, and from an event detail page to the sponsoring ministry.
So I’ve added one more field to my Events field group - a relationship field:
Name:
event_sponsoring_ministry
Label:
Event Sponsoring Ministry
Field Type:
Relationship
Weblog to Create Relationship With:
Ministries
Display Criteria:
I choose “Sort by Title” in “Ascending” order
In this chapter all we’ll do is setup the field and assign a related Ministry while entering content. In the next chapter I’ll show how to pull related Ministry information to the Events detail view.
Connect the Field Group to the Weblog
Make sure to assign the new field group to the Events weblog via the “Edit Groups” link in Weblog Management.
Enter Content
Go ahead and post some new entries in the Events weblog. There are a couple of new things to note here:
Make sure to click the Date tab and assign choose an Entry Date that’s in the future. The time of the post will be used as the event starting time so round it off to a nice “top of the hour” number. The other new thing is to now use the relationship field - so for every post choose a sponsoring ministry in the drop-down. I found that putting a number of events on one date helped me with formatting the calendar visually. Keep in mind that you can edit your entries to assign new entry dates to move events around the calendar for formatting purposes.
Create an Events Template Group
With the content structures in place I’ll now work on pulling the content to the site. Create a new template group named “events”. Since the content is full-width like the Beliefs page, it made a good starting point - so I copied that code into the new events/index template.
Coding the Template
The first order of business is to change all references of “beliefs” to “events” - so the page title, the body id, and the variable in the main navigation embed. Then in the main content div you can remove all the code there entirely.
I used the calendar code from the EE documentation as a starting point for my code - the “big” version which is the second example on that page. I also used the provided calendar css as a starting point.
After some tweaks - here is the guts of my events/index template - take a scan through it and then I’ll highlight the changes I had to make from the example code I used as a starting point:
<!--BEGIN CONTENT SECTION-->
<div class="interiorBox">
{exp:weblog:calendar switch="calendarToday|calendarCell" weblog="events" show_future_entries="yes" sort="asc"}
<table id="event_calendar" summary="Church Event Calendar" >
<tr class="calendarHeader">
<th><div class="calendarMonthLinks"><a href="{previous_path=events}"><<</a></div></th>
<th colspan="5">{date format="%F %Y"}</th>
<th><div class="calendarMonthLinks"><a class="calendarMonthLinks" href="{next_path=events}">>></a></div></th>
</tr>
<tr>
{calendar_heading}
<td class="calendarDayHeading">{lang:weekday_abrev}</td>
{/calendar_heading}
</tr>
{calendar_rows }
{row_start}<tr>{/row_start}
{if entries}
<td class='{switch}' align='center'>
{day_number}
{entries}
<div class="event_link">
<a href="#" title="{embed="embeds/event_rollover_title" my_entry_id="{entry_id}"}">{title}</a>
</div>
{/entries}
</td>
{/if}
{if not_entries}
<td class='{switch}' align='center'>{day_number}</td>
{/if}
{if blank}
<td class='calendarBlank'>{day_number}</td>
{/if}
{row_end}</tr>{/row_end}
{/calendar_rows}
</table>
{/exp:weblog:calendar}
</div><!--END CONTENT SECTION-->
Here are the changes I had to make from the sample code I copied from the EE docs:
- Changed the weblog it references - to “events” in my case
- Changed the next_path and previous_path values - and just referenced this index template
- Added “show_future_entries="yes” to the calendar tag - otherwise the calendar will only show events for today or ones that had passed
With those changes I had a working basic event calendar.
Getting Tricky with Embeds
I wanted to take it a step further though and see what it would require in order to be able to pull custom fields to the calendar view - so users could get more event information without having to click through to the detail page.
Remember that the weblog:calendar tag doesn’t support custom fields by default. However - it does return entry_id. Using that as a bridge I was able to pull custom field content to the index template by using an embedded template with an embedded variable. I decided that directly displaying more content on the calendar would visually junk it up so decided to pull custom field content into the link title attribute . The result? Mousing over an event link will pop up the little browser tooltip and display the event start time, duration and location.
So I created a new template in my embeds group called “event_rollover_title”. It has the following code:
{exp:weblog:entries weblog="events" entry_id="{embed:my_entry_id}" show_future_entries="yes" dynamic="off"
disable="trackbacks|pagination|member_data|categories"}
Starts: {entry_date format="%g:%i%A"}
Duration: {event_duration} hrs.
Location: {event_location}
{/exp:weblog:entries}
and then added a calling template in events/index:
<a href="#" title="{embed="embeds/event_rollover_title" my_entry_id="{entry_id}"}">{title}</a>
Here’s how it works:
The parent weblog:calendar tag returns entry_id, which gets passed to this embedded template. This embedded template takes the entry_id and uses it as a parameter on a weblog:entries tag, which as you know returns all custom fields. The fields within the weblog:entries pull out the post time (used here as an event start time), duration, and location. This text is assembled and returned to the calling template as the link title text.
One note I need to make about this approach is that it, due to it’s nested approach, it could be resource intensive if you have a lot of calendar entries. For the couple of church sites I’ve been involved with, I wouldn’t be worried, as there are rarely more than a couple of entries a day. I’ll also - in a future chapter - cover some caching approaches that will also help mitigate any performance concerns.
Don’t Forget
Don’t forget to update embeds/main_nav to make the link to events/index live.
Companion Files
The companion file zip archive for this chapter includes
- New events/index
- Updated stylesheets/style
- Updated embeds/main_nav
- New embeds/event_rollover_title
Here’s a link to download the companion files: 20-Events-Index.zip
Next up - the events detail template.
Series Navigation
Next entry: 21 - Implementing the Event Calendar Details Template
Previous entry: 19 - Events Calendar Overview
Previous Comments
Hey Craig -
In my approach, yes entry date == event date.
I did this because the built-in calendaring function keys off entry date. I don’t know of any way to feed the calendar tag a custom date field instead.
So yes, if you want the calendar view then use entry_date.
I’ve never run into needing events loaded in the system that I wanted to hide from visitors. Usually as soon as something is scheduled the desire is to get it on the site - both to market the event and communicate to others that the building has been reserved.
Mike,
Is there any way to get events to span across several days on the calendar? I have a site that needs such functionality. It is a real pain to have to add an entry each day for week long events.
Jesse
Hi Jesse -
The repEET plugin I linked to in the Calendar Overview chapter will do multiday events.
Add Your Comment
Latest Products
- Screencasts : Prepping an EE Site for Client Access
So you’ve been slaving away… More >> - Screencasts : Members-Only Content and Workflow
Do you have content that… More >> - Screencasts : Designing an ExpressionEngine Architecture
OK - so you’ve got… More >> - Products RSS Feed
- Products Email Notification
Checkout Requirements
In order to make a purchase from Train-ee you’ll need to first be registered and logged in, and you will also need a PayPal account.
Links to the downloadable files will be sent upon receipt of payment.
Note that if you pay with a credit or debit card and PayPal sees the transaction as an “eCheck”, there will be a 3-4 day delay before the transaction completes and you receive the download links.

Mike,
To clarify:
You use entry_date here. I think of that field as the date on which I want the entry to become visible on the site. Perhaps I have that wrong. You are using it here to be the actual event date, correct? If so, is that because you cannot display custom fields if you use the built-in calendar functionality?
I did this section a few weeks ago and handled it differently. I created a custom date field, and used the event_date to designate when I wanted people to see that event promotion begin.
As I appreciate this, you are using “show future entries” and the entry date to achieve similar functionality. And I have to do it your way if I want to use the calendar control that EE provides. Is that correct?