2002-06-11 18:33:00 UTC
Сначала немного пояснений. Календарь вызывается с двумя параметрами:
-
date_user— это хэш, который передает параметры даты (дня, месяца и года) и начальные значения месяца и года, с которых начинается календарь. Данные о дате используемой для формирования этого хэша берутся из строки запроса:...?y=2002&m=3&d=26—^form:d.int(0),^form:m.int(current_month)и^form:y.int(current_year). По-умолчанию, выводится календарь за текущий месяц и год. Ссылки, на днях и названии месяца и года календаря, формируют указанный хэш. Пример хэша:$date_user[ $.day(^form:d.int(0)) $.month(^form:m.int(current_month)) $.year(^form:y.int(current_year)) $.start_y(2002) $.start_m(3) ]
Следует отметить, что значение месяца и года, всегда должны быть осмысленными, ненулевыми значениями (например по-умолчанию принять их равными текущим значениям месяца и года), а значение дня может быть нулем (если не нужно показывать новости за какой-либо день). -
days_of_files— это хэш, в котором передаются дни, за которые были какие-либо материалы.$days_of_files[ $.1[число > 0] $.2[число > 0] $.5[число > 0] ... ]
Ключами хэша являются значения дней месяца. Этот хэш можно делать вручную, а можно и с помощью БД. Пример формирования хэша из СУБД MySQL:$days_of_files[ ^hash::sql{ SELECT DAYOFMONTH(date_field), some_field FROM some_table WHERE DAYOFMONTH(date_field) and MONTH(date_field) = 10 and YEAR(date_field) = 2002 }[$.distinct(1)] ]гдеYEAR,MONTHиDAYOFMONTHэто функции возвращающие соответственно числовое (не строковое!) значение года, месяца и дня из поля типаdateилиdatetime. Для других СУБД используйте их собственные функции работы с датами. - Календарь формирует строку запроса в URI, цель которой передавать данные о дате странице, и далее страница выводит некие материалы за эту дату. Однако, можно и не зацикливаться на строке запроса и передавать вместо
...?y=2002&m=3&d=26красивый URI вида...2002-3-26.html, из которого в коде страницы извлекать данные о дате.
Вызывать календарь так:
$c[^calendar::init[$date_user;$days_of_files]] ^c.calendar[]
Код класса календаря:
#######
@CLASS
calendar
#######
@init[date_user;days_of_files]
# the shape of arrows for previous and next month
$back[<^;<^;]
$forward[>^;>^;]
# colors for day's digits
$color_day_off[#ff0000]
$color_day_past_or_now[#000000]
$color_day_future[#666666]
# colors for day's cells
$color_cell_day[#ffffff]
$color_cell_day_now[#ffcc00]
# colors for weekday's cells
$color_cell_weekday[#eeeeee]
$color_cell_weekday_now[#cccccc]
# initial data the year and the month of the calendar begining
$self.date_user[$date_user]
$date_now[^date::now[]]
$start_y(^date_user.start_y.int($date_now.year))
$start_m(^date_user.start_m.int(1))
^if($date_user.year && $date_user.month){
$d($date_user.day)
$m($date_user.month)
$y($date_user.year)
}{
$d($date_now.day)
$m($date_now.month)
$y($date_now.year)
}
# the hash of local calendar (month and day names)
$calendar_locale[
$.month_names[
$.1[Январь]
$.2[Февраль]
$.3[Март]
$.4[Апрель]
$.5[Май]
$.6[Июнь]
$.7[Июль]
$.8[Август]
$.9[Сентябрь]
$.10[Октябрь]
$.11[Ноябрь]
$.12[Декабрь]
]
$.day_names[
$.0[Пн]
$.1[Вт]
$.2[Ср]
$.3[Чт]
$.4[Пт]
$.5[Сб]
$.6[Вс]
]
]
$month[$calendar_locale.month_names.$m]
$calendar_month[^date:calendar[rus]($y;$m)]
# defining variables month and year for previous month
$calendar_month_prev[^date::create($y;$m)]
^calendar_month_prev.roll[month](-1)
$prev_m($calendar_month_prev.month)
$prev_y($calendar_month_prev.year)
# defining variables month and year for next month
$calendar_month_next[^date::create($y;$m)]
^calendar_month_next.roll[month](+1)
$next_m($calendar_month_next.month)
$next_y($calendar_month_next.year)
# the hash of publications(files)
$self.days_of_files[$days_of_files]
#######
@calendar[]
<table cellpadding="4" cellspacing="3" width="100%">
^month_year[]
^day_of_week[]
^days[]
</table>
#######
# вывод года и месяца календаря со ссылками на пред. и след. месяцы
@month_year[]
# defining style of links without underlining
$link_style[style="text-decoration: none^;"]
<tr>
<td bgcolor="$color_cell_day" align="center" width="16%">
# не выводить ссылки для предыдущего месяца текущего(выбранного) месяца
# если месяц раньше стартового месяца календаря
^if($prev_y < $start_y || $m <= $start_m && $y == $start_y){
$back
}{
<a href="?y=$prev_y&m=$prev_m" $link_style>
$back
</a>
}
</td>
<td bgcolor="$color_cell_day" align="center" colspan="5" width="68%">
# начертание названия месяца и года
# если текущие выводить жирным шрифтом
^if($date_now.month == $m && $date_now.year == $y){
$month_year[<strong>$month $y</strong>]
}{
$month_year[$month $y]
}
# Вывод месяца и года
^if($date_user.day &&
$date_user.month &&
$date_user.year ||
!$date_user.month &&
!$date_user.year ||
$date_user.day){
<a href="?y=$y&m=$m">$month_year</a>
}{
$month_year
}
</td>
<td bgcolor="$color_cell_day" align="center" width="16%">
^if($next_y > $date_now.year ||
$y == $date_now.year &&
$next_m > $date_now.month){
$forward
}{
<a href="?y=$next_y&m=$next_m" $link_style>
$forward
</a>
}
</td>
</tr>
#######
# вывод названий дней недели
@day_of_week[][cell;content;weekday;color]
$cell{<td bgcolor="$color" align="center" width="16%">$content</td>}
<tr>
^for[i](0;6){
^if($i == 6){
$weekday(0)
$content[<span style="color: $color_day_off">$calendar_locale.day_names.$i</span>]
}{
$weekday($i+1)
$content[$calendar_locale.day_names.$i]
}
# определение цвета ячейки дня недели
^if(
$date_now.weekday == $weekday &&
$date_now.month == $m &&
$date_now.year == $y
){
$color[$color_cell_weekday_now]
}{
$color[$color_cell_weekday]
}
$cell
}
</tr>
#######
@days[][cell;content;color] output all days of the month
$cell{<td bgcolor="$color" align="center" width="16%">$content</td>}
^calendar_month.menu{
<tr>
^for[i](0;6){
# определение цвета ячейки дня
^if(
$date_now.day == $calendar_month.$i &&
$date_now.month == $m &&
$date_now.year == $y
){
$color[$color_cell_day_now]
}{
$color[$color_cell_day]
}
^if($calendar_month.$i){
$content[^day[$calendar_month.$i]]
}{
$content[]
}
$cell
}
</tr>
}
#######
# Вывод дня календаря
@day[d][text;link;color;style;d_face]
# начертание дня, если показываются материалы за конкр. день
# выводить его жирным начертанием
$d_face[
^if($d == $date_user.day){
<strong>$d</strong>
}{
$d
}
]
# вывод дня текстом (без ссылки)
$text{
<span style="color: ^if($i == 6){$color_day_off}{$color}">$d_face</span>
}
# вывод дня со ссылкой
$link{
^if($i == 6){
$style[style="color: $color_day_off"]
}{
$style[]
}
<a href="?y=$y&m=$m&d=$d" $style>$d_face</a>
}
# определение цвета дня, если день в будущем, цвет другой
^if($y == $date_now.year && $m == $date_now.month && $d > $date_now.day){
$color[$color_day_future]
}{
$color[$color_day_past_or_now]
}
^if($d <= 9){
$d[^d.right(1)]
}
# вывод, дня текстом или ссылкой, в зависимости от условий
^if(!$days_of_files.$d || $d == $date_user.day){
$text
}{
$link
}