Documentation for the Textpattern plugin smd_calendar by Stef Dawson follows this short message from our sponsor ;-)
If you like my code and it makes your site better, feel free to show your appreciation with something from my UK Amazon wish list (or US) or donate to the Stef Dawson community coding pot, either via paypal.me/stefdawson or by following the Donate button below to PayPal. Thanks!
smd_calendar
Render a calendar with one or more articles as events on each day. Useful for gig guides, “what’s on” or scheduling apps.
Features
- Full-size / mini calendar by month, with ISO week support
- Nav: next/prev month or month/year dropdown. Year range can be from first/last article or +/- N years
- One article = one event, native to TXP: posted date = the date it appears in the calendar (overrideable)
- Filter events by cat / section / author / status / time / expiry
- Specify event frequency in custom field (1 week / 10 days / 3 months / etc)
- Custom fields for in/exclusions (dates on which an event is (re)scheduled/cancelled/omitted)
- Multi-day spanned events based on article expiry
- Display future, expired or sticky events
- Holidays per-calendar
- Pass each event to a form/container. Spanned and/or recurring events can be sent to a separate form. Cell format also customisable
- Conditional tests for flags and dates so you can build your own logic
- Table-, row-, cell-, and event-level classes for indicating different scenarios
- Tags to display recurring events; event/calendar characteristics; or the current date/time
Installation / Uninstallation
Requires Textpattern 4.4.1+
Download the plugin from either textpattern.org, or the software page, paste the code into the TXP Admin->Plugins pane, install and enable the plugin. Create any needed custom fields. Visit the forum thread for more info or to report on the success or otherwise of the plugin.
To uninstall, delete from the Admin->Plugins page.
Naming convention
The core of the plugin is the smd_calendar tag, which renders a standard calendar. Each cell contains one or more events that occur on that day. Before diving into the tags here are the basics:
- *calid% : you may put more than one calendar on a page: each can be uniquely referenced with a calendar ID so they may be controlled independently
- *event% : an article. Any article written in the given section(s) will appear on the calendar as long as its expiry hasn’t been met. More than one event may appear in each cell
- *event flag% : events can either be standard, they can recur, they can span multiple days, dates can be unscheduled or omitted from the calendar, or extra dates can be added
- *cell flag% : a series of flags are used to label each cell according to what it contains. Cells can either be empty (i.e. no date: the filler cells at the start/end of the month), they can be a regular day (no flag), they can contain an event, or may be a holiday
Flags provide information about the cell / event — and can be tested with the conditional tag — while the corresponding class names are just there for your CSS use.
When assigned as classes, flags always take the ‘class’ prefix (i.e. the 1st item given in smd_calendar’s classprefixes
attribute) — whether they appear at the event or cell levels. The only classes that take the optional 2nd ‘event’ prefix are the fields you specify in the eventclasses
attribute.
Standard cells and events
The following cumulative naming rules apply:
- Normal (day) cells don’t have a class assigned to them unless you specify one with
cellclass
- Any cell that contains an event (of any type) is flagged as an
event
- Any cell that falls on a holiday is given the flag
hols
- The current day is given the flag
today
A single event (aka article) with a Posted date will be flagged standard
, unless it recurs or spans more than one day.
Recurring events
If you have nominated a field as your stepfield
you may enter a comma-separated list of frequencies at which the event is to repeat. The format of the repetition is number interval, e.g. 4 weeks
or 10 days
or 6 months
. The plugin will do its best to figure out what you mean. See date input formats for more.
A few points:
second tuesday
will show an event every 2nd Tuesday from the start date (i.e. fortnightly)second tuesday ?month ?year
will substitute the current month and year in first, and then calculate the date, resulting in the event only recurring on the 2nd Tuesday of each month. You must use both?month
and?year
if you choose this type of date or your event won’t appear20 ?month
will show the event on the 20th of every month- things like
first thursday
orlast friday
orthis tuesday
don’t need the?month
or?year
because they can only occur monthly, and will only show the event on the given day of the month
If you can find a use for it, you may specify multiple frequencies, for example 3 days, 1 week
. That means you would see the event on the 1st day, then the 3rd, 6th, 7th, 9th, 12th, 14th, 15th, 18th, 21st, 24th… days thereafter. Note that the event only occurs once on the 21st day even though the two frequencies clash.
Recur rules:
- The repetition will continue forever1 unless you specify an expiry time
- The very first event of a recurring set will be flagged with
recurfirst
- Each following cell that contains a recurring event will be flagged with
recur
- Both flags are applied to the event as classes using the class prefix
- Repeated events may be cancelled or omitted on a per-date basis
1 ‘forever’ is limited to 99999 recurrences per event, or 274 years’ worth of daily events. Either UNIX will run out of dates or PHP will run out of memory long before you reach this limit :-)
Multi-day (spanned) events
Any event that has:
- a start date
- an expiry date that is a day or more later than the start date, and
- does not have any repetition in its
stepfield
is flagged as a multi
. By default the first event is displayed in full and each ‘continuation’ event is shown only as a right arrow in subsequent cells. Events may span months or years and the plugin figures everything out using flag rules:
- The first cell of a spanned set is
multifirst
- The last cell is
multilast
- Every other cell is a
multi
except if the event rolls over into the next month. In that case, the entry on the 1st of the month is amultiprev
to indicate it belongs to a previous event - If the 1st day of the month is the last day of the event, the
multiprev
is dropped in favour ofmultilast
Switch off spanning completely with showspanned="0"
. Events that have an expiry then become standard events.
‘Continuation’ cells may be processed with a separate form (spanform
). If you choose not to use a spanform
, the standard form
or container will be used and you will have to distinguish between the different multi flags yourself using the conditional tag.
You can also cancel or omit days of a spanned event in the same manner as you do with recurring events, except you cannot cancel the first day; you should move the event start date and apologise!
Cancelling and omitting events
Plans change and you may find that a gig has to be cancelled. Perhaps you advertise a weekly boot fair but the field is waterlogged one week. No problem: nominate a skipfield
in your smd_calendar
tag and enter the date of the cancelled event.
Or you might run a theatre web site that has a three-week production performance on weeknights only. Instead of setting up three separate events — one for each week — nominate an omitfield
and list the dates on which the performance does not air. Omitted dates will not, under any circumstances, appear on the calendar and they override cancelled dates/holidays. If cellplus
mode is used, you will however see a cell flag labelled omit
(plus class prefix) in case you do wish to style such cells.
To specify the dates in either field, use any acceptable date format, but derivatives of dd-monthname-yyyy or monthname-dd-yyyy are the most unambiguous to avoid problems (e.g. is 1/5
Jan 5th or May 1st). You can specify as many cancellations or omissions as you like; comma-separate each one. You may also specify ranges of dates to omit/cancel by using the notation start date => end date
.
By default, cancelled events will not appear on the calendar. If you use showskipped="1"
the event will appear in the cell as normal and the cancel
flag will apply to the event (and cell if you choose) so you may detect/style it.
Extra dates
When events are cancelled you may elect to reschedule the event on a different date instead of having to create a new event with identical details. Use the extrafield
to simply add it to the calendar on its new day. You might also use this feature if you have a recurring event on the 1st of every month but for some reason you have to move one of the events a day or two. Simply cancel the offending date and add the new date using extrafield
.
The list of dates can be in any standard date format (including date ranges using start => end
). They will be added to the calendar and flagged as extra
. Also see the extrastrict
attribute.
If your original event spans more than one day, you may elect to schedule the entire block again. Add a ‘+’ after any date you wish to repeat in its entirety, e.g. 2009-Mar-12+, 2009-Jun-18+, 2009-Feb-19
would copy the entire event block to March and June, but only the 1st date to Feb 19th. Events/cells are flagged as both extra
and multi
where applicable.
Notes:
- if you schedule an extra event on a day that already contains the same event (perhaps on a spanned or recurring date) you may see two identical events on the same day. Try and avoid this, unless it’s your intended behaviour
- date ranges and the ‘+’ syntax are mutually exlcusive on any date (e.g.
2009-Mar-10+ => 2009-Mar-15
is illegal)
Holidays
Public holidays need not be a nuisance to your events. Give the plugin a holiday list and it’ll make sure any recurring or multi events are not scheduled on those days. Standard one-off events are permitted by default because you might want to organise a special event on that day, though you can forbid those too if you wish.
The list of dates you specify can be entered directly in a string in the holidays
attribute or in a <txp:variable />
:
<txp:variable name="nat_hols"
value="Dec 25, 26 Dec, 31/Dec, Jan-1,
May 4 2009, 2009-08-31" />
<txp:smd_calendar holidays="txpvar:nat_hols" />
That list shows some of the variety and breadth of formats the plugin allows. There are more. Note that the events without a year occur on the same date every year, whereas the ones with a year will only occur on that specific date.
Once your dates are defined you can control which events are allowed to fall on those dates via holidayflags
. Combining that attribute, showspanned
, showskipped
and the forms — along with the conditional tag — can give a wide variety of ways to display events and cells.
Holiday cells are given the flag hols
, and any event that is not specifically permitted by the holidayflags
is automatically assigned a cancel
flag if it falls on one of the days. Omitted dates will, however, cause the cancel
flag to be removed.
Tag: <txp:smd_calendar>
Put this tag wherever you want your calendar to appear. Use the following attributes to control its output. The default value is unset unless stated otherwise.
Display attributes
- size
- Calendar size. Options:
- large
- small
- The small is more geared towards a minical, although functionally there isn’t much between them
- Default: large
- firstday
- First day of the week to show in the calendar. 0=Sunday, 1=Monday … 6=Saturday
- Default: 0
- dayformat
- Way in which day names are rendered. Options:
- ABBR shows abbreviated day names; Mon, Tue, Wed, etc
- FULL uses full names
- Any valid strftime() codes. Locale-specific names are returned
- A comma-separated list of custom day names surrounded by
{}
brackets
- Example, for two-letter German weekdays:
dayformat="{So,Mo,Di,Mi,Do,Fr,Sa}"
. The first day in the list must represent Sunday or things will break - Default: ABBR
- monthformat
- Way in which the month names are rendered. Options:
- FULL shows full month names
- ABBR uses abbreviated names
- Any valid strftime() codes. Locale-specific names are returned
- A comma-separated list of custom month names surrounded by
{}
brackets
- Example, for single-letter month names:
monthformat="{J,F,M,A,M,J,J,A,S,O,N,D}"
. The first month in the list must represent January or things will break - Default: FULL
- select
- Use a select dropdown for rapid access to weeks, months or years instead of fixed names. Choose one or more of:
- week
- month
- year
- Note: week and month are mutually exclusive
- You may also specify up to two extra arguments, separated by
:
chars. These add text in front of and behind the week/month/year, respectively - Example:
select="week:WEEK#, year:<:>"
displays a select list with entries like this:WEEK#15 <2009>
- selectbtn
- Add a dedicated submit button to week/month/year select lists. Specify the text you wish to appear on the button. It will have the CSS class name
smd_cal_input
- Default: unset (i.e. auto-submit on select list change)
- isoweeks
- Show ISO week numbers as a column at the start of the calendar. Any text in this attribute enables the feature, and becomes the heading of the ISO week column
- You may change the default week number in each cell by adding a comma and some text; whatever you enter will be put in each ISO week cell. Use the following replacement codes in your markup to insert the relevant info:
- {week}
- {month}
- {year}
- {isoyear}
- Example:
isoweeks="wk, #{week}"
will put ‘wk’ at the top of the column and something like#24
,#25
,#26
… beneath it. If the first item is omitted, there will be no column heading - Note that if this feature is enabled,
firstday
will be forced to start on a Monday as governed by the ISO specification - navarrow
- Comma-separated pair of items you want to appear as prev/next arrows in the calendar
- Default:
<, >
- caption
- Add a caption to the calendar
- summary
- Add a summary to the calendar
Filter attributes
- time
- Which events to display. Options:
- any
- past
- future
- today
- Default: any
- expired
- Hide or show expired events. Options:
- unset (use the TXP Preference ‘Publish expired articles’)
- 0 (hide)
- 1 (show)
- status
- Events in this status list are published on the calendar. Options:
- live
- sticky
- Default: live
- category
- Filter events by this list of categories. Use
SMD_UNCAT
for uncategorised events - subcats
- Consider sub-categories. Choose a numeric nesting level to consider, or the word
all
- section
- Filter events by this list of sections
- author
- Filter events by this list of author login names
- realname
- Filter events by this list of author Real Names (note: may add one extra query)
- showall
- If your calendar appears on the front page of your site and you have not used the
section
attribute, then:- 0: only shows events from sections marked with
On front page
- 1: shows all events from all sections
- 0: only shows events from sections marked with
- Default: 0
- month
- Start the calendar on this month from 1 (Jan) to 12 (Dec). Normal calendar navigation overrides this value
- If
static
is used, this month becomes the only one you may view - If unset, and no
m=
value appears on the URL line, the current month is used - week
- Start the calendar during the month containing this ISO week (from 1 to 53)
- Ignored if
static
or one of the calendar navigation controls is used - If a
w=
value appears on the URL line, the given week overrides any month value - year
- Start the calendar at this 4-digit year. Normal calendar navigation overrides this value
- If
static
is used, this year becomes the only one you may view - If unset, and no
y=
value appears on the URL line, the current year is used - static
- Force the calendar to be fixed to one month/year (i.e. no navigation). Month and year decided by attributes
month
andyear
or, if omitted, the current date will be used
Form attributes
- form
- Use the given TXP form to process each event
- If the smd_calendar tag is used as a container it will be used in preference to the form
- If neither are used, a default is used (Large: hyperlinked article title, Small: empty event)
- spanform
- Display spanned events differently to standard events; they usually use the same
form
/container - If neither are specified, a right-arrow will be used to indicate continuation of the previous day’s event
- Note: the first day of a spanned set is not passed to the
spanform
; only continuation cells are passed to it - recurform
- Display recurring events differently to standard events
- Note: the first event of a recurring set is not passed to
recurform
- cellform (only on large calendars)
- Use if you wish to build each cell entirely from scratch
- There are some replacement variables you can use to insert dynamic pieces of information in your cells
- Note: you cannot use TXP article or plugin tags in the Form
- headerform
- Use if you wish to build the header yourself
- There are some replacement variables you can use to insert dynamic pieces of information in your header
Field-based attributes (custom fields or other article fields)
- stepfield
- ID of a field within which an event may be told to repeat
- Note: it is the field’s ID not its name, so for custom fields you must use
custom_1
orcustom_2
etc - Without this attribute, no recurring events may be defined
- omitfield
- ID (not name) of a field that contains a list of dates on which this event is to be omitted
- skipfield
- ID (not name) of a field that contains a list of dates on which this event is cancelled
- extrafield
- ID (not name) of a field from which a list of additional event dates may be given; the same event details will be copied to the new day(s)
- extrastrict
- Control visibility of extra dates on the calendar. Options:
- 0:
extrafield
dates automatically appear on the calendar - 1: restrict new dates from appearing after the event’s expiry date
- 0:
- Default: 0
- showskipped
- Control visibility of cancelled events on the calendar. Options:
- 0 (hide)
- 1 (show)
- Default: 0
- showspanned
- Control visibility of spanned events on the calendar. Options:
- 0 (hide)
- 1 (show)
- Default: 1
- datefields
- IDs (not names) of up to two fields from which posted and expiry date stamps may be read. Comma-separate the field names; the first will be used as the Posted date and the second as the Expiry
- If either is omitted or mangled, the article’s “real” posted/expiry date will be used instead
- If the expiry date occurs before the start date, your datefields will be ignored and a warning will be issued
Config attributes
- holidays
- List of dates that are decreed as holidays
- May be deferred to a
<txp:variable />
, in which case define your list in a named variable and useholidays="txpvar:my_var_name"
to read them into the plugin - holidayflags
- Permit certain event flags to be scheduled on holidays. List one or more of:
- standard
- recur
- multi
- Default:
standard
- id
- HTML ID to apply to the table that holds the calendar. This becomes the value of the URL variable
calid
- Use this if you have more than one calendar on a page and wish to control them separately via the URL vars
- navid
- HTML ID to apply to the prev/next/month/year navigation form
- yearwidth
- A comma-separated list that specifies how many years your calendar spans. Visitors will not be permitted to navigate (next/prev) the calendar outside this range. Options:
- 0: use the earliest (posted) event as the earliest year, and the latest (modified or posted, whichever is greater) event as the latest year
- any other single number expands the range equally in past & future directions
- any pair of numbers subtracts the first from the earliest event and adds the second number of whole years to the latest event
- adding
c
to either value causes the current year to be used instead of the earliest or latest event
- Example:
yearwidth="2,4c"
subtracts 2 years from the earliest event and adds 4 whole years to today’s date - Default: 0
- remap
- When dealing with multiple calendars on a page it is often beneficial to use different names for
w=
,m=
ory=
in the URL so you can navigate calendars individually. This attribute enables you to rename the w, m, & y variable to any name specified after a colon (:) - Example:
remap="w:wk, y:yr"
- linkposted (only on small calendars)
- Each cell that contains an event flag of the given type(s) will have its day number linked to the event’s true start date instead of the cell’s date. This allows you to always link to a valid article/event
- Note that if more than one event occurs in the cell, the link will only be to the first event the plugin finds
- Example: if you have a weekly event that starts on the 20th December 2008, setting
linkposted="recur"
will cause the link to bedate=2008-12-20
every week. Without linkposted, the dates would be 2008-12-20, 2008-12-27, 2009-01-03, and so on - Default:
recur, multi, multiprev, multilast
(i.e. any recurring or spanned event) - maintain
- Keep track of this comma-separated list of variables in the URL when navigating the calendar using the next/prev or month/year select lists. If you wish to maintain state yourself or do something exotic, empty this attribute first to avoid weirdness. Options:
- calid
- section
- category
- author
- article
- date
- pg
- any other URL variable of your choosing
- Example: use
maintain="section, article, calid"
if you have an individual article page with a calendar in a sidebar, so the currently viewed article will remain in view when changing date - Default: calid
- nameval
- Add your own name/value pairs to the calendar’s URL.
- Example:
nameval="tracker=mycal, keep=1"
would add?tracker=mycal&keep=1
to the URL. Useful if you want tomaintain
some values which you can’t add to the URL on page load - event_delim
- Delimiter between each event.
- Default: comma
Style attributes
- classlevels
- Each flagged event can be given a CSS class based on its flag name(s). Classes can be applied to events, cells, or both. You may also promote (i.e. copy) all event classes that occur in a day to the cell itself so you can style the cell based on the events it contains. Options:
- event
- cell
- cellplus (for copying unique event classes to the containing cell)
- Note you should not use
cell
andcellplus
together because the latter overrides the former - Default: cell, event
- classprefixes
- Comma-separated list of up to two prefixes to apply to your class names. The first prefix is applied to cell-level classes (and flags) and the second prefix is applied to event classes (see
eventclasses
) - If you only specify one prefix, it will be used for both. If you use
classprefixes=""
then no prefixes will be used at all - Default: smd_cal_, smd_cal_ev_
- class
- Class name of the calendar table itself
- Default: unset
- rowclass
- Class name of each table row
- Default: unset
- cellclass
- Class name of each table cell
- Default: unset
- emptyclass
- Class name of any cells that don’t contain a day number (i.e. the blank cells at the start & end of a month)
- Default: empty
- isoweekclass
- Class name of each cell containing an ISO week
- Default: week
- navclass
- Class name of the prev/next month nav arrows. If a comma-separated list is used, the first item will be the name of the class of the previous month, the 2nd item of the next month. If a single value is used, both class names will be the same
- Default: navprev, navnext
- myclass
- Class name of both the month and year in the calendar header (either the
<span>
or<select>
tags). Ifmywraptag
is used, the class is applied to the wraptag instead - Default: unset
- eventclasses
- Comma-separated list of items to add as classes to each event. Each are prefixed with the event prefix
- Example:
eventclasses="ID, AuthorID, custom_5"
would add three classes to each event corresponding to the event’s ID, its author (login) name and the contents of custom_5 - If you use
cellplus
, these classes will be copied to the cell level. Some special names exist:category
adds both Category1 and Category2 (if set);gcat
will add the current ‘global’ category (if filtering by category);author
adds the author ID (if filtering by author);section
adds the current section - Default: category
- eventwraptag
- HTML tag, without brackets, to wrap each event with
- Default: span
- mywraptag
- HTML tag, without brackets, to wrap around both month + year dropdown select lists and submit button
- Default: unset
Using a cellform
with replacement variables
If you don’t like the layout of the default cell, you can do it yourself with the cellform
attribute. The cells are generated last, so by the time the plugin reaches this attribute, all events have already been processed by any of your forms/containers. Thus you can’t use TXP article or plugin tags.
To build your own cells you often need information such as the events that fall on a particular day; or the week, month or day numbers, etc. So you may also insert any of the following replacements to have the relevant value inserted among your markup:
- {day} / {dayzeros} : day of the week (1-31 / 01-31)
- {weekday} : weekday in the local language, or from your
dayformat
list - {weekdayfull} or {weekdayabbr} : weekday in the local language
- {week} : ISO week number (01-53)
- {month} / {monthzeros} : month number (1-12 / 01-12)
- {monthname} : month name in the local language, or from your
monthformat
list - {monthnamefull} or {monthnameabbr} : month name in the local language
- {year} : 4-digit year
- {shortyear} : 2-digit year
- {isoyear} : 4 digit ISO year
- {shortisoyear} : 2 digit ISO year
- {evid} : event (article) ID
- {events} : all events for the day
- {standard} : only standard events
- {recurfirst} / {recur} : various recurring events
- {allrecur} : all recurring events for the day
- {multifirst} / {multi} / {multiprev} / {multilast} : various multi events
- {allmulti} : all multi events for the day
- {cancel} : only cancelled events
- {extra} : only extra events
Using a headerform
You can create your own header if you wish and employ any of the following replacements in the markup:
- {firstday} : current weekday (as a number from 0 to 6)
- {daynames} : comma-separated day names
- {isoweekhead} : ISO week heading
- {week} : ISO week
- {month} : month
- {year} : year
- {isoyear} : ISO year
Differences between large and small calendars
cellform
cannot be used on a small calendar- By default, no event descriptions are placed in the small calendar. You can add them yourself if you wish using a form/container
- The only thing rendered in a small calendar cell is the hyperlinked date and any flags so you can style the boxes
classlevels
are ignored: everything is automatically assigned at the cell level (i.e.cellplus
is set)eventclasses
are still honoured if you wish to use a form to process them yourself- The small calendar outputs year-month-day-title or messy permlinks only
Tag: <txp:smd_if_cal>
This conditional tag allows you — inside your container/forms — to test certain conditions of the current event/cell. For enhanced conditional checking (perhaps in conjunction with smd_cal_now), consider the smd_if plugin. The default value is unset unless stated otherwise.
Attributes
- flag
- The cell or event flag(s) you want to test, each separated by a comma. List one or more of:
- event
- standard
- recurfirst
- recur
- multifirst
- multi
- multilast
- multiprev
- cancel
- omit
- extra
- hols
- today
- SMD_ANY (will trigger if the cell or event contains any of the above)
- calid
- The calendar ID you wish to check for a match
- year
- The year the current cell falls in
- isoyear
- The ISO year the current cell falls in
- month
- The month number (1-12) that the current cell falls in
- week
- The ISO week number that the current cell falls in
- day
- The day number the current cell falls in
- logic
- Method of combining the nominated tests. Options:
- or: tag will trigger if at least one of the tests is true
- and: tag will only trigger if all the tests are true
- Default: or
‘And’ logic is useful for checking if the cell is of a certain type AND is later than the 15th of the month, for example.
Rudimentary comparators can be applied to the (iso)year
, month
, week
and day
attributes. Normally the value you supply will be tested for an exact match but if you prefix it with one of the following character sequences then the behaviour changes:
>
tests if attribute is greater than the given value (e.g.year=">2008"
)>=
tests if attribute is greater than or equal to the given value (e.g.month=">=7"
)<
tests if attribute is less than the given value<=
tests if attribute is less than or equal to the given value!
tests if attribute is not the given value (e.g.day="!15"
)
Tag: <txp:smd_cal_info>
Inside your smd_calendar container/forms, use this tag to output certain information about the current event.
Attributes
- type
- Comma-separated list of types of information you want to display. Options:
- flag
- calid
- (iso)year
- month
- week
- day
- s (current section)
- category
- author
- realname
- article (id of the currently viewed article)
- any other article variable such as
section
(the current article’s section),authorid
,article_image
, etc
- If using the
html
attribute, you may optionally specify the name you want the variable to appear as in the URL string. The variables all take on sensible defaults (e.g. ‘section’ becomes?s=<section name>
, ‘category1’ becomes?c=<category1 name>
, etc). - Example:
<txp:smd_cal_info type="catgeory:the_cat" html="1" />
means you would see?the_cat=<category1 name>
in the URL - Default: flag
- join
- The characters you want to use to separate each item you asked for. Note it is the characters between each item so the very first entry will not have the
join
in front of it (seejoin_prefix
) - Default: a space
- join_prefix
- The string you want to put in front of the first item in the returned list. If you do not specify this attribute it tries to be clever:
- If using
type="flag"
the join_prefix is set to the same asjoin
. Thus withjoin=" cal_"
you might getcal_multi cal_today cal_hols
- If using
html="1"
the join_prefix is set to a question mark, thus:type="month,year,category" html="1"
might render?m=12&y=2008&c=gigs
, which can be put straight on the end of an anchor
- If using
- Default:
SMD_AUTO
- html
- Control in which format the information is returned. Options:
- 0: return items verbatim
- 1: return items as a URL parameter string. This is useful if you are building your own content inside each cell via a
form
and wish to maintain the current search environment. If you allow people to filter events by category or author you can use this to return the ‘current’ state of certain variables so you can pass them to the next page and maintain state
- Note: Setting this attribute to 1 overrides the
join
attribute and sets it to an ampersand - Default: 0
- escape
- Escape HTML entities such as
<
,>
and&
for page validation purposes. Useescape=""
to turn this off - Default:
html
Tag: <txp:smd_cal_class>
Inside your smd_calendat container/forms, use this tag to add a list of classes to the current cell/event. Very useful if building cells yourself because inside a conditional tag you could add particular class names based on some value in a cell.
Attributes
- name
- Comma-separated list of classnames to add to the current cell/event. These are not subject to any
classprefixes
so will always appear exactly as you write them - Default: unset
Tag: <txp:smd_cal_now>
Return the current date/time, formatted however you please. Useful for extracting parts of the current system timestamp to compare things via other conditional plugins or the <txp:smd_if_cal>
tag.
Attributes
- format
- The way you want the date/time represented. Use any valid strftime() string. Has full Windows support, even for those values where strftime() indicates otherwise
- Default: the date format set in Basic Preferences.
- now
- If you don’t want the time to be ‘now’ you can state what time ‘now’ is! Use any standard date/time format
- You may also use the codes
?day
,?month
or?year
in your time string which will do one of two things:- replace the codes with the URL parameters
d=
,m=
ory=
, if they are being used - use the current day, month or year (i.e. the parts of today’s date)
- replace the codes with the URL parameters
- Default: now! (the time at which you call the tag)
- offset
- An offset into the future that you wish to apply to
now
- Example:
2 months
. See Example 6 for a practical application of this attribute - gmt
- Return either:
- 0: local time according to the time zone set in Basic Prefs
- 1: GMT time
- Default: 0
- lang
- An ISO language code that formats time strings suitable for the specified language (or locale) as defined by ISO 639
- Default: unset (i.e. use the value as stated in TXP prefs)
Tag: <txp:smd_article_event>
When you create recurring events, they really only exist once as a single article; the repetition is a trick. Thus the built-in article tags only show the single, real articles.
This tag — similar in function to <txp:article_custom />
— allows you to list recurring articles as if they were ‘real’ articles in the database. They don’t become real articles, they are just listed as such.
Inside the tag’s form
or container you can use all existing article tags to display any information you like about each ‘virtual’ article. The default value is unset unless stated otherwise.
Identical attributes to smd_calendar:
- stepfield
- skipfield
- omitfield
- extrafield
- datefields
- section
- category
- author
- realname
- status
- time
- expired
Other attributes
- id
- Restrict events to this list of article IDs
- custom
- Specify your own comma-separated list of custom field clauses to the query. Separate each field from its (optional) operator and clause with a colon (alterable via
param_delim
). - Example:
custom="custom_3:like:Lion%, custom_6:Chessington"
would addAND custom_3 like 'Lion%' AND custom_6='Chessington'
to the database query. - param_delim
- Alter the separator character(s) between field-clause items in the
custom
attribute. - Default: colon (:)
- type
- Comma-separated list of event types to display. Options:
- standard
- recur
- multi
- Default: standard, recur, multi
- allspanned
- Control display of spanned events:
- 0: any event that has a start date in the past will be omitted from the list
- 1: display remaining days from spanned events that began in the past
- Example: use
allspanned="1"
if you are listing remaining performance dates from a Broadway show’s schedule that started some months ago. - Default: 0
- month
- Only show events that occur in the given YYYY-mm
- from
- Only show events with Posted dated beginning after this start date. Can be any valid date format
- to
- Only show events with Posted dates up to this end date. Can be any valid date format
- sort
- Order the events by this column (case-sensitive) and sort direction (asc or desc)
- Default: Posted asc
- form
- Pass each matching event to the given TXP form. Note that using a container overrides this attribute, and if you specify neither a form nor container, you will see a list of article Posted dates
- paging
- Unlike article_custom, events from the smd_article_event tag may be paged using
<txp:older />
and<txp:newer />
. But if you wish to show an event list on the same page as a standard article list, the older/newer tags will navigate both lists simultaneously. Under this circumstance you may need to turn paging off (0). Options:- 0 (off)
- 1 (on)
- Default: 1
- offset
- Begin displaying events from this numeric position, instead of from the start of the list of events
- Default: 0
- limit
- Inly show this many events maximum per page, i.e. the number of events to display, whether they come from one ‘real’ article or many
- Default: 10
- eventlimit
- Only show this many events maximum per event
- Example: if you have a weekly repeated event that lasts for four months and you set
eventlimit="6"
you will only see a maximum of 6 events from every article containing repetition. The range (start and end date) is determined by other plugin attributes - Default: 10
- pageby
- Esoteric paging feature, identical to
<txp:article />
- Default: same as
limit
- pgonly
- Set to 1 to perform the paging action without displaying anything. Probably useless
- wraptag
- The HTML tag, without brackets, to wrap the list in
- break
- The HTML tag to separate each item with
- class
- The CSS class to apply to the
wraptag
The smd_article_event tag process
It is worth noting that this tag executes in 3-phases:
- Pre-filter: all events that match
type
,category
,section
,author
,status
,id
, andexpired
are extracted - Time-filter: any “time-based” attributes are then applied to the above list. At this point, any
extrafield
,stepfield
,omitfield
, orskipfield
are calculated to find repeated dates (up to as many aseventlimit
allows or the calculation exceeds the event’s expiry time). The attributestime
,month
,from
, andto
are used to refine the filtration here - Output: whatever the previous phases have left behind is subject to any
paging
,offset
andlimit
you may have specified, then wrapped and displayed
Tag: <txp:smd_event_info>
Identical tag to <txp:smd_calinfo /> but for use inside <txp:smd_article_event />
.
Examples
Example 1: basic calendar
You have the entire arsenal of TXP tags available to you in a calendar. Thus you can set the article’s start and end dates to the same day and set the start and end times to indicate the start and end of the event. You can then use standard <txp:posted />
or <txp:expires />
tags with various format
strings to render the event’s criteria.
Similarly you can use any other TXP tags to show as much or as little detail as you like in the calendar cell.
<txp:smd_calendar section="events">
<div>
Event: <txp:permlink><txp:title /></txp:permlink>
<br /><txp:excerpt />
</div>
<div class="evtime">
Start: <txp:posted format="%H:%M" />
</div>
<div class="evtime">
End: <txp:expires format="%H:%M" />
</div>
</txp:smd_calendar>
Example 2: conditional calendar
Using the conditional tag you can take action if certain events contain particular flags. This example also shows a completely useless manner of employing <txp:smd_cal_now />
.
Time is: <txp:smd_cal_now format="%T" />
<txp:smd_calendar form="evform"
stepfield="custom_3" skipfield="custom_6"
spanform="multis" />
In form evform
:
<txp:smd_if_cal flag="recur">
<txp:permlink>(RECUR)</txp:permlink>
<txp:else />
<txp:permlink><txp:title /></txp:permlink>
<txp:smd_if_cal flag="multifirst">
<span class="right">«--</span>
</txp:smd_if_cal>
<txp:smd_if_cal flag="recurfirst">
<span>One of many...</span>
</txp:smd_if_cal>
</txp:smd_if_cal>
And in form multis
:
<txp:smd_if_cal flag="multi, multiprev">
<txp:permlink>--»--</txp:permlink>
</txp:smd_if_cal>
<txp:smd_if_cal flag="multilast">
<txp:permlink>
<span class="left">--»</span> END <txp:title />
</txp:permlink>
</txp:smd_if_cal>
Notice that multifirst
is tested inside the same form as standard events. This is because only continuation spanned cells are passed to the spanform
; the first event of a spanned group is just like any standard event. Similarly, if you had been using recurform
the first event of the recurring set would be processed in the usual form/container and every subsequent event would be passed to the dedicated form.
Example 3: classes
You could use the calendar tags to output various pieces of flag information to build your own class names. This example also demonstrates the html
attribute of <txp:smd_cal_info />
to build up a query string that is passed along with an event’s category1
when a visitor clicks the anchor.
This allows your site visitors to filter events by category while retaining the ability to show the calendar for the current month/year and section they are viewing instead of dropping back to the current month/year like other calendar systems often do.
<txp:smd_calendar isoweeks="WEEK#"
yearwidth="0,2" select="year, month"
stepfield="custom_1" skipfield="custom_2"
showskipped="1" expired="1">
<span class="<txp:smd_cal_info join=" cal_" />">
<txp:permlink><txp:title /></txp:permlink>
<a href="?c=<txp:category1
/>&<txp:smd_cal_info type="s, year,
month, calid" html="1" join_prefix=""
/>"><txp:category1 title="1" /></a>
</span>
</txp:smd_calendar>
What is also useful about the <txp:smd_cal_info />
tag is that if a particular value is not set it will not be included in the output.
Example 4: upcoming events
List the next 5 upcoming — recurring — events, plus any standard and spanned events, formatting them as a definition list.
<h2>Upcoming Events</h2>
<txp:smd_article_event stepfield="custom_1"
wraptag="dl" time="future" eventlimit="5">
<txp:if_different>
<dt><txp:posted format="%B %Y" /></dt>
</txp:if_different>
<dd>
<txp:permlink><txp:title/></txp:permlink>
<txp:posted />
</dd>
</txp:smd_article_event>
If you add pagination tags you can flip through all the events; they will be displayed 10 at a time on each page (if you want to keep track of which page you are on as you flip through a calendar that is in a sidebar, add pg
to the maintain
attribute in your calendar).
Note the hyperlinked title shown here will jump to the ‘real’ article (the first date in the recurring set) when clicked, not to an article with a date matching the recurrence.
If you wanted to allow people to book an event, try this in your hyperlinked individual article:
<txp:if_individual_article>
<txp:article limit="1">
<h3><txp:title /></h3>
<txp:body />
<p>Please choose a date to book:</p>
<select>
<txp:smd_article_event stepfield="custom_1"
type="recur" id='<txp:article_id />'>
<option
value='<txp:posted format="%G-%m-%d"/>'>
<txp:posted format="%m %d, $G" />
</option>
</txp:smd_article_event>
</select>
</txp:article>
</txp:if_individual_article>
With some cunning you could even add the ‘virtual’ date that they chose in your original smd_article_event list and pass it as a URL variable to your individual article where you could read the value and pre-select the date in the select list for the vistor.
Example 5: iCal synchronisation
How about being able to output your events in iCal format so other people can sync their calendars to yours? Put this in a new Page template in its own Section:
BEGIN:VCALENDAR
VERSION:2.0
X-WR-CALNAME:Gigs Calendar
PRODID:-//Apple Computer, Inc//iCal 1.5//EN
X-WR-TIMEZONE:Europe/London
<txp:smd_article_event form="icsitem" time="any"
section="gigs" limit="1000">
BEGIN:VEVENT
DTSTART:<txp:posted format="%Y%m%dT%H%i%s" />
DTEND:<txp:expires format="%Y%m%dT%H%i%s" />
SUMMARY:<txp:title />
END:VEVENT
</txp:smd_article_event>
END:VCALENDAR
That will output an iCal-formatted gig list (repeated or otherwise). If you got freaky with it and added some conditional logic inside the template you could even read in URL variables and plug them in. Thus you could link to it directly off the calendar itself, pass in the section, category or event info and have a customised iCal stream pumped out of Textpattern.
Thanks to woof for bringing the original David Emery article to my attention.
Example 6: redefining now
Using the now
and offset
attributes of <txp:smd_cal_now />
you can effectively set ‘now’ to be any time you like and make calculations based on a particular date.
Plugging the ?month
and ?year
codes in allows you to make <txp:smd_article_event />
track the calendar. So you can automatically show only the events that occur in the month the visitor is browsing via the calendar:
<txp:smd_calendar stepfield="custom_1" />
<h2>Events this month</h2>
<txp:smd_article_event stepfield="custom_1"
from='<txp:smd_cal_now now="01-?month-?year" />'
to='<txp:smd_cal_now now="?month-?year"
offset="1 month" />' time="any" wraptag="ul">
<li><txp:permlink><b><txp:title/></b></txp:permlink></li>
</txp:smd_article_event>
Author / credits
Stef Dawson. Jointly funded by generous donators: mrdale, woof, jakob, renobird and joebaich. Originally based on mdp_calendar. All props to the original author, and of course the class upon which the calendar is based.
Source code
If you’d rather frolic in the raw code halls, you’ll need to step into the view source page.
Legacy software
If, for some inexplicable reason, you need a prior version of a plugin, it can probably be found on the plugin archive page.
Experimental software
If you’re feeling brave, or fancy dipping your toe in shark-infested water, you can test out some of my beta code. It can be found on the plugin beta page.