Created
January 29, 2015 14:50
-
-
Save sntran/f6062244e81e131674db to your computer and use it in GitHub Desktop.
A Calendar in XSLT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | |
<xsl:template name="calendar"> | |
<xsl:param name="month" select="substring($page-modified-date, $date-modified-length - 7, 2)" /> | |
<xsl:param name="year" select="substring($page-modified-date, $date-modified-length - 4, 4)" /> | |
<!-- Default to an empty node list. --> | |
<xsl:param name="events" select="/.." /> | |
<xsl:variable name="month-name"> | |
<xsl:call-template name="thisMonthtoMonth"> | |
<xsl:with-param name="thisMonth" select="$month"/> | |
</xsl:call-template> | |
</xsl:variable> | |
<xsl:variable name="offset"> | |
<xsl:call-template name="day-of-the-week"> | |
<xsl:with-param name="day" select="1"/> | |
<xsl:with-param name="month" select="$month"/> | |
<xsl:with-param name="year" select="$year"/> | |
</xsl:call-template> | |
</xsl:variable> | |
<xsl:variable name="total-days"> | |
<xsl:call-template name="days-in-month"> | |
<xsl:with-param name="month" select="$month"/> | |
<xsl:with-param name="year" select="$year"/> | |
</xsl:call-template> | |
</xsl:variable> | |
<div class="calendar-month" id="month-{($year - 1) * 12 + $month}"> | |
<table summary="Calendar for {$month-name}, {$year}"> | |
<caption> | |
<xsl:value-of select="$month-name"/> | |
<xsl:text> </xsl:text> | |
<xsl:value-of select="$year"/> | |
</caption> | |
<tr class="weekdays"> | |
<th abbr="Sunday">Sun</th> | |
<th abbr="Monday">Mon</th> | |
<th abbr="Tuesday">Tue</th> | |
<th abbr="Wednesday">Wed</th> | |
<th abbr="Thursday">Thu</th> | |
<th abbr="Friday">Fri</th> | |
<th abbr="Saturday">Sat</th> | |
</tr> | |
<xsl:call-template name="calendar-week"> | |
<xsl:with-param name="offset" select="$offset"/> | |
<xsl:with-param name="total" select="$total-days"/> | |
<xsl:with-param name="events" select="$events"/> | |
</xsl:call-template> | |
</table> | |
</div></xsl:template> | |
<xsl:template name="calendar-week"> | |
<xsl:param name="offset" select="0" /> | |
<xsl:param name="total" /> | |
<xsl:param name="week" select="1" /> | |
<xsl:param name="day" select="1" /> | |
<xsl:param name="events" select="/.." /> | |
<tr> | |
<xsl:call-template name="calendar-day"> | |
<xsl:with-param name="day" select="$day - $offset"/> | |
<xsl:with-param name="total" select="$total"/> | |
<xsl:with-param name="events" select="$events"/> | |
</xsl:call-template> | |
</tr> | |
<xsl:if test="$week < 6"> | |
<xsl:call-template name="calendar-week"> | |
<xsl:with-param name="offset" select="$offset"/> | |
<xsl:with-param name="total" select="$total"/> | |
<xsl:with-param name="week" select="$week + 1"/> | |
<xsl:with-param name="day" select="$week * 7 + 1"/> | |
<xsl:with-param name="events" select="$events"/> | |
</xsl:call-template> | |
</xsl:if> | |
</xsl:template> | |
<!-- Recursively prints the date of a particular month. --> | |
<xsl:template name="calendar-day"> | |
<xsl:param name="count">1</xsl:param> | |
<xsl:param name="day" /> | |
<xsl:param name="total" /> | |
<xsl:param name="events" select="/.." /> | |
<xsl:variable name="event" select="$events[substring(./title, 9, 2) = $day]" /> | |
<xsl:choose> | |
<xsl:when test="($day < 1) or ($day > $total)"> | |
<!-- Print an empty slot if the day argument is not on this day of the week --> | |
<td class="empty"><xsl:text disable-output-escaping="yes">&nbsp;</xsl:text></td> | |
</xsl:when> | |
<xsl:otherwise> | |
<td> | |
<xsl:choose> | |
<xsl:when test="$event"> | |
<!-- Label to trigger corresponding radio input if any, | |
which in turns toggle the corresponding event --> | |
<label class="icon-circle has-event" for="event-{$event/title}"> | |
<span class="date"><xsl:value-of select="$day"/></span> | |
</label> | |
</xsl:when> | |
<xsl:otherwise> | |
<label for="event-{substring($events/title, 1, 7)}-{$day}"> | |
<span class="date"><xsl:value-of select="$day"/></span> | |
</label> | |
</xsl:otherwise> | |
</xsl:choose> | |
</td> | |
</xsl:otherwise> | |
</xsl:choose> | |
<xsl:if test="$count < 7"> | |
<xsl:call-template name="calendar-day"> | |
<xsl:with-param name="count" select="$count + 1" /> | |
<xsl:with-param name="day" select="$day + 1" /> | |
<xsl:with-param name="total" select="$total"/> | |
<xsl:with-param name="events" select="$events"/> | |
</xsl:call-template> | |
</xsl:if> | |
</xsl:template> | |
<!-- HELPERS --> | |
<!-- Given the year, month, and day, return an integer for the day of the week in the range of 0-6, where 0=Sunday --> | |
<xsl:template name="day-of-the-week"> | |
<xsl:param name="year" /> | |
<xsl:param name="month" /> | |
<xsl:param name="day" /> | |
<xsl:variable name="a" select="floor((14 - $month) div 12)"/> | |
<xsl:variable name="y" select="$year - $a"/> | |
<xsl:variable name="m" select="$month + 12 * $a - 2"/> | |
<xsl:value-of select="($day + $y + floor($y div 4) - floor($y div 100) | |
+ floor($y div 400) + floor((31 * $m) div 12)) mod 7"/> | |
</xsl:template> | |
<!-- Given a month and a year, determine the number of days in the month. --> | |
<xsl:template name="days-in-month"> | |
<xsl:param name="month" /> | |
<xsl:param name="year" /> | |
<xsl:choose> | |
<xsl:when test="$month = 2 and | |
not($year mod 4) and | |
($year mod 100 or not($year mod 400))"> | |
<xsl:value-of select="29"/> | |
</xsl:when> | |
<xsl:otherwise> | |
<xsl:value-of | |
select="substring('312831303130313130313031', | |
2 * $month - 1,2)"/> | |
</xsl:otherwise> | |
</xsl:choose> | |
</xsl:template> | |
</xsl:stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment