part of the ArsDigita Community System by Philip Greenspun

The Big Idea

A site like might want to offer a calendar of upcoming events. This has nothing to do with displaying things in a wall-calendar style format, as provided by the calendar widget. In fact, a calendar of upcoming events is usually better presented as a list.

What distinguishes /calendar from /news is that items may be categorized and the display at a large site might be personalized to a user's country, state, or zip code. Also, if there are too many items to display comfortably, the non-expired events coming up soonest get displayed.

See for a good running example that distinguishes /news from /calendar.

Under the Hood

The data model is simple:

create sequence calendar_category_id_sequence start with 1 ;

create table calendar_categories (
	category_id	integer primary key,
	-- if scope=public, this is the address book the whole system
        -- if scope=group, this is the address book for a particular group
 	scope           varchar(20) not null,
	group_id	references user_groups,
	category	varchar(100) not null,
	enabled_p	char(1) default 't' check(enabled_p in ('t','f')),
	constraint calendar_category_scope_check check ((scope='group' and group_id is not null) or
	constraint calendar_category_unique_check unique(scope, category, group_id)	

create index calendar_categories_group_idx on calendar_categories ( group_id );

create sequence calendar_id_sequence start with 1;

create table calendar (
	calendar_id	integer primary key,
	category_id	not null references calendar_categories,
	title		varchar(100) not null,
	body		varchar(4000) not null,
	-- is the body in HTML or plain text (the default)
	html_p			char(1) default 'f' check(html_p in ('t','f')),
	start_date	date not null,  -- first day of the event
	end_date	date not null,  -- last day of the event (same as start_date for single-day events)
	expiration_date	date not null,  -- day to stop including the event in calendars, typically end_date
	event_url	varchar(200),  -- URL to the event
	event_email	varchar(100),  -- email address for the event
	-- for events that have a geographical location
	country_code	references country_codes(iso),
	-- within the US
	usps_abbrev	references states,
	-- we only want five digits
	zip_code	varchar(10),
	approved_p	char(1) default 'f' check(approved_p in ('t','f')),
	creation_date	date not null,
	creation_user		not null references users(user_id),
	creation_ip_address	varchar(50) not null

Comments are handled by the general comments facility.

Related Modules

The /news module is better for generation announcements (e.g., press releases from companies).

The /bboard system is better if you want to support lively discussion and archive the exchanges.