Yii: Добавляем календарь материалов
Виджет календаря на месяц на Yii, в котором выделены дни публикаций материалов. Возможность переходить к следующему и предыдущему месяцам.Недавно мы уже сделали архив статей по месяцам. Добавим теперь такую популярную полезность - календарь на Yii. Это тоже добавляет удобства в ориентировании на сайте.
Сначала добавляем вызов виджета в /protected/views/layouts/column3.php
<?php $this->widget('Calendar'); ?>
В компонентах создаём файл для календаря - /protected/components/Calendar.php с содержимым:
<?php
class Calendar extends CWidget
{
public $title='Calendar';
public function run()
{
// Set locale
if (isset(Yii::app()->params['calendarLocale']) && Yii::app()->params['calendarLocale'] == 'Japan') {
$locale='ja_JP.utf8';
$setlocale = setlocale(LC_ALL, $locale);
}
// Prepare the css style within the calendar widget
$url=CHtml::asset(Yii::getPathOfAlias('application.components.css.calendar').'.css');
Yii::app()->getClientScript()->registerCssFile($url);
// Previous month and next month
if (!empty($_GET['time'])) {
$month = date('n', $_GET['time']);
$year = date('Y', $_GET['time']);
if (!empty($_GET['pnc']) && $_GET['pnc'] == 'n') $month++;
if (!empty($_GET['pnc']) && $_GET['pnc'] == 'p') $month--;
} else {
$month = date('n');
$year = date('Y');
}
$firstDay = mktime(0,0,0,$month,1,$year);
$firstDayNextMonth = mktime(0,0,0,$month+1,1,$year);
$pnc = array('<'=>CHtml::normalizeUrl(array('material/PostedInMonth', 'time'=>$firstDay, 'pnc'=>'p')),
'>'=>CHtml::normalizeUrl(array('material/PostedInMonth', 'time'=>$firstDay, 'pnc'=>'n')));
// Today
$days = array();
if ($firstDay <= time() && time() < $firstDayNextMonth) {
$today = date('j', time());
$days[$today] = array(NULL,NULL,'<span id="today">'.$today.'</span>');
}
// Make the links
$material = new Material;
foreach($material->findMaterialPostedThisMonth() as $article) {
$days[date('j', strtotime($article->create_time))] = array(CHtml::normalizeUrl(array('material/PostedOnDate', 'time'=>strtotime($article->create_time))), 'linked-day');
}
if (isset($locale) && $locale == 'ja_JP.utf8') $len = 3;
else $len = 2;
$this->render('calendar', array('year'=>$year, 'month'=>$month, 'days'=>$days, 'len'=>$len, 'url'=>'', 'pnc'=>$pnc));
}
}
А также в видах компонентов создаём - /protected/components/views/calendar.php
<div id="harrisNewsHeader">
<div id="HarrisNews" class="portlet-comments">
<h3>Календарь</h3>
<center>
<ul class="Calendar">
<?php
if (isset(Yii::app()->params['calendarLocale']) && Yii::app()->params['calendarLocale'] == 'Japan')
include_once('generate_calendar_Japan.php');
else
include_once('generate_calendar.php');
echo generate_calendar($year, $month, $days, $len, $url, 0, $pnc);
?>
</ul>
</center>
</div>
<div id="HarrisNewsFooter"></div>
</div>
И /protected/components/views/generate_calendar.php
<?php
# PHP Calendar (version 2.3), written by Keith Devens
# http://keithdevens.com/software/php_calendar
# see example at http://keithdevens.com/weblog
# License: http://keithdevens.com/software/license
function generate_calendar($year, $month, $days = array(), $day_name_length = 3, $month_href = NULL, $first_day = 0, $pn = array()){
$first_of_month = gmmktime(0,0,0,$month,1,$year);
#remember that mktime will automatically correct if invalid dates are entered
# for instance, mktime(0,0,0,12,32,1997) will be the date for Jan 1, 1998
# this provides a built in "rounding" feature to generate_calendar()
$day_names = array(); #generate all the day names according to the current locale
for($n=0,$t=(3+$first_day)*86400; $n<7; $n++,$t+=86400) #January 4, 1970 was a Sunday
$day_names[$n] = ucfirst(gmstrftime('%A',$t)); #%A means full textual day name
list($month, $year, $month_name, $weekday) = explode(',',gmstrftime('%m,%Y,%B,%w',$first_of_month));
$weekday = ($weekday + 7 - $first_day) % 7; #adjust for $first_day
$title = htmlentities(ucfirst($month_name)).' '.$year; #note that some locales don't capitalize month and day names
#Begin calendar. Uses a real <caption>. See http://diveintomark.org/archives/2002/07/03
@list($p, $pl) = each($pn); @list($n, $nl) = each($pn); #previous and next links, if applicable
if($p) $p = '<span class="calendar-prev">'.($pl ? '<a href="'.htmlspecialchars($pl).'">'.$p.'</a>' : $p).'</span> ';
if($n) $n = ' <span class="calendar-next">'.($nl ? '<a href="'.htmlspecialchars($nl).'">'.$n.'</a>' : $n).'</span>';
$calendar = '<table>'."\n".
'<div class="calendar-month">'.$p.($month_href ? '<a href="'.htmlspecialchars($month_href).'">'.$title.'</a>' : $title).$n."</div>\n<tr>";
if($day_name_length){ #if the day names should be shown ($day_name_length > 0)
#if day_name_length is >3, the full name of the day will be printed
foreach($day_names as $d)
$calendar .= '<th abbr="'.htmlentities($d).'">'.htmlentities($day_name_length < 4 ? substr($d,0,$day_name_length) : $d).'</th>';
$calendar .= "</tr>\n<tr>";
}
if($weekday > 0) $calendar .= '<td colspan="'.$weekday.'"> </td>'; #initial 'empty' days
for($day=1,$days_in_month=gmdate('t',$first_of_month); $day<=$days_in_month; $day++,$weekday++){
if($weekday == 7){
$weekday = 0; #start a new week
$calendar .= "</tr>\n<tr>";
}
if(isset($days[$day]) and is_array($days[$day])){
@list($link, $classes, $content) = $days[$day];
if(is_null($content)) $content = $day;
$calendar .= '<td'.($classes ? ' class="'.htmlspecialchars($classes).'">' : '>').
($link ? '<a href="'.htmlspecialchars($link).'">'.$content.'</a>' : $content).'</td>';
}
else $calendar .= "<td>$day</td>";
}
if($weekday != 7) $calendar .= '<td colspan="'.(7-$weekday).'"> </td>'; #remaining "empty" days
return $calendar."</tr>\n</table>\n";
}
?>
И ещё нужны стили /protected/components/css/calendar.css
/**
* CSS styles for Calendar
*/
ul.Calendar
{
font-size:11px;
# border:0;
# line-height:150%;
display:inline;
}
ul.Calendar li
{
display:inline;
}
ul.Calendar a:link,
ul.Calendar a:visited
{
border:solid 1px #c3881a;
color:#801000;
padding:1px 3px;
text-decoration:none;
}
ul.Calendar .page a
{
font-weight:normal;
}
ul.Calendar a:hover
{
border:solid 1px #801000;
}
ul.Calendar #today
{
color:#990000;
font-weight: bold;
}
ul.Calendar table
{
margin-bottom: 0px;
width: 87%;
}
ul.Calendar th,
ul.Calendar td,
ul.Calendar caption
{
text-align: center;
padding: 2px 0px;
}
ul.Calendar .calendar-month
{
padding: 5px 0px;
text-align: center;
}
Теперь всё.
almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.
Вы можете почитать все статьи от almix'а.
- 14 Разработка приложения на Yii. Урок 14: Выводим список категорий как новый виджет на сайте (29.04.2015)
- 13 Разработка приложения на Yii. Урок 13: Внедряем категории для статей. (29.04.2015)
- 12 Разработка приложения на Yii. Урок 12: Профилирование приложения, включаем кеширование. (20.01.2015)
- 11 Yiico. Видеокурс по разработке сайта на Yii. Урок 11: Отладка приложения, включаем журналирование. (20.01.2015)
- 10 Yiico. Видеокурс по разработке сайта на Yii. Урок 10: Если ваше приложение находится не в корневой папке, а во вложенной. (19.10.2014)
- 9 Разработка сайта на Yii с нуля. Урок 9. Выборка статей определённого автора. (13.08.2014)
- 8 Разработка сайта на Yii с нуля. Урок 8. Вызов в моделях функции, общей для них. Как избегать дублирования кода? (25.07.2014)
- 7 Разработка сайта на Yii с нуля. Урок 7. Изменение количества выводимых записей на странице в CGridView. Включаем сессии Yii. (04.09.2013)
- 6 Разработка сайта на Yii с нуля. Урок 6. Автоматич. отправка оповещений об одобренных комментариях на email автора комментария (11.08.2013)
- 5 Разработка сайта на Yii с нуля. Урок 5. Переименовываем blog в yiico. Изменяем "Home" в breadcrumbs. Включаем Gzip-сжатие. (09.08.2013)
- 4 Курс по Yii с нуля. Урок 4. Дорабатываем простую работу с пользователями: хранение пароля при редактировании пользователя. (13.04.2013)
- 3 Курс по Yii с нуля. Урок 3. Создаём новых пользователей. Организуем простую систему авторизации. Аутентификация, пароли, соли. (20.07.2014)
- 2 Yii + Git (github) на Mac. (24.03.2013)
- 2 Курс по Yii с нуля. Урок 2. Переносим и настраиваем Yii и проект нашего сайта на рабочем сервере. Избавляемся от index.php в url (09.07.2014)
- 1 Курс по Yii с нуля. Урок 1. Устанавливаем Yii на локальном компьютере. Заводим проект будущего сайта. (10.03.2013)
- 0 Composer – пакетный менеджер PHP. Что и как? (22.07.2014)
- 0 MySQL: проверить содержится ли значение в поле столбца (в столбце хранится строка значений через запятую) (22.05.2014)
- 0 Yii: Статичные страницы (создание, редактирование, удаление) (28.04.2014)
- 0 Yii: Расширение ECKEditor = Связка ckeditor + kcfinder (визуальный редактор с бесплатным файловым менеджером) (28.04.2014)
- 0 Yii: Bootstrap tabs, делаем активной вкладку на которую выполняется переход по ссылке (20.03.2014)
- 0 Yii: Доступ к атрибуту модели из файла шаблона (Вызов в шаблоне какого-либо атрибута модели). (17.02.2014)
- 0 Yii: Множественный автокомплит с помощью CJuiAutoComplete (автокомплит нескольких значений в одно поле) (07.02.2014)
- 0 Yii: Фотогалерея через поведение (доработка расширения imagesgallerymanager) (08.03.2016)
- 0 Yii: Установка и настройка Yii-app заготовки приложения от Crisu83 (09.03.2014)
- 0 Twitter Bootstrap Carousel Crossfade (09.09.2013)
3 комментариев
вот эта хренова функция, она в модели Материалов (статей) находится:
/**
* Находит материалы,опубликованные в этом месяце
* @возвращает массив материалов этого месяца
*/
public function findMaterialPostedThisMonth()
{
if (!empty($_GET['time'])) {
$month = date('n', $_GET['time']);
$year = date('Y', $_GET['time']);
if (!empty($_GET['pnc']) && $_GET['pnc'] == 'n') $month++;
if (!empty($_GET['pnc']) && $_GET['pnc'] == 'p') $month--;
} else {
$month = date('n');
$year = date('Y');
}
return $this->findAll(array(
'condition'=>'create_time > :time1 AND create_time < :time2
AND t.status='.self::STATUS_PUBLISHED,
'params'=>array(':time1' => date("Y-m-d", mktime(0,0,0,$month,1,$year)),
':time2' => date("Y-m-d", mktime(0,0,0,$month+1,1,$year)),
),
'order'=>'t.create_time DESC',
));
}
А зачем при переключении месяца сразу же перезагружается страница с результатом?
Логично было бы если например сегодня 1 число просмотреть что было в прошлом месяце 31 . то есть надо сначала клацнуть назад страница перезагружается потом нажать на 31.