Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added settings for show_upcoming_events and show_past_events to control ... #3

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
52 changes: 46 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,60 @@ like this::

With this, you'll be able to add calendar and event items in your site.

Calendar Page Layout
--------------------

The default layout in the calendar template is to have the calendar at the top,
followed by a list of upcoming and past events. You have a choice of displaying
the upcoming and past events list or not, and whether it is shown above or
below the calendar.

And, if the events list is shown, you can control which goes first, upcoming or
past events.

Scope of Events Shown
---------------------

The default calendar will only show events that have been added to the calendar
itself. There are two other scopes available:

- site wide: Show all events found by an exhaustive search of the site database.
- recursive: Show events found in the calendar itself, in the current context
(where the calendar "lives"), and in any content nodes contained within.

The ``site wide`` choice is useful for a site that has a single calendar, and
the events need to be stored in different places around the site. For example,
if an add-on content type is a container for events, as with an "ArtClass" type
that contains events for class periods, the __init__.py setup for the add-on
can set the type_info.addable_to of Event, such as:::

Event.type_info.addable_to.append("ArtClass")

The ``recursive`` choice is useful for a site that has a need to show more than
one calendar. Imagine a site for a sporting league, in which there are two
divisions, "East" and "West." There are separate content hierarchies for these
divisions, with events held in some fashion within them. A calendar could be
added to each division, and the scope set to ``recursive`` to show all events
for the given division.

Upcoming events widget
----------------------

kotti_calendar provides a upcoming events widget, which is disabled by default.
To enable the widget add the following to the ``pyramid.includes`` setting::
To enable the widget in a slot add the following configuration line::

kotti_calendar.upcoming_events_widget.slot = left

where the value for ``slot`` is one of:::

pyramid.includes = kotti_calendar.widgets.includeme_upcoming_events
none, left, right, abovecontent, belowcontent, beforebodyend

With this, the upcoming events will be shown in the right column of the site.
Set this to ``none`` if you don't want the widget to show in a slot (the
default).

You can adjust how many events will be shown in the widget with set
``kotti_calendar.upcoming_events_widget.events_count`` to a different
value. It defaults to ``5``::
You can adjust how many events will be shown in the upcoming events widget, if
shown, with ``kotti_calendar.upcoming_events_widget.events_count``. It
defaults to ``5``::

kotti_calendar.upcoming_events_widget.events_count = 10

Expand Down
5 changes: 4 additions & 1 deletion development.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.debug_templates = true
pyramid.default_locale_name = de
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
pyramid_tm
Expand All @@ -17,6 +17,9 @@ kotti.secret = qwerty
# kotti_calendar specific configuration:
kotti.configurators = kotti_calendar.kotti_configure

kotti_calendar.upcoming_events_widget.slot = right
kotti_calendar.upcoming_events_widget.num_events = 5

[filter:fanstatic]
use = egg:fanstatic#fanstatic

Expand Down
47 changes: 39 additions & 8 deletions kotti_calendar/__init__.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,66 @@
from kotti.views.slots import assign_slot
from kotti.util import extract_from_settings

from pyramid.i18n import TranslationStringFactory

_ = TranslationStringFactory('kotti_calendar')


def kotti_configure(settings):

working_settings = upcoming_events_settings(settings=settings)

settings['kotti_calendar.upcoming_events_widget.slot'] = \
working_settings['slot']
settings['kotti_calendar.upcoming_events_widget.num_events'] = \
working_settings['num_events']

if working_settings['slot'] != 'none':
assign_slot('upcoming-events', working_settings['slot'])

settings['pyramid.includes'] += ' kotti_calendar kotti_calendar.views'
settings['kotti.available_types'] += ' kotti_calendar.resources.Calendar kotti_calendar.resources.Event'
settings['kotti.available_types'] += \
' kotti_calendar.resources.Calendar kotti_calendar.resources.Event'


EVENTS_WIDGET_DEFAULTS = {
'events_count': '5',
'slot': 'none',
'num_events': '5',
}


def events_settings(name=''):
def upcoming_events_settings(name='', settings=None):

prefix = 'kotti_calendar.upcoming_events_widget.'
if name:
prefix += name + '.' # pragma: no cover
settings = EVENTS_WIDGET_DEFAULTS.copy()
settings.update(extract_from_settings(prefix))

working_settings = EVENTS_WIDGET_DEFAULTS.copy()

working_settings.update(extract_from_settings(prefix, settings=settings))

try:
working_settings['num_events'] = int(working_settings['num_events'])
except ValueError:
working_settings['num_events'] = 5

try:
settings['events_count'] = int(settings['events_count'])
working_settings['slot'] in [u'none',
u'left',
u'right',
u'abovecontent',
u'belowcontent',
u'beforebodyend']
except ValueError:
settings['events_count'] = 5
return settings
working_settings['slot'] = 'none'

return working_settings


def includeme(config):

config.add_translation_dirs('kotti_calendar:locale')
config.scan(__name__)


def _patch_colander():
Expand Down
11 changes: 10 additions & 1 deletion kotti_calendar/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from kotti.resources import Document
from kotti.sqla import JsonType
from sqlalchemy import Boolean
from sqlalchemy import String
from sqlalchemy import Column
from sqlalchemy import DateTime
from sqlalchemy import ForeignKey
Expand All @@ -20,6 +21,9 @@ class Calendar(Content):
id = Column(Integer, ForeignKey('contents.id'), primary_key=True)
feeds = Column(JsonType(), nullable=False)
weekends = Column(Boolean())
scope = Column(String(128))
show_events_list = Column(String(128))
events_list_order = Column(String(128))

type_info = Content.type_info.copy(
name=u'Calendar',
Expand All @@ -28,10 +32,15 @@ class Calendar(Content):
addable_to=[u'Document'],
)

def __init__(self, feeds=(), weekends=True, **kwargs):
def __init__(self, feeds=(), weekends=True, scope='calendar_only',
show_events_list='below', events_list_order='upcoming_first',
**kwargs):
super(Calendar, self).__init__(**kwargs)
self.feeds = feeds
self.weekends = weekends
self.scope = scope
self.show_events_list = show_events_list
self.events_list_order = events_list_order


class Event(Document):
Expand Down
60 changes: 24 additions & 36 deletions kotti_calendar/templates/calendar-view.pt
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,32 @@
${api.context.description}
</p>

<div id="fullcalendar">
<div id="fullcalendar"
tal:condition="context.show_events_list == 'below'">

<div tal:repeat="events_dict events_dicts">
<h3 tal:condition="events_dict['label'] == 'upcoming'" i18n:translate="upcoming_events">Upcoming Events</h3>
<h3 tal:condition="events_dict['label'] == 'past'" i18n:translate="past_events">Past Events</h3>
<ul>
<li tal:repeat="event events_dict['events']">
<h4>
<a href="${api.url(event)}" title="${event.description}">
${event.title}
</a>
<span tal:define="format event.all_day and api.format_date or api.format_datetime">
${format(event.start)}
<span tal:condition="event.end">-
${format(event.end)}
</span>
</span>
</h4>
<p>${event.description}</p>
</li>
</ul>
</div>

<h2 tal:condition="upcoming_events" i18n:translate="upcoming_events">Upcoming events</h2>
<ul tal:condition="upcoming_events">
<li tal:repeat="event upcoming_events">
<h3>
<a href="${api.url(event)}" title="${event.description}">
${event.title}
</a>
<span tal:define="format event.all_day and api.format_date or api.format_datetime">
${format(event.start)}
<span tal:condition="event.end">-
${format(event.end)}
</span>
</span>
</h3>
<p>${event.description}</p>
</li>
</ul>

<h2 tal:condition="past_events" i18n:translate="past_events">Past events</h2>
<ul tal:condition="past_events">
<li tal:repeat="event past_events">
<h3>
<a href="${api.url(event)}" title="${event.description}">
${event.title}
</a>
<span tal:define="format event.all_day and api.format_date or api.format_datetime">
${format(event.start)}
<span tal:condition="event.end">-
${format(event.end)}
</span>
</span>
</h3>
<p>${event.description}</p>
</li>
</ul>
<div id="fullcalendar"
tal:condition="context.show_events_list == 'above'">

<script type="text/javascript">
$('#fullcalendar').fullCalendar($.extend(${fullcalendar_options}, localOptions));
Expand Down
34 changes: 15 additions & 19 deletions kotti_calendar/templates/upcoming-events.pt
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
<div tal:condition="events"
id="upcoming-events"
i18n:domain="kotti_calendar">
<h2 i18n:translate="">Upcoming events</h2>
<dl>
<tal:repeat tal:repeat="event events">
<dt class="upcoming-event">
<a href="${api.url(event)}" title="${event.description}">
${event.title}
</a>
</dt>
<dd>
<span tal:define="format event.all_day and api.format_date or api.format_datetime">
${format(event.start)}
<span tal:condition="event.end">-
${format(event.end)}
</span>
</span>
<p>${event.description}</p>
</dd>
</tal:repeat>
</dl>
<ul class="nav nav-list current-classes">
<li class="nav-header" i18n:translate="">Upcoming Events</li>
<li tal:repeat="event events">
<a href="${api.url(event)}" title="${event.description}">
${event.title}
</a>
<span tal:define="format event.all_day and api.format_date or api.format_datetime">
${format(event.start)}
<span tal:condition="event.end">-
${format(event.end)}
</span>
</span>
<p>${event.description}</p>
</li>
</ul>
</div>
5 changes: 4 additions & 1 deletion kotti_calendar/tests/browser.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Setup and Login
>>> from kotti import testing
>>> tools = testing.setUpFunctional(
... **{'kotti.configurators': 'kotti_calendar.kotti_configure'})
... 'kotti_calendar.upcoming_events_widget.slot': 'right',
... 'kotti_calendar.upcoming_events_widget.num_events': '5',
... })
>>> browser = tools['Browser']()
>>> ctrl = browser.getControl

Expand Down Expand Up @@ -70,7 +73,7 @@ View calendar and event
True
>>> browser.getLink("Day off").click()
>>> "Nov 12, 2010" in browser.contents
True
False


Edit calendar and events
Expand Down
45 changes: 45 additions & 0 deletions kotti_calendar/tests/test_configure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from pyramid.interfaces import ITranslationDirectories

from kotti_calendar import includeme
from kotti_calendar import kotti_configure


def test_kotti_configure():

settings = {
'kotti.available_types': '',
'pyramid.includes': '',
}

kotti_configure(settings)

assert settings['pyramid.includes'] == ' kotti_calendar kotti_calendar.views'
assert settings['kotti.available_types'] == ' kotti_calendar.resources.Calendar kotti_calendar.resources.Event'

assert settings['kotti_calendar.upcoming_events_widget.slot'] == 'none'
assert settings['kotti_calendar.upcoming_events_widget.num_events'] == 5

settings['kotti_calendar.upcoming_events_widget.num_events'] = "3"
kotti_configure(settings)
assert settings['kotti_calendar.upcoming_events_widget.num_events'] == 3

settings['kotti_calendar.upcoming_events_widget.slot'] = "right"
kotti_configure(settings)

from kotti.events import objectevent_listeners
from kotti.views.slots import RenderRightSlot

oel = objectevent_listeners
assert len(oel[(RenderRightSlot, None)]) == 1


def test_includeme(config):

includeme(config)

utils = config.registry.__dict__['_utility_registrations']
k = (ITranslationDirectories, u'')

# test if the translation dir is registered
assert k in utils
assert utils[k][0][0].find('kotti_calendar/locale') > 0
Loading