イベントカレンダーの作成 [Plone3.3]
年・月・日表示ができるイベントカレンダーをコレクションのビューとして作成する。利用方法はコレクションで表示するイベントタイプの検索条件(コンテンツタイプ、位置、日付など)を指定することを想定する。
スキンレイヤ
スキンレイヤの登録
まず portal_skins 内に新しくスキン格納用のフォルダ(eng_calendar_skins)を追加する。次に portal_skins の Properties で、custom の下に eng_calendar_skins を追加する。これでスキンにこのディレクトリも読み込まれるようになる。
Name : Plone Default Layers : custom eng_calendar_skins :
スキンの作成
週の文字列生成スクリプト
週の文字列を生成するスクリプト eng_calendar_weekstr をスキンレイヤ内に作成する。
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import PloneMessageFactory
translation_service = getToolByName(context, 'translation_service');
result_list = []
for i in xrange(7):
msgid = translation_service.day_msgid(i, format='a')
english = translation_service.weekday_english(i, format='a')
result_list.append(PloneMessageFactory(msgid, default=english))
return result_list
イベントリスト生成スクリプト
1ヶ月のイベントリスト生成スクリプト eng_calendar を次のように作成する。パラメータとしてリストを作成する年、月を渡す。
Parameter List
year, month
本体
end_date = container.portal_calendar.getNextMonth(month, year) - 1
last_day = end_date.day()
results = context.queryCatalog(
end = { 'query' : DateTime(year, month, 1, 0, 0), 'range' : 'min'},
start = { 'query' : DateTime(year, month, last_day, 23, 59), 'range' : 'max'},
sort_on = 'start',
)
event_list = []
for i in xrange(last_day):
day = i + 1
event_list.append({ 'day': day,
'week': DateTime(year, month, day).dow(),
'daily_events': [], })
for result in results:
if result.start.Date() == result.end.Date():
day = result.start.day()
event_list[day-1]['daily_events'].append( { 'title': result.Title,
'start': result.start,
'end': result.end,
'location': result.location,
'url': result.getURL(), } )
else:
if result.start < DateTime(year, month, 1, 0, 0):
day_begin = 1
else:
day_begin = result.start.day()
if result.end > DateTime(year, month, last_day, 23, 59):
day_end = last_day
else:
day_end = result.end.day()
for day in xrange(day_begin, day_end + 1):
event_list[day-1]['daily_events'].append( { 'title': result.Title,
'start': result.start,
'end': result.end,
'location': result.location,
'url': result.getURL(), } )
return event_list
カレンダーテンプレート
イベントカレンダーを表示するテンプレートを eng_calendar_view として次のように作成する。
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
lang="en"
metal:use-macro="here/main_template/macros/master"
i18n:domain="plone">
<body>
<div metal:fill-slot="main">
<metal:main_macro define-macro="main">
<metal:body define-macro="body_macro"
tal:define="kssClassesView context/@@kss_field_decorator_view;
getKssClasses nocall:kssClassesView/getKssClassesInlineEditable;
templateId template/getId">
<div tal:replace="structure provider:plone.abovecontenttitle" />
<h1 class="documentFirstHeading">
<metal:field use-macro="python:here.widget('title', mode='view')">
Title
</metal:field>
</h1>
<div tal:replace="structure provider:plone.belowcontenttitle" />
<p class="documentDescription">
<metal:field use-macro="python:here.widget('description', mode='view')">
Description
</metal:field>
</p>
<div tal:replace="structure provider:plone.abovecontentbody" />
<div tal:define="translation python:context.translation_service;
today python:DateTime();
month request/month | today/month;
month python:test(not request.has_key('month') and request.has_key('year'), 4, month);
month python:int(month);
day request/day | today/day;
day python:int(day);
orig_year request/year | today/year;
orig_year python:int(orig_year);
year python:month<4 and orig_year-1 or orig_year;
week_list python:context.eng_calendar_weekstr();
en_week_list python: [ translation.weekday_english(i, format='a') for i in range(0,7) ];
month_english python:translation.month_english(month);
event_list python:context.eng_calendar(orig_year, month);
base_url python:context.absolute_url();
msgfactory python:modules['Products.CMFPlone'].PloneMessageFactory;
param_year python:request.has_key('year');
param_month python:request.has_key('month');
param_day python:request.has_key('day');">
<!-- 年別タブ -->
<div tal:define="results python:context.queryCatalog( sort_on='start' );"
tal:condition="results">
<div id="year-tabs" tal:define="today_year today/year;
today_year python:int(today_year);
results python:context.queryCatalog( sort_on='start' );
month_begin python:test(results, results[0].start.month(), month);
year_begin python:test(results, results[0].start.year(), orig_year);
year_begin python:month_begin<4 and year_begin-1 or year_begin;
results python:context.queryCatalog( sort_on='end' );
month_end python:test(results, results[len(results)-1].end.month(), month);
year_end python:test(results, results[len(results)-1].end.year(), orig_year);
year_end python:month_end<4 and year_end-1 or year_end;">
<ul>
<tal:items tal:repeat="item python:xrange(year_begin, year_end+1)">
<li class="year-tab">
<a href="#"
tal:attributes="href python:base_url + '?year=' + str(item)">
<span tal:replace="python:str(item)" /><span tal:replace="python:test(language == 'ja', u'\u5e74\u5ea6', '')" />
</a>
</li>
</tal:items>
</ul>
</div>
</div>
<div class="visualClear"><!-- --></div>
<h2><span tal:replace="year" /> <span tal:replace="python:test(language == 'ja', u'\u5e74\u5ea6', u'Events')" /></h2>
<!-- 月別タブ -->
<div id="month-tabs" tal:define="month_list python:range(4,13) + range(1,4);"
tal:condition="python:not param_year or param_month or param_day">
<ul>
<tal:item repeat="month_num month_list">
<li class="month-tab"
tal:define="tab_year python:test(month_num<4, year+1, year)"
tal:attributes="class python:(month_num == month and 'active ' or '') + 'month_tab'">
<a href="#"
tal:attributes="href python:base_url + '?year=' + str(tab_year) + '&month=' + str(month_num);">
<span tal:define="english python:translation.month_english(month_num);
msgid python:translation.month_msgid(month_num);
msg python:msgfactory(msgid, default=english);"
tal:replace="msg">
April
</span>
</a>
</li>
</tal:item>
</ul>
</div>
<!-- 月カレンダーのヘッダ -->
<div id="calendar_header"
tal:condition="python:not param_day and (param_month or not param_year)">
<div id="april-logo" class="month-logo"
tal:attributes="id python:month_english.lower() + '-logo';
class string:month-logo;">
<img tal:attributes="src python:month_english.lower() + '-logo.jpg';
alt python:month_english;" />
</div>
<div id="april-picture" class="month-picture"
tal:attributes="id python:month_english.lower() + '-picture';
class string:month-picture;">
<img tal:attributes="src python:month_english.lower() + '-picture.jpg';" />
</div>
</div>
<!-- 月カレンダーのカレンダー部 -->
<table id="current_month_events"
tal:condition="python:not param_day and (param_month or not param_year)">
<tal:item tal:repeat="item event_list">
<tr class="event_item"
tal:define="week_str python:week_list[item['week']];
en_week_str python:en_week_list[item['week']].lower();"
tal:attributes="class python:'event_item week_' + en_week_str; ">
<td class="day">
<a href="#"
tal:omit-tag="python:not item['daily_events']"
tal:attributes="href python:base_url + '?year=' + str(orig_year) + '&month=' + str(month) + '&day=' + str(item['day'])">
<span tal:replace="python:item['day']">1</span>
</a>
</td>
<td class="week">
<span tal:content="week_str">Mon</span>
</td>
<td class="event_of_day">
<ul tal:condition="item/daily_events">
<li tal:repeat="event item/daily_events">
<a href="#" tal:attributes="href event/url">
<span tal:replace="event/title" />
</a>
</li>
</ul>
</td>
</tr>
</tal:item>
</table>
<!-- 日カレンダーのヘッダ -->
<div tal:condition="python:param_day">
<div id="calendar_header"
tal:define="msgid python:translation.month_msgid(month);
english python:translation.month_english(month);
month_msg python:msgfactory(msgid, default=english);
week_num python:event_list[day-1]['week'];
week_msgid python:translation.day_msgid(week_num);
week_english python:translation.weekday_english(week_num);
week_msg python:msgfactory(week_msgid, default=week_english);">
<div class="current-date">
<div class="today" tal:condition="python:language == 'ja'">
<span class="month" tal:content="month_msg" />
<span class="day" tal:content="python:str(day)">28</span><tal:date tal:replace="python:u'\u65e5'" />
<span class="weekday" tal:content="week_msg" />
</div>
<div class="today" tal:condition="python:language != 'ja'">
<span class="weekday" tal:content="week_msg">Monday</span>,
<span class="month" tal:content="month_msg">April</span>
<span class="day" tal:content="python:str(day)">28</span>
</div>
</div>
<div id="current_month_calendar" class="event_calendar">
<div id="calendar_month">
<span tal:replace="month_msg">March</span>
</div>
<table>
<tr>
<td class="weekday_sun" i18n:translate="weekday_sun_short">Su</td>
<td class="weekday_mon" i18n:translate="weekday_mon_short">Mo</td>
<td class="weekday_tue" i18n:translate="weekday_tue_short">Tu</td>
<td class="weekday_wed" i18n:translate="weekday_wed_short">We</td>
<td class="weekday_thu" i18n:translate="weekday_thu_short">Th</td>
<td class="weekday_fri" i18n:translate="weekday_fri_short">Fr</td>
<td class="weekday_sat" i18n:translate="weekday_sat_short">Sa</td>
</tr>
<tr tal:define="first_week python:event_list[0]['week'];
week_num python:len(event_list) + first_week;
week_num python:test(week_num%7, int(week_num/7)+1, int(week_num/7));"
tal:repeat="week python:xrange(week_num)">
<tal:item repeat="date python:xrange(week*7-first_week+1, week*7-first_week+8)">
<td tal:condition="python:date>0 and date<=len(event_list)"
tal:attributes="class python:event_list[date-1]['daily_events'] and 'event' or 'no_event';">
<a href="#"
tal:omit-tag="python:not event_list[date-1]['daily_events']"
tal:attributes="href python:base_url + '?year=' + str(orig_year) + '&month=' + str(month) + '&day=' + str(date);">
<span tal:replace="python:str(date)">1</span>
</a>
</td>
<td tal:condition="python:not (date>0 and date<=len(event_list))" />
</tal:item>
</tr>
</table>
</div>
</div>
</div>
<!-- 日カレンダー -->
<div id="day_events" tal:condition="python:param_day">
<div class="no_event_today"
tal:condition="python:not event_list[day-1]['daily_events']"
tal:content="python:test(language == 'ja', u'\u672c\u65e5\u958b\u50ac\u4e88\u5b9a\u306e\u30a4\u30d9\u30f3\u30c8\u306f\u3042\u308a\u307e\u305b\u3093\u3002', 'No Events Today.')"></div>
<table id="today_events" tal:condition="python:event_list[day-1]['daily_events']">
<tr class="day_list_header">
<th class="event_title"
tal:content="python:language=='ja' and u'\u884c\u4e8b\u540d' or 'Event'">Event</th>
<th class="event_when"
tal:content="python:language=='ja' and u'\u65e5\u6642\u30fb\u5834\u6240' or 'Date/Time, Location'">Date/Time</th>
</tr>
<tal:item tal:repeat="item python:event_list[day-1]['daily_events']">
<tr class="event_item">
<td class="event_title">
<a href="#" tal:attributes="href item/url;" tal:content="item/title" />
</td>
<td class="event_when"
tal:define="start_date item/start/Date;
end_date item/end/Date;">
<div tal:condition="python:start_date == end_date" tal:omit-tag="">
<span tal:content="item/start/TimeMinutes">3:10</span> -
<span tal:content="item/end/TimeMinutes"
tal:condition="python:item['start'] != item['end']">5:45</span>
<br /><span tal:content="item/location" />
</div>
<div tal:condition="python:start_date != end_date" tal:omit-tag=""
tal:define="notime python:test(item['start'].TimeMinutes()=='00:00' and item['end'].TimeMinutes()=='00:00', True, False)">
<span tal:content="python:item['start'].Date() + test(notime, '', ' ' + item['start'].TimeMinutes())">3:10</span> -
<span tal:content="python:item['end'].Date() + test(notime, '', ' ' + item['end'].TimeMinutes())">5:45</span>
<br /><span tal:content="item/location" />
</div>
</td>
</tr>
</tal:item>
</table>
</div>
<!-- 年カレンダー -->
<div class="year-page" tal:condition="python:param_year and not param_month and not param_day">
<div tal:define="month_list python:range(4,13) + range(1,4);"
tal:repeat="month month_list" tal:omit-tag="">
<div tal:define="tab_year python:test(month<4, year+1, year);
english python:translation.month_english(month, format='a').lower();"
tal:attributes="class python:'calendar-item calendar-' + english;">
<div class="year" tal:content="tab_year" />
<div class="month">
<a href="#"
tal:attributes="href python:base_url + '?year=' + str(tab_year) + '&month=' + str(month);"
tal:content="month">1</a>
</div>
<table tal:define="msgid python:translation.month_msgid(month);
english python:translation.month_english(month);
month_msg python:msgfactory(msgid, default=english);
event_list python:context.eng_calendar(tab_year, month);">
<tr class="week_head">
<td class="weekday_sun" i18n:translate="weekday_sun_short">Su</td>
<td class="weekday_mon" i18n:translate="weekday_mon_short">Mo</td>
<td class="weekday_tue" i18n:translate="weekday_tue_short">Tu</td>
<td class="weekday_wed" i18n:translate="weekday_wed_short">We</td>
<td class="weekday_thu" i18n:translate="weekday_thu_short">Th</td>
<td class="weekday_fri" i18n:translate="weekday_fri_short">Fr</td>
<td class="weekday_sat" i18n:translate="weekday_sat_short">Sa</td>
</tr>
<tr tal:define="first_week python:event_list[0]['week'];
week_num python:len(event_list) + first_week;
week_num python:test(week_num%7, int(week_num/7)+1, int(week_num/7));"
tal:repeat="week python:xrange(week_num)">
<tal:item repeat="date python:xrange(week*7-first_week+1, week*7-first_week+8)">
<td tal:condition="python:date>0 and date<=len(event_list)"
tal:attributes="class python:event_list[date-1]['daily_events'] and 'event' or 'no_event';">
<a href="#"
tal:omit-tag="python:not event_list[date-1]['daily_events']"
tal:attributes="href python:base_url + '?year=' + str(tab_year) + '&month=' + str(month) + '&day=' + str(date);">
<span tal:replace="python:str(date)">1</span>
</a>
</td>
<td tal:condition="python:not (date>0 and date<=len(event_list))" />
</tal:item>
</tr>
</table>
</div>
<div class="visualClear"
tal:condition="python: month % 3 == 0"><!-- --></div>
</div>
</div>
</div>
</metal:body>
</metal:main_macro>
</div>
</body>
</html>
画像
デザイン用の各月の画像などを同じレイヤに作成する。
イベントのXML出力
他のサイトとのイベント連携も可能となるよう XML 出力もできるようにしておく。ページテンプレートとしてスキンフォルダに eng_events_xml を追加する。追加したテンプレートの Properties タブより content_type を次のように変更する。
content_type : text/xml
テンプレートは次のように定義する。
<?xml version="1.0" encoding="UTF-8" ?>
<items xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
xmlns:metal="http://xml.zope.org/namespaces/metal"
tal:define="year request/year;
year python:int(year);
month request/month;
month python:int(month);
end_date python:context.portal_calendar.getNextMonth(month, year) - 1;
last_day python:end_date.day();
results python:here.queryCatalog({
'end' : { 'query' : DateTime(year, month, 1, 0, 0), 'range' : 'min'},
'start' : { 'query' : DateTime(year, month, last_day, 23, 59), 'range' : 'max'},
'sort_on' : 'start'});">
<item tal:repeat="result results">
<url tal:content="python:result.getObject().absolute_url()" />
<title tal:content="result/Title" />
<location tal:content="result/location" />
<start tal:content="result/start" />
<end tal:content="result/end" />
</item>
</items>
呼び出すには year と month を指定して次のように行う。これで指定した月のイベント一覧を出力できる。
http://イベントカレンダー用コレクションのURL/eng_events_xml?year=2009&month=4
設定
Topicのビューで選択できるものを指定する
フォルダのビューで選択できるものを指定する。上で作成した、eng_calendar_view も設定できるようにする。portal_types/Topic を開き Available view methods に次の行を追加する。
eng_calendar_view
曜日と月名の翻訳を追加する
Plone3では曜日と月の翻訳が定義されていないため、plone.app.locales/plone/app/locales/i18n/plone-ja.po を編集してPlone2.5時の翻訳を追加する。
#. Default: "Sun" #: datetime abbreviation of a day, format %a msgid "weekday_sun_abbr" msgstr "日" #. Default: "Mon" #: datetime abbreviation of a day, format %a msgid "weekday_mon_abbr" msgstr "月" #. Default: "Tue" #: datetime abbreviation of a day, format %a msgid "weekday_tue_abbr" msgstr "火" #. Default: "Wed" #: datetime abbreviation of a day, format %a msgid "weekday_wed_abbr" msgstr "水" #. Default: "Thu" #: datetime abbreviation of a day, format %a msgid "weekday_thu_abbr" msgstr "木" #. Default: "Fri" #: datetime abbreviation of a day, format %a msgid "weekday_fri_abbr" msgstr "金" #. Default: "Sat" #: datetime abbreviation of a day, format %a msgid "weekday_sat_abbr" msgstr "土" #. Default: "Sunday" #: datetime name of a day, format %A msgid "weekday_sun" msgstr "日曜日" #. Default: "Monday" #: datetime name of a day, format %A msgid "weekday_mon" msgstr "月曜日" #. Default: "Tuesday" #: datetime name of a day, format %A msgid "weekday_tue" msgstr "火曜日" #. Default: "Wednesday" #: datetime name of a day, format %A msgid "weekday_wed" msgstr "水曜日" #. Default: "Thursday" #: datetime name of a day, format %A msgid "weekday_thu" msgstr "木曜日" #. Default: "Friday" #: datetime name of a day, format %A msgid "weekday_fri" msgstr "金曜日" #. Default: "Saturday" #: datetime name of a day, format %A msgid "weekday_sat" msgstr "土曜日" # Shorthand for "Sunday" #. Default: "Su" #: datetime two letter abbreviation of a day used in the portlet_calendar msgid "weekday_sun_short" msgstr "日" # Shorthand for "Monday" #. Default: "Mo" #: datetime two letter abbreviation of a day used in the portlet_calendar msgid "weekday_mon_short" msgstr "月" # Shorthand for "Tuesday" #. Default: "Tu" #: datetime two letter abbreviation of a day used in the portlet_calendar msgid "weekday_tue_short" msgstr "火" # Shorthand for "Wednesday" #. Default: "We" #: datetime two letter abbreviation of a day used in the portlet_calendar msgid "weekday_wed_short" msgstr "水" # Shorthand for "Thursday" #. Default: "Th" #: datetime two letter abbreviation of a day used in the portlet_calendar msgid "weekday_thu_short" msgstr "木" # Shorthand for "Friday" #. Default: "Fr" #: datetime two letter abbreviation of a day used in the portlet_calendar msgid "weekday_fri_short" msgstr "金" # Shorthand for "Saturday" #. Default: "Sa" #: datetime two letter abbreviation of a day used in the portlet_calendar msgid "weekday_sat_short" msgstr "土" #. Default: "January" #: datetime name of a month, format %B msgid "month_jan" msgstr "1月" #. Default: "February" #: datetime name of a month, format %B msgid "month_feb" msgstr "2月" #. Default: "March" #: datetime name of a month, format %B msgid "month_mar" msgstr "3月" #. Default: "April" #: datetime name of a month, format %B msgid "month_apr" msgstr "4月" #. Default: "May" #: datetime name of a month, format %B msgid "month_may" msgstr "5月" #. Default: "June" #: datetime name of a month, format %B msgid "month_jun" msgstr "6月" #. Default: "July" #: datetime name of a month, format %B msgid "month_jul" msgstr "7月" #. Default: "August" #: datetime name of a month, format %B msgid "month_aug" msgstr "8月" #. Default: "September" #: datetime name of a month, format %B msgid "month_sep" msgstr "9月" #. Default: "October" #: datetime name of a month, format %B msgid "month_oct" msgstr "10月" #. Default: "November" #: datetime name of a month, format %B msgid "month_nov" msgstr "11月" #. Default: "December" #: datetime name of a month, format %B msgid "month_dec" msgstr "12月"
