Code


Version 2 (modified by Carl Karsten <carl@…>, 7 years ago) (diff)

--

Here is what happens when you browse to http://www.example.com/eventcal/2007/08/

The URL is split into host/path, path is used to find a view:

In this case, it gets done in 2 steps. the "eventcal" part is used to route things into the 'calendar app' which lives in eventcal:

line 9 of ./urls.py:
     (r'^eventcal/', include('eventcal.urls')),

line 7 of ./eventcal/urls.py
    (r'^(?P<year>\d{4})/(?P<month>\d{2})/$', 'month_index'),

The parameters are extracted: year and month - (?P<year>\d{4}) = decimal(4) And calls month_index( request, year, month )

(it can also be called with no year/month, which defaults to the current date.)

def month_index(request, year = None, month = None):
    now = datetime.today()
    if not year:
      year = now.year
    if not month:
      month = now.month
    year = int(year)
    month = int(month)

    # Make sure we have a sane date.
    # A munged URL could give us month 13
    try:
        cal_date = date(year, month, 1)
    except ValueError:
        raise Http404

    # Week starts on Sunday
    c=calendar.Calendar(calendar.SUNDAY)

    # get all the dates that will be displayed,
    # including the tail and head of previous/next months.
    # (a list of weeks, each week is a list of 7 dates.)
    dates=c.monthdatescalendar(year, month)

    # array, ['Monday', 'Tuesday'.. 0 is Mon.
    ## daynames=calendar.day_name
    # make list, cuz I can't figure out how to use the array in the template.
    # Use the first week of the calandar, which is handy
    # because it makes sure the week starts on the weekday we want it to
    # (like Sunday)
    daynames= [ calendar.day_name[d.weekday()] for d in dates[0] ]

    # get Events from the DB that are in the specified month.
    # [0][0] = first day of first week, [-1][-1], last day of last week.
    # so start/end of the range being displaied.
    events = Event.objects.filter(eventdate__range=(dates[0][0],dates[-1][-1]))

    # some fluf to make the page usable
    prev_month=(cal_date+relativedelta(months=-1))# .month
    next_month=(cal_date+relativedelta(months=+1))# .month

    return render_to_response('month_index.html', locals())

render_to_response() takes a template file month_index.html and a bunch of vars (easy way: pass all the local vars) and returns browser ready HTML. I should probably not use .html for these files, cuz they aren't; but all the cool people use .html, so I'll fight that battle some other day.

Template commands used here: {# X #} one line comments. {% comment %}X X X...{% endcomment %} multi line comment.

{% extends X %} - kinda like subclass X. kinda like #include if you don't pay attention too close. but more like subclassing because {% block Y %} defined in X can be overridden (replaced) if it is redefined in the current code. in this case, main.html defines the 'stuff that will be on all pages' including some placeholders for headings and content, and month_index.html defines the headings and content. I can't figure out if it really is subclassing, or just similar.

{{ X }} - expression evaluation - think VFPs <<X>> text merge. X is evaluated, result is put in the HTML. pipe char | is used like unix filters to format the results. /{{ prev_month|date:"Y/m" }} prev_month is a date. |date:"Y/m" makes a string out of the year/month. so 6/1/2007 becomes "2007/6" which makes a nice URL for handing into the top of this process. <a href="/eventcal/2007/6">prev</a>

{% for week in dates %} {% endfor %} basic for loop.

{% ifequal day now.date %} {% endifequal %}> it's IF, but for some reason they made the operator? part of the command instead of "IF X" where X is a boolean. no clue why. possibly for speed.

{# month_index.html #}
{% extends "main.html" %}

{% block css %}
<link href="/static/css/calendar.css" type="text/css" rel="stylesheet" />
{% endblock %}

{% block title %}Calendar{% endblock %}

{% block list_title %}Events{% endblock %}

{% block content %}

{# Display month/year and links to previous/next month. #}
<div class="content-vol">
<h4 class="calendar_heading">
<a href="/eventcal/{{ prev_month|date:"Y/m" }}/"> &lt; </a>
{{ cal_date|date:"F" }} 
{# <a href="/eventcal/{{ cal_date.year }}/"> #}
{# <a href="/eventcal/databrowse/eventcal/event/calendars/eventdate/"> #}
{{ cal_date.year }}
<a href="/eventcal/{{ next_month|date:"Y/m" }}/"> &gt; </a>
</h4>

{# headers: Monday, Tuesday.... #}
<table class="cal_month_calendar">
<tr>
{% for dayname in daynames %}
  <th>{{ dayname }}</th>
{% endfor %}
</tr>

{# What we came here for: the days and events. #}
{# Make the grid of days #}
{% for week in dates %}
<tr class="pc_row_odd" align="left" valign="top">
{% for day in week %}
<td
{% ifequal day now.date %} class="today"
{% else %} {% ifequal day.month month %} 
  class="cal_in_month" 
  {% else %} class="cal_not_in_month"
 {% endifequal %}
{% endifequal %}>

<div class="pc_calendar_date">
<a href="/eventcal/{{ day|date:"Y/m/j" }}/#daysevents">
{{ day|date:"j" }}
</a> </div> 
{# spin thought the list of evetns, find ones for current day #}
{% for event in events %}
  {% ifequal event.eventdate day %}
  <p class="event_desc">
  {# <a href="/eventcal/databrowse/eventcal/event/objects/{{ event.id }}/"> #}
  <a href="/eventcal/detail/{{ event.id }}/">
  {{ event.title }}</a>

</p>
  {% endifequal %}
{% endfor %}
</td>

{% endfor %}
</tr>
{% endfor %}
</table>
<br/>

{# List the days events in a list. #}
<A name=daysevents></A>
<ul class="event_list">
Events for {{cal_date|date:"l, F j, Y"}}
<hr>

{% for event in days_events %}
<li> 
  {# <a href="/eventcal/databrowse/eventcal/event/objects/{{ event.id }}/"> #}
  <a href="/eventcal/detail/{{ event.id }}/">{{ event.title }}</a>
   {{ event.detail|linebreaks }}</span> 
  </li>
  <hr>
{% endfor %}
</ul>

</div>

{% endblock %}

Pretty much all main does is define the 'menu' that will be on all pages.

{# main.html #}
{% extends "base.html" %}
{% block css %}{% endblock %}
{% block title %}Logged in{% endblock %}
{% block headtags %}
{% endblock %}
{% block content %}{% endblock %}
{% block foottags %}
<a href="/eventcal">Event Calendar</a>
<a href="/admin">Admin</a>
<a href="/messages">Messages</a>
<a href='/logout'>logout</a>
{% endblock %}

base.html is the top most file on the food chain.

{# base.html #}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>My Great Site {% block title %}{% endblock %}</title>
  <link href="/static/css/style.css" rel="stylesheet" type="text/css" /> 
  {% block css %}{% endblock %}
</head>

<body background="/static/images/background.png">

  <div id="container">
  
   <div id="header">
        {% block headtags %}{% endblock %}
   </div>

   <div id="main">
        {% block content %}{% endblock %}
   </div>

   <div id="footer">
        {% block foottags %}{% endblock %}
   </div>


  </div> <!-- /container -->
 </body>
</html>