2002-06-11 18:33:00 UTC

Сначала немного пояснений. Календарь вызывается с двумя параметрами:

  1. 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)
    ]
    
    Следует отметить, что значение месяца и года, всегда должны быть осмысленными, ненулевыми значениями (например по-умолчанию принять их равными текущим значениям месяца и года), а значение дня может быть нулем (если не нужно показывать новости за какой-либо день).
  2. 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. Для других СУБД используйте их собственные функции работы с датами.
  3. Календарь формирует строку запроса в 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[&lt^;&lt^;]
$forward[&gt^;&gt^;]

# 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
}

Загрузить файл с примером: calendar.zip

2002-06-11 18:33:00 UTC parser snippet web