Simple Django event calendar template tag

Simple Django event calendar template tag

blogserver / apps / blog / templatetags / event_tags.py


##### Here is the template tag code. It goes in a file named
# "event_tags.py" in a subdirectory of your app called "templatetags".
#####

from calendar import HTMLCalendar
from django import template
from datetime import *
from itertools import groupby
import pdb
from django.utils.html import conditional_escape as esc
from blogserver.apps.blog.models import Post
register = template.Library()

def do_event_calendar(parser, token):
    """
    The template tag's syntax is {% event_calendar year month event_list %}
    """

    try:
        #tag_name, year, month, event_list = token.split_contents()
        tag_name= token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires three arguments" % token.contents.split()[0]
    #return EventCalendarNode(year, month, event_list)
    return EventCalendarNode()

class EventCalendarNode(template.Node):
    """
    Process a particular node in the template. Fail silently.
    """

    def __init__(self,):
        try:
            lToday = datetime.now()
            #self.year = template.Variable(year)
            #self.month = template.Variable(month)
            self.year = lToday.year
            self.month = lToday.month
            my_events = Post.objects.filter(date_published__year=self.year, date_published__month=self.month)
            #self.event_list = template.Variable(event_list)
            self.event_list = my_events
        except ValueError:
            raise template.TemplateSyntaxError

    def render(self, context):
        try:
            # Get the variables from the context so the method is thread-safe.
            #my_event_list = self.event_list.resolve(context)
            #my_year = self.year.resolve(context)
            #my_month = self.month.resolve(context)
            my_event_list = self.event_list
            my_year = self.year
            #pdb.set_trace()
            my_month = self.month
            cal = EventCalendar(my_event_list)
            return cal.formatmonth(int(my_year), int(my_month))
        except ValueError:
            return
        except template.VariableDoesNotExist:
            return

class EventCalendar(HTMLCalendar):
    """
    Overload Python's calendar.HTMLCalendar to add the appropriate events to
    each day's table cell.
    """

    def __init__(self, events):
        super(EventCalendar, self).__init__()
        self.events = self.group_by_day(events)

    def formatday(self, day, weekday):
        if day != 0:
            cssclass = self.cssclasses[weekday]
            if date.today() == date(self.year, self.month, day):
                cssclass += ' today'
            if day in self.events:
                cssclass += ' filled'
                href="/%d/%02d/%02d/"%(self.year,self.month,day)
                return self.day_cell(cssclass, '<span class="dayNumber" title="click to view post"><a href=%s >%d</a></span>' % (href,day))
            return self.day_cell(cssclass, '<span class="dayNumberNoEvents">%d</span>' % (day))
        return self.day_cell('noday', '&nbsp;')

    def formatmonth(self, year, month):
        self.year, self.month = year, month
        return super(EventCalendar, self).formatmonth(year, month)

    def group_by_day(self, events):
        field = lambda event: event.date_published.day
        return dict(
            [(day, list(items)) for day, items in groupby(events, field)]
        )

    def day_cell(self, cssclass, body):
        return '<td class="%s">%s</td>' % (cssclass, body)

# Register the template tag so it is available to templates
register.tag("event_calendar", do_event_calendar)

 blogserver/ views.py

# Create your views here.
from django.shortcuts import render_to_response
import pdb
from datetime import *
from calendar import monthrange
from blogserver.apps.blog.models import Post
from django.template import RequestContext
from django.utils.html import conditional_escape as esc
from django.utils.safestring import mark_safe
from itertools import groupby
from calendar import HTMLCalendar, monthrange
##### Here’s code for the view to look up the event objects for to put in
# the context for the template. It goes in your app’s views.py file (or
# wherever you put your views).
#####
def named_month(month_number):
    “””
Return the name of the month, given the number.
“””
    return date(1900, month_number, 1).strftime(“%B”)
def this_month(request):
    “””
Show calendar of events this month.
“””
    today = datetime.now()
    return calendar(request, today.year, today.month)
def calendar(request, year, month, series_id=None):
    “””
Show calendar of events for a given month of a given year.
“series_id“
The event series to show. None shows all event series.
“””
    my_year = int(year)
    my_month = int(month)
    my_calendar_from_month = datetime(my_year, my_month, 1)
    my_calendar_to_month = datetime(my_year, my_month, monthrange(my_year, my_month)[1])
    my_events = Post.objects.filter(date_published__year=my_year, date_published__month=my_month)
    if series_id:
        my_events = my_events.filter(series=series_id)
    # Calculate values for the calendar controls. 1-indexed (Jan = 1)
    my_previous_year = my_year
    my_previous_month = my_month – 1
    if my_previous_month == 0:
        my_previous_year = my_year – 1
        my_previous_month = 12
    my_next_year = my_year
    my_next_month = my_month + 1
    if my_next_month == 13:
        my_next_year = my_year + 1
        my_next_month = 1
    my_year_after_this = my_year + 1
    my_year_before_this = my_year – 1
    #pdb.set_trace()
    return render_to_response(“blog/calendar.html”, { ‘events_list': my_events,
                                                        ‘month': my_month,
                                                        ‘month_name': named_month(my_month),
                                                        ‘year': my_year,
                                                        ‘previous_month': my_previous_month,
                                                        ‘previous_month_name': named_month(my_previous_month),
                                                        ‘previous_year': my_previous_year,
                                                        ‘next_month': my_next_month,
                                                        ‘next_month_name': named_month(my_next_month),
                                                        ‘next_year': my_next_year,
                                                        ‘year_before_this': my_year_before_this,
                                                        ‘year_after_this': my_year_after_this,
    }, context_instance=RequestContext(request))
def post_calendar(request):
  #pdb.set_trace()
# return render_to_response(“base.html”,)
  lToday = datetime.now()
  return calendar(request, lToday.year, lToday.month)
def base_page(request):
  #pdb.set_trace()
  return render_to_response(“base.html”,)
  #lToday = datetime.now()
  #return calendar(request, lToday.year, lToday.month)
##### Here’s code for the view to look up the event objects for to put in
# the context for the template. It goes in your app’s views.py file (or
# wherever you put your views).
#####
 blogserver / templates / blog/ calendar.html
at end do not forget to setting your url files
<style type="text/css">
/* Calendar */

#calendar table {
    width: 100%;
}

#calendar table tr th {
    text-align: center;
    font-size: 16px;
    background-color: #316497;
    color: #99ccff;
}

#calendar table tr td {
    width: 10%;
    border: 1px solid #555;
    vertical-align: top;
    height: 20px;
    padding: 2px;
}

#calendar td.noday {

}

#calendar td.filled {
    background-color: #99ccff;
}

#calendar td.today {
    border: 4px solid #316497;
}

#calendar .dayNumber {
    font-size: 16px !important;
    font-weight: bold;
}

#calendar a {
    font-size: 10px;
}

}
</style>
{% load event_tags %}

<div id="calendar">
{% event_calendar year month events_list %}
</div>
And I think the better way is bulit the calendar in css or js files and get event from the server