Merge branch 'fresh-start' into cms-features

* fresh-start:
  update theme
  fixed coding convention nits
  internationalized the sponsor model fields
  Makes conference app fields and models localizable
  added documentation for conference models
  made sponsorship app conference-aware
  initial documentation of sponsorship app
  added sponsorship template tags and template fragments; improved admin
  fixed incorrect module name in import
  initial sponsorship app adapted from DjangoCon

Conflicts:
	symposion_project/requirements/base.txt
	symposion_project/settings.py
This commit is contained in:
Luke Hatcher 2012-05-21 20:10:32 -04:00
commit 637921628e
16 changed files with 320 additions and 12 deletions

View file

@ -1,4 +1,5 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from timezones.fields import TimeZoneField
@ -11,14 +12,14 @@ class Conference(models.Model):
the full conference for a specific year, e.g. US PyCon 2012.
"""
title = models.CharField(max_length=100)
title = models.CharField(_("title"), max_length=100)
# when the conference runs
start_date = models.DateField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
start_date = models.DateField(_("start date"), null=True, blank=True)
end_date = models.DateField(_("end date"), null=True, blank=True)
# timezone the conference is in
timezone = TimeZoneField(blank=True)
timezone = TimeZoneField(_("timezone"), blank=True)
def __unicode__(self):
return self.title
@ -35,6 +36,10 @@ class Conference(models.Model):
del CONFERENCE_CACHE[pk]
except KeyError:
pass
class Meta(object):
verbose_name = _("conference")
verbose_name_plural = _("conferences")
class Section(models.Model):
@ -44,16 +49,20 @@ class Section(models.Model):
scheduling process.
"""
conference = models.ForeignKey(Conference)
conference = models.ForeignKey(Conference, verbose_name=_("conference"))
name = models.CharField(max_length=100)
name = models.CharField(_("name"), max_length=100)
# when the section runs
start_date = models.DateField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
start_date = models.DateField(_("start date"), null=True, blank=True)
end_date = models.DateField(_("end date"), null=True, blank=True)
def __unicode__(self):
return self.name
class Meta(object):
verbose_name = _("section")
verbose_name_plural = _("sections")
def current_conference():

View file

@ -0,0 +1,7 @@
from django.contrib import admin
from sponsorship.models import SponsorLevel, Sponsor
admin.site.register(SponsorLevel)
admin.site.register(Sponsor, list_display=("name", "level", "added", "active"), list_filter = ("level", ))

View file

@ -0,0 +1,45 @@
import datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _
from conference.models import Conference
class SponsorLevel(models.Model):
conference = models.ForeignKey(Conference, verbose_name=_("conference"))
name = models.CharField(_("name"), max_length=100)
order = models.IntegerField(_("order"), default=0)
description = models.TextField(_("description"), blank=True)
class Meta:
ordering = ["conference", "order"]
verbose_name = _("sponsor level")
verbose_name_plural = _("sponsor levels")
def __unicode__(self):
return u"%s %s" % (self.conference, self.name)
def sponsors(self):
return self.sponsor_set.filter(active=True).order_by("added")
class Sponsor(models.Model):
name = models.CharField(_("name"), max_length=100)
external_url = models.URLField(_("external URL"))
annotation = models.TextField(_("annotation"), blank=True)
contact_name = models.CharField(_("contact_name"), max_length=100)
contact_email = models.EmailField(_(u"Contact e\u2011mail"))
logo = models.ImageField(_("logo"), upload_to="sponsor_logos/")
level = models.ForeignKey(SponsorLevel, verbose_name=_("level"))
added = models.DateTimeField(_("added"), default=datetime.datetime.now)
active = models.BooleanField(_("active"), default=False)
def __unicode__(self):
return self.name
class Meta:
verbose_name = _("sponsor")
verbose_name_plural = _("sponsors")

View file

@ -0,0 +1,75 @@
from django import template
from conference.models import current_conference
from sponsorship.models import Sponsor, SponsorLevel
register = template.Library()
class SponsorsNode(template.Node):
@classmethod
def handle_token(cls, parser, token):
bits = token.split_contents()
if len(bits) == 3 and bits[1] == "as":
return cls(bits[2])
elif len(bits) == 4 and bits[2] == "as":
return cls(bits[3], bits[1])
else:
raise template.TemplateSyntaxError("%r takes 'as var' or 'level as var'" % bits[0])
def __init__(self, context_var, level=None):
if level:
self.level = template.Variable(level)
else:
self.level = None
self.context_var = context_var
def render(self, context):
conference = current_conference()
if self.level:
level = self.level.resolve(context)
queryset = Sponsor.objects.filter(level__conference = conference, level__name__iexact = level, active = True).order_by("added")
else:
queryset = Sponsor.objects.filter(level__conference = conference, active = True).order_by("level__order", "added")
context[self.context_var] = queryset
return u""
class SponsorLevelNode(template.Node):
@classmethod
def handle_token(cls, parser, token):
bits = token.split_contents()
if len(bits) == 3 and bits[1] == "as":
return cls(bits[2])
else:
raise template.TemplateSyntaxError("%r takes 'as var'" % bits[0])
def __init__(self, context_var):
self.context_var = context_var
def render(self, context):
conference = current_conference()
context[self.context_var] = SponsorLevel.objects.filter(conference=conference)
return u""
@register.tag
def sponsors(parser, token):
"""
{% sponsors as all_sponsors %}
or
{% sponsors "gold" as gold_sponsors %}
"""
return SponsorsNode.handle_token(parser, token)
@register.tag
def sponsor_levels(parser, token):
"""
{% sponsor_levels as levels %}
"""
return SponsorLevelNode.handle_token(parser, token)

View file

@ -0,0 +1,40 @@
Conference App
==============
The overall conference settings are managed via the ``conference`` app.
Conferences and their sections are added and configured via the Django admin.
Models
------
Each conference needs an instance of a ``Conference`` model. In most cases you
will only need one of these but Symposion does support multiple conferences
sharing a database. Similar to the Django Sites framework, the conference your
project is for is selected by the ``CONFERENCE_ID`` setting which defaults to
``1`` but can be changed to the pk of another conference if you have more than
one.
The conference model has an optional ``start_date`` and ``end_date``
indicating when the conference will run. These are optional so you can begin
to configure your conference even if you don't know the exact dates.
The conference model also has a ``timezone`` field which you should set to the
timezone your conference will be in.
There is also a ``Section`` model. This is useful if your conference has
different parts to it that run of different days with a different management,
review or scheduling process. Example of distinct sections might be
"Tutorials", "Talks", "Workshops", "Sprints", "Expo". Many aspects of
Symposion can be configured on a per-section basis.
Each section has an optional ``start_date`` and ``end_date`` similar to the
overall conference.
Helper Functions
----------------
A ``conference.models.current_conference()`` function exists to retrieve the
``Conference`` selected by ``CONFERENCE_ID``.

View file

@ -10,11 +10,13 @@ We are in the process of cleaning things up and making them more generic.
The project homepage is http://pinax.github.com/symposion/
Contents:
Apps:
.. toctree::
:maxdepth: 2
conference
sponsorship
Indices and tables

View file

@ -0,0 +1,82 @@
Sponsorship App
===============
Sponsorship is managed via the ``sponsorship`` app.
Sponsorship levels and sponsors are added via the Django admin.
Models
------
Each sponsor level has a ``name`` (e.g. "Gold", "Silver") and an ``order``
field which is an integer that is used to sort levels (lowest first). Each
level also has a ``description`` which is not currently exposed anywhere
but can be used for private annotation.
Each sponsor has a ``name``, ``external_url`` (i.e. link to the sponsor's
website), ``contact_name`` and ``contact_email``, ``logo``, and ``level``.
A sponsor may also have a private ``annotation`` that can be used by
organizers to take notes about the sponsor.
A sponsor will not appear on the site until the ``active`` flag is set true.
Template Snippets
-----------------
The easiest way to include sponsor logos, grouped by level, is to either::
{% include "sponsorship/_vertical_by_level.html" %}
or::
{% include "sponsorship/_horizontal_by_level.html" %}
You can get a wall of sponsors (without level designation) with::
{% include "sponsorship/_wall.html" %}
You can always tweak these templates or use them as the basis for your own.
This is often all you'll need to do to display sponsors on your site.
If you want to display a specific sponsor logo you can use::
{% include "sponsorship/_sponsor_link.html" with sponsor=sponsor %}
or::
{% include "sponsorship/_sponsor_link.html" with sponsor=sponsor dimensions="100x100" %}
if you want different dimensions than the default 150 x 150.
Template Tags
-------------
If you want to retrieve the sponsors and traverse them yourself, you can use
the provided template tags::
{% load sponsorship_tags %}
{% sponsors as all_sponsors %}
or::
{% load sponsorship_tags %}
{% sponsors "Gold" as gold_sponsors %}
if you want to just get a specific level.
You can get the levels with::
{% load sponsorship_tags %}
{% sponsor_levels as levels %}
and you can always iterate over those levels, calling ``level.sponsors`` to
get the sponsors at that level.

View file

@ -27,4 +27,5 @@ django-reversion==1.5.1
django-markitup==1.0.0
markdown==2.1.1
pinax-theme-bootstrap==0.2.1
pinax-theme-bootstrap==2.0.3
django-forms-bootstrap==2.0.3.post1

View file

@ -4,4 +4,7 @@
--requirement=base.txt
# Put project-specific requirements here.
# See http://pip-installer.org/requirement-format.html for more information.
# See http://pip-installer.org/requirement-format.html for more information.
PIL==1.1.7
easy-thumbnails==1.0-alpha-21

View file

@ -151,6 +151,7 @@ INSTALLED_APPS = [
# theme
"pinax_theme_bootstrap",
"django_forms_bootstrap",
# external
"staticfiles",
@ -166,6 +167,7 @@ INSTALLED_APPS = [
"cms",
"mptt",
"reversion",
"easy_thumbnails",
# Pinax
"pinax.apps.account",
@ -173,6 +175,7 @@ INSTALLED_APPS = [
# project
"about",
"sponsorship",
"conference",
]

View file

@ -0,0 +1,11 @@
{% load sponsorship_tags %}
{% sponsor_levels as levels %}
<div class="sponsor-list">
{% for level in levels %}
<h3>{{ level.name }}</h3>
{% for sponsor in level.sponsors %}
{% include "sponsorship/_sponsor_link.html" with sponsor=sponsor %}
{% endfor %}
{% endfor %}
</div>

View file

@ -0,0 +1,10 @@
{% load thumbnail %}
{% spaceless %}
<a href="{{ sponsor.external_url }}">
{% if dimensions %}
<img src="{% thumbnail sponsor.logo dimensions %}" alt="{{ sponsor.name }}" />
{% else %}
<img src="{% thumbnail sponsor.logo '150x150' %}" alt="{{ sponsor.name }}" />
{% endif %}
</a>
{% endspaceless %}

View file

@ -0,0 +1,13 @@
{% load sponsorship_tags %}
{% sponsor_levels as levels %}
<div class="sponsor-list">
{% for level in levels %}
<h3>{{ level.name }}</h3>
{% for sponsor in level.sponsors %}
<div>
{% include "sponsorship/_sponsor_link.html" with sponsor=sponsor %}
</div>
{% endfor %}
{% endfor %}
</div>

View file

@ -0,0 +1,7 @@
{% load sponsorship_tags %}
{% sponsors as sponsors %}
<div class="sponsor-wall">
{% for sponsor in sponsors %}
{% include "sponsorship/_sponsor_link.html" with sponsor=sponsor %}
{% endfor %}
</div>