neue Verzeichnissstruktur

This commit is contained in:
Christian Berg
2014-11-26 13:13:07 +01:00
parent daa35f5913
commit f34281089d
3372 changed files with 168 additions and 2544 deletions

0
content/__init__.py Normal file
View File

60
content/admin.py Normal file
View File

@@ -0,0 +1,60 @@
'''
Created on 19.09.2011
@author: christian
'''
# import stuff we need from django
from django.contrib import admin
from . import models
class PageTabularInline(admin.TabularInline):
fields = ('title_de', 'menu_name_de', "position",)
model = models.Page
sortable_field_name = "position"
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("headline_de",)}
list_display = ('headline', 'category', 'date_created', 'author',)
list_editable = ('category', 'author')
class CategoryAdmin(admin.ModelAdmin):
list_display = ['name', 'slug', 'description']
list_display_links = ('name', 'slug',)
prepopulated_fields = {'slug': ('name_de',)}
class PageAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ('menu_name_de',)}
inlines = [PageTabularInline, ]
list_display = ('position', 'menu_name', 'title', 'parent', 'path',)
list_display_links = ('menu_name', 'title',)
list_editable = ('position',)
list_filter = ('parent',)
search_fields = ('menu_name_de', 'title_de',)
fieldsets = (
('Deutsch', {
'fields': ('menu_name_de', 'title_de', 'pdf_de', 'content_de',),
'classes': ('collapse',),
}),
('English', {
'fields': ('menu_name_en', 'title_en', 'pdf_en', 'content_en'),
'classes': ('collapse', 'closed'),
}),
('Meta Data', {
'fields': ('content_type', 'slug', ('parent', 'position'),
'status', 'template',)
}),
)
class Media:
js = [
'/static/js/tiny_mce/tiny_mce.js',
'/static/js/tinymce_setup.js',
]
admin.site.register(models.Article, ArticleAdmin)
admin.site.register(models.Page, PageAdmin)
admin.site.register(models.Category, CategoryAdmin)

View File

@@ -0,0 +1,49 @@
# -*- encoding: UTF-8 -*-
'''
Created on 30.09.2011
@author: christian
'''
from . import models
from django.core.cache import cache
def content_menus(request):
current_page = None
current_path = request.path_info[1:request.path_info.rfind('.')]
current_top_page = None
# erzeuge das Top-Level Menü
top_menu_items = []
top_level_pages = cache.get('top_level_pages')
if top_level_pages == None:
top_level_pages = models.Page.objects.filter(parent=None)
top_level_pages = top_level_pages.exclude(slug='index')
top_level_pages = top_level_pages.order_by('position')
cache.set('top_level_pages', top_level_pages, 360)
for item in top_level_pages:
if current_path.startswith(item.path):
item.active = True
current_top_page = item
else:
item.active = False
top_menu_items.append(item)
# Entdecke die aktuell geöffnete Seite
all_pages = cache.get('all_pages')
if all_pages == None:
all_pages = models.Page.objects.values_list('path', 'id')
all_pages = dict((path, page_id) for path, page_id in all_pages)
cache.set('all_pages', all_pages, 360)
while len(current_path) > 0:
if current_path in all_pages:
current_page = models.Page.objects.get(pk=all_pages[current_path])
break
current_path = current_path[0:current_path.rfind('.')]
return {'top_menu_items': top_menu_items,
'current_top_page': current_top_page,
'current_path': current_path,
'current_page': current_page
}

61
content/feeds.py Normal file
View File

@@ -0,0 +1,61 @@
from datetime import datetime, time
from django.conf import settings
from django.utils.translation import ugettext as _
from django.contrib import comments
from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Rss201rev2Feed
from models import Article
class LatestNews(Feed):
link = "http://www.kasu.at/"
description = _("Current news from Kasu")
title = "Kasu - traditonelle asiatische Spielkultur"
feed_type = Rss201rev2Feed
def items(self, obj):
return Article.objects.published()[:10]
def item_title(self, item):
return item.headline
def item_author_name(self, item):
return item.author.username
def item_categories(self, item):
return (item.category.name,)
def item_description(self, item):
return item.content
def item_pubdate(self, item):
return datetime.combine(item.date_created, time())
class LatestComments(Feed):
"""Feed of latest comments on the current site."""
link = "http://www.kasu.at/"
description = _("Latest comments on kasu.at")
title = _("Kasu - latest comments")
feed_type = Rss201rev2Feed
def items(self):
qs = comments.get_model().objects.filter(site__pk=settings.SITE_ID,
is_public=True, is_removed=False)
return qs.order_by('-submit_date')[:40]
def item_author_name(self, item):
return item.user_name
def item_description(self, item):
return item.comment
def item_pubdate(self, item):
return item.submit_date
def item_title(self, item):
return 'From %(user_name)s in %(content_object)s' % {
'user_name': item.user_name,
'content_object': item.content_object
}

58
content/forms.py Normal file
View File

@@ -0,0 +1,58 @@
'''
Created on 04.10.2011
@author: christian
'''
import django.forms
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext as _
from utils.html5 import forms
from . import models
class ArticleForm(forms.ModelForm):
error_css_class = 'error'
required_css_class = 'required'
class Meta(object):
fields = ('headline_de', 'content_de', 'headline_en', 'content_en',
'category', 'image')
model = models.Article
def save(self, force_insert=False, force_update=False, commit=True):
article = super(ArticleForm, self).save(commit=False)
article.slug = slugify(article.headline_de)[:50]
if commit:
article.save(force_insert=force_insert, force_update=force_update)
return article
class PageForm(forms.ModelForm):
error_css_class = 'error'
required_css_class = 'required'
content_type = django.forms.ChoiceField(
choices=models.CONTENT_CHOICES,
widget=django.forms.RadioSelect
)
class Meta(object):
exclude = ('position',)
model = models.Page
def clean(self):
cleaned_data = super(PageForm, self).clean()
content_type = cleaned_data.get("content_type")
pdf_de = cleaned_data.get("pdf_de")
if not pdf_de and content_type == "2":
msg = _('Please upload a PDF-File to this PDF-Page.')
self._errors["content_type"] = self.error_class([msg])
self._errors["pdf_de"] = self.error_class([msg])
# These fields are no longer valid. Remove them from the
# cleaned data.
del cleaned_data["content_type"]
del cleaned_data["pdf_de"]
# Always return the full collection of cleaned data.
return cleaned_data

View File

@@ -0,0 +1 @@
#

View File

@@ -0,0 +1 @@
#!/usr/bin/python

View File

@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
from content.models import Article, Category
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from django.template.defaultfilters import slugify
from django.utils.datetime_safe import datetime
import re
import xlrd #@UnresolvedImport
class Command(BaseCommand):
help = "Importiert die alten Daten aus einer CSV Datei" #@ReservedAssignment
date_header_regex = r"""<h1><span class=\"small\">(?P<date>[\d\.]*)[\ -]*</span>[\ -]*(?P<title>.*)</h1>(?P<content>.*)"""
header_regex = r"""<h1>[\ -]*(?P<title>.*)</h1>(?P<content>.*)"""
def __init__(self):
self.author = User.objects.get(username="xeniac")
self.category = Category.objects.get(slug='allgemeines')
def create_article(self):
self.slug = slugify(self.headline[:50])
article, created = Article.objects.get_or_create(slug=self.slug, date_created=self.date_created,
defaults={
'author': self.author,
'headline_de': self.headline,
'content_de': self.content,
'category': self.category
})
if created:
print "Created: %s - %s" % (self.date_created, self.headline)
article.clean()
article.save()
def parse_with_date(self, original):
match_obj = re.search(self.date_header_regex, original, re.IGNORECASE | re.DOTALL)
if match_obj:
self.date_created = datetime.strptime(match_obj.group('date'), '%d.%m.%Y')
self.headline = match_obj.group('title').strip()
self.content = match_obj.group('content').strip()
return True
else:
return False
def parse_without_date(self, original):
match_obj = re.search(self.header_regex, original, re.IGNORECASE | re.DOTALL)
if match_obj:
self.date_created = datetime.strptime('01.01.1982', '%d.%m.%Y')
self.headline = match_obj.group('title').strip()
self.content = match_obj.group('content').strip()
return True
else:
return False
def handle(self, *args, **options):
try:
xls_file = xlrd.open_workbook(args[0])
except IndexError:
print "Bitte den Pfad zur CSV Datei angeben!"
return False
except IOError:
print "Datei '%s' wurde nicht gefunden! " % args[0]
return False
table = xls_file.sheet_by_index(0)
for row in xrange(1, table.nrows):
if not table.cell_value(row, 2) in ('Archiv', 'News'):
continue
original = table.cell_value(row, 3)
if self.parse_with_date(original) or self.parse_without_date(original):
self.create_article()
else:
print "Fehler bei String!"
print table.cell_value(row, 3)

View File

@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from django.utils.datetime_safe import datetime
from events.models import Event, Location
import xlrd # @UnresolvedImport
class Command(BaseCommand):
help = "Importiert die alten Events" # @ReservedAssignment
def __init__(self):
self.author = User.objects.get(username="xeniac")
def handle(self, *args, **options):
try:
xls_file = xlrd.open_workbook(args[0])
except IndexError:
return "Bitte den Pfad zur Excel Datei angeben!"
except IOError:
return "Datei '%s' wurde nicht gefunden! " % args[0]
table = xls_file.sheet_by_index(0)
for row in xrange(1, table.nrows):
name = table.cell_value(row, 0)
print name
start = xlrd.xldate_as_tuple(table.cell_value(row, 1),
xls_file.datemode)
start = datetime(start[0], start[1], start[2], 0, 0, 0)
end = xlrd.xldate_as_tuple(table.cell_value(row, 2),
xls_file.datemode)
end = datetime(end[0], end[1], end[2], 23, 59, 59)
location = Location.objects.get(pk=table.cell_value(row, 3))
Event.objects.get_or_create(name=name, start=start, defaults={
'end': end,
'location': location,
})

262
content/models.py Normal file
View File

@@ -0,0 +1,262 @@
# -*- coding: utf-8 -*-
from os import path
from django.utils.timezone import now
from django.core.urlresolvers import reverse
from django.core.cache import cache
from django.db import models
from django.template.defaultfilters import slugify
from django.utils.safestring import mark_safe
from django.utils.translation import get_language, ugettext as _
from imagekit.models import ImageSpecField
from imagekit.processors import SmartResize
from utils import STATUS_CHOICES, STATUS_WAITING, STATUS_PUBLISHED, \
STATUS_REJECTED, cleaner, OverwriteStorage # @UnusedImport
from django.core.exceptions import ValidationError
CONTENT_CHOICES = (
(0, u'Django View'),
(1, u'HTML'),
(2, u'PDF')
)
def get_upload_path(instance, filename):
'''
Generates the desired file path and filename for an uploaded Image.
With this function Django can save the uploaded images to subfolders that
also have a meaning for humans.
@param instance: an Django Object for which the Image has been uploaded.
@type instance: a instace of an models.Model sub-class.
@param filename: The filename of the uploaded image.
@type filename: String
'''
extension = filename[filename.rfind('.') + 1:]
if isinstance(instance, Category):
return "categories/%s.%s" % (instance.slug, extension)
class ImageModel(models.Model):
article = ImageSpecField(
source='image',
processors=[SmartResize(width=210, height=130)]
)
class Meta:
abstract = True
class ArticleManager(models.Manager):
def published(self):
return self.filter(status=STATUS_PUBLISHED, date_created__lte=now())
class Article(ImageModel):
headline_de = models.CharField(_('Headline'), max_length=255)
headline_en = models.CharField('Headline', max_length=255, blank=True)
content_de = models.TextField(_('Content'))
content_en = models.TextField('Content', blank=True)
category = models.ForeignKey('Category', verbose_name=_('Category'))
image = models.ImageField(_('Image'), upload_to='news/',
blank=True, null=True)
slug = models.SlugField(_('Slug'), unique_for_month='date_created')
author = models.ForeignKey('auth.User', verbose_name=_('Author'))
status = models.SmallIntegerField(_('Status'), choices=STATUS_CHOICES,
default=STATUS_PUBLISHED)
date_created = models.DateField(_('Created'), blank=True)
date_modified = models.DateTimeField(_('Modified'), auto_now=True)
objects = ArticleManager()
class Meta(object):
verbose_name = _('Article')
verbose_name_plural = _('Articles')
ordering = ('-date_created',)
def clean(self):
if not self.date_created:
self.date_created = now()
if not self.slug:
self.slug = slugify(self.headline_de)[:50]
self.content_de = cleaner.clean_html(self.content_de)
self.content_en = cleaner.clean_html(self.content_en)
def __unicode__(self):
return self.headline
@property
def posting_image(self):
if self.image:
return self.article
else:
return self.category.article
def get_absolute_url(self):
kwargs = {
'year': self.date_created.strftime('%Y'),
'month': self.date_created.strftime('%m'),
'slug': self.slug,
}
return reverse('show-article', kwargs=kwargs)
@property
def headline(self):
headline = getattr(self, "headline_%s" % get_language())
if not headline:
return mark_safe(self.headline_de)
else:
return mark_safe(headline)
@property
def content(self):
content = getattr(self, "content_%s" % get_language(), self.content_de)
if not content:
return mark_safe(self.content_de)
else:
return mark_safe(content)
class Page(models.Model):
'''
Eine Seite auf der Homepage. Sie kann eine "statische" HTML Seite,
die URL einer dynamische Django View, oder ein PDF Dokument sein.
Jede Seite kann neben Deutsch auch auf Englisch angeboten werden.
Ist keine englische Übersetzung vorhanden, wird die deutsche Version
angeboten.
'''
menu_name_de = models.CharField(
'Menü Name',
max_length=255,
help_text=_('The short name for the menu-entry of this page')
)
menu_name_en = models.CharField(
'Menu Name',
max_length=255,
blank=True,
help_text=_('The short name for the menu-entry of this page')
)
title_de = models.CharField('Titel', max_length=255,
help_text=_('This title appears in the HTML header'))
title_en = models.CharField('Title', max_length=255, blank=True,
help_text=_('This title appears in the HTML header'))
slug = models.SlugField(_('slug'))
path = models.CharField(_('Path'), max_length=100, db_index=True,
editable=False, unique=True)
parent = models.ForeignKey('self', blank=True, null=True,
related_name='subpages', on_delete=models.SET_NULL)
position = models.PositiveSmallIntegerField(_('Position'),
blank=True, null=True)
status = models.SmallIntegerField(_('status'), choices=STATUS_CHOICES,
default=STATUS_WAITING)
content_type = models.IntegerField(choices=CONTENT_CHOICES)
content_de = models.TextField('Inhalt', blank=True)
content_en = models.TextField('Content', blank=True)
enable_comments = models.BooleanField(_('enable comments'), default=True)
template = models.CharField(_('Template'), max_length=100,
default="content/page.html")
pdf_de = models.FileField(upload_to='pdf/de/', blank=True, null=True)
pdf_en = models.FileField(upload_to='pdf/en/', blank=True, null=True)
def __unicode__(self):
return u'%s' % self.title
@property
def content(self):
return mark_safe(getattr(self, "content_%s" % get_language()) or \
self.content_de)
@property
def css_class(self):
return CONTENT_CHOICES[self.content_type][1].lower().replace(' ', '_')
@property
def menu_name(self):
return getattr(self, "menu_name_%s" % get_language()) or \
self.menu_name_de
@property
def pdf_file(self):
return getattr(self, "pdf_%s" % get_language()) or self.pdf_de
@property
def title(self):
return getattr(self, "title_%s" % get_language()) or self.title_de
def clean(self):
if self.parent == None:
self.path = self.slug
else:
self.path = path.join(self.parent.path, self.slug)
if self.content_type == None:
if self.pdf_de:
self.content_type = 2
if self.content_de:
self.content_type = 1
else:
self.content_type = 0
if self.content_type == 1:
self.content_de = cleaner.clean_html(self.content_de)
self.content_en = cleaner.clean_html(self.content_en)
elif self.content_type == 2 and not self.pdf_de.name:
raise ValidationError(
_(u'Please upload a PDF-File to this PDF-Page.'))
def get_absolute_url(self):
path = '/' + self.path
if self.content_type == 1:
path += '.html'
elif self.content_type == 2:
path += '.pdf'
else:
path += '/'
return path
class Meta(object):
ordering = ['parent__id', 'position']
unique_together = (('slug', 'parent'),)
verbose_name = _('Page')
verbose_name_plural = _('Pages')
class Category(ImageModel):
name_de = models.CharField(_('Name'), max_length=80)
name_en = models.CharField(_('Name'), max_length=80, blank=True)
description_de = models.TextField(_('Description'))
description_en = models.TextField(_('Description'), blank=True)
image = models.ImageField(_('Image'), upload_to='news/categories/',
blank=True, null=True)
slug = models.SlugField(_('Slug'), unique=True, db_index=True)
class Meta(object):
ordering = ('slug',)
verbose_name = _('Category')
verbose_name_plural = _('Categories')
@property
def name(self):
return getattr(self, "name_%s" % get_language(), self.name_de)
@property
def description(self):
return getattr(self, "description_%s" % get_language(),
self.description_de)
def get_absolute_url(self):
return reverse('article-archive', kwargs={'category': self.slug})
def __unicode__(self):
return self.name
def force_cache_update(sender, instance, **kwargs):
for page in instance.subpages.all():
page.clean()
page.save()
cache.delete('all_pages')
cache.delete('top_level_pages')
models.signals.post_delete.connect(force_cache_update, sender=Page)
models.signals.post_save.connect(force_cache_update, sender=Page)

11
content/specs.py Normal file
View File

@@ -0,0 +1,11 @@
from imagekit.specs import ImageSpec
from imagekit import processors
class ResizeArticle(processors.Resize):
width = 210
height = 130
crop = True
class Article(ImageSpec):
pre_cache = True
processors = [ResizeArticle]

View File

@@ -0,0 +1,94 @@
{% extends "base.html" %}
{% load i18n comments %}
{% block title %}
{% trans 'Article Archive' %}
{% if active_category %} - {{active_category.name}}{% endif %}
{% if month %}{{ month|date:'F Y' }}</h2>{% elif year %}{{year}}{% endif %}
{% endblock %}
{% block meta_title %}
{% trans 'Article Archive' %}
{% if active_category %} - {{active_category.name}}{% endif %}
{% if month %}{{ month|date:'F Y' }}</h2>{% elif year %}{{year}}{% endif %}
{% endblock %}
{% block extra_head %}
<style type="text/css" media="screen and (min-width: 701px)">#teaser{background-image:url("{{STATIC_URL}}img/news_teaser.jpg")}</style>
<!--[if lt IE 9]><style type="text/css" media="screen">#teaser{background-image:url("{{STATIC_URL}}img/news_teaser.jpg")}</style><![endif]-->
{% endblock %}
{% block navigation %}
<ul id="navigation">
<li><a href="{{current_top_page.get_absolute_url}}" {% if not active_category %}class="active"{% endif %}>{% trans 'All Categories' %}</a></li>
{% for category in categories %}
<li><a href="{% url 'article-archive' category=category.slug %}"
{% ifequal category.slug active_category.slug %}class="active"{% endifequal %}>{{ category.name }}</a></li>
{% endfor %}
</ul>
<!--[if lt IE 9]><style type="text/css" media="screen">#teaser{background-image:url("{{STATIC_URL}}img/news_teaser.jpg")}</style><![endif]-->
{% endblock %}
{% block maincontent %}
<section id="teaser" class="grid_8">
<div id="teaser_text">
<h2>{% trans 'Article Archive' %}
{% if active_category %} - {{active_category.name}}{% endif %}
{% if month %}{{ month|date:'F Y' }}</h2>{% elif year %}{{year}}{% endif %}
</h2>
{{content|safe}}
</div>
</section>
<section class="grid_4 red_box">
{% block date_list %}
<h2>{% trans "Archive" %} {{year}}</h2>
<ul class="list" style="margin: 20px;">
{% if active_category %}
{% for date in date_list %}
<li class="date"><a href="{% url "article-archive" category=active_category.slug year=date|date:'Y' %}">{{active_category.name}}: {{ date|date:'Y' }}</a></li>
{% endfor %}
{% else %}
{% for date in date_list %}
<li class="date"><a href="{% url "article-archive" year=date|date:'Y' %}">{{ date|date:'Y' }}</a></li>
{% endfor %}
{% endif %}
</ul>
{% endblock %}
</section>
<section class="grid_8">
{% for article in article_list %}
{% get_comment_count for article as comment_count %}
<article class="article">
<h3><a href="{{article.get_absolute_url}}">{{article.headline}}</a></h3>
<ul class="info">
<li><img src="{{STATIC_URL}}icons/calendar.png" alt="{% trans 'created on' %}:" title="{% trans 'created on' %}"/> <time datetime="{{article.date_created|date:"c"}}">{{ article.date_created|date }}</time></li>
<li><img src="{{STATIC_URL}}icons/user_red.png" alt="{% trans 'by' %}:" title="{% trans 'by' %}"/> <span class="author">{{ article.author }}</span></li>
<li><img src="{{STATIC_URL}}icons/comments.png" alt="{% trans 'comments' %}:" title="{% trans 'comments' %}"/> <a href="{{article.get_absolute_url}}#comments" >{{comment_count}} {% trans "comments" %}</a></li>
</ul>
<a href="{{article.get_absolute_url}}"><img src="{{article.posting_image.url}}" alt="{{article.category}}:" class="posting_image"/></a>
{{article.content|truncatewords_html:50}}
<p class="more_link"><a href="{{article.get_absolute_url}}" class="button">{% trans "Read More"%} <img src="{{STATIC_URL}}icons/page_go.png" alt="&raquo;" /></a></p>
</article>
{% empty %}
<p>{% trans "We're sorry. Your search yielded no results." %}</p>
{% endfor %}
</section>
<aside class="grid_4">
{% for feed in feeds %}
<h2><a href="{{feed.public_url}}">{{feed.title}}</a></h2>
<ul>
{% for item in feed.feed_items.all %}
<li><a href="{{item.link}}">{{item.title}}</a></li>
{% endfor %}
</ul>
{% endfor %}
</aside>
{% endblock %}
{% block additional_buttonbar %}
{% if perms.content.add_article %}
<a href="{% url "add-article" %}" class="button"><img src="{{ STATIC_URL }}icons/note_add.png" alt="" /> {% trans "Add Article" %}</a>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,9 @@
{% extends "content/article_archive.html" %}
{% load i18n %}
{% block date_list %}
<h2>{% trans "Archive" %} {{month|date:'E'}}</h2>
<div class="buttonbar">
<a href="{% url "article-archive" year=month|date:'Y' %}" class="button"><img src="{{ STATIC_URL }}icons/arrow_undo.png" alt="{% trans 'back' %}" /> {% trans 'back' %}</a>
</div>
{% endblock %}

View File

@@ -0,0 +1,20 @@
{% extends "content/article_archive.html" %}
{% load i18n %}
{% block meta_title %}{{ article.headline }}{% endblock %}
{% block date_list %}
<h2>{% trans "Archive" %} {{year}}</h2>
<ul class="list" style="margin: 20px;">
{% if active_category %}
{% for date in date_list %}
<li class="date"><a href="{% url "article-archive" category=active_category.slug year=year|date:'Y' month=date|date:'m' %}">{{active_category.name}}: {{ date|date:'F' }}</a></li>
{% endfor %}
{% else %}
{% for date in date_list %}
<li class="date"><a href="{% url "article-archive" year=year|date:'Y' month=date|date:'m' %}">{{ date|date:'F' }}</a></li>
{% endfor %}
{% endif %}
</ul>
{% endblock %}

View File

@@ -0,0 +1,54 @@
{% extends "base.html" %}
{% load i18n comments %}
{% block title %}{{ article.headline }}{% endblock %}
{% block description %}{{article.content|striptags|truncatewords:16}}{% endblock %}
{% block extra_head %}
<link rel="image_src" type="image/jpeg" href="{{article.posting_image.url}}" />
{% endblock %}
{% block opengraph %}
<meta property="og:type" content="article" />
<meta property="og:title" content="{{ article.headline }}" />
<meta property="og:url" content="http://www.kasu.at{{ article.get_absolute_url }}" />
<meta property="og:image" content="http://www.kasu.at{{article.posting_image.url}}" />
<meta property="og:description" content="{{article.content|striptags|truncatewords:25}}" />
{% endblock %}
{% block itemscope %}itemscope itemtype="http://schema.org/Article"{% endblock %}
{% block content %}
<h2 itemprop="name">{{article.headline}}</h2>
<div itemprop="articleBody">{{ article.content }}</div>
{% endblock %}
{% block sidebar %}
<img alt="{{article.category.name}}" src="{{article.posting_image.url}}" class="posting_image" itemprop="image"/>
<p>&nbsp;</p>
<ul class="info">
<li class="user"><strong>{% trans 'Author' %}:</strong> <a href="{% url "membership-details" article.author %}" itemprop="author">{{article.author}}</a></li>
<li class="date"><strong>{% trans 'Created on' %}: </strong><time date="{{article.date_created|date:"c"}}">{{ article.date_created|date }}</time></li>
<li class="category"><strong>{% trans "Category"%}: </strong><a href="{{ article.category.get_absolute_url }}" itemprop="articleSection">{{article.category.name}}</a></li>
</ul>
<p class="center">
<a href="https://plus.google.com/share?url=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}" onclick="javascript:window.open(this.href,
'', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"><img src="{{STATIC_URL}}img/google_plus.png" alt="Google+" title="{% trans 'Share on Google+'%}" width="39" height="39"/></a>
<a href="https://twitter.com/share?url=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}" target='_blank'><img src="{{STATIC_URL}}img/twitter.png" alt="Twitter" title="{% trans 'Share on Twitter' %}" width="39" height="39"/></a>
<a href="http://facebook.com/sharer.php?u=http%3A%2F%2Fwww.kasu.at{{article.get_absolute_url|urlencode}}?t={{article.headline|urlencode}}" target="_blank"><img src="{{STATIC_URL}}img/facebook.png" alt="Facebook" title="{% trans 'Share on Facebook'%}" width="39" height="39"/></a>
</p>
{% endblock %}
{% block comments%}
{% render_comment_list for article %}
{% render_comment_form for article %}
{% endblock %}
{% block buttonbar %}
{% if perms.content.change_article %}
<a href="{% url "edit-article" article.id %}" class="button"><img src="{{STATIC_URL}}icons/note_edit.png" alt="" />{% trans "Edit Article" %}</a>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,52 @@
{% extends "base.html" %}
{% load i18n fieldset_extras %}
{% block title %}
{% if object.pk %}{% trans "Edit Article" %}{% else %}{% trans "Create Article" %}{% endif %}
{% endblock %}
{% block extra_head %}
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/language_tabs.js" ></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/ckeditor/ckeditor.js"></script>
{% endblock %}
{% block maincontent %}
{% get_fieldset "category, image" from form as fieldset_common %}
{% get_fieldset "headline_de, content_de" from form as fieldset_de %}
{% get_fieldset "headline_en, content_en" from form as fieldset_en %}
<form action="" method="post" enctype="multipart/formdata" class="grid_12">
<fieldset>
<legend>{% if object.pk %}{% trans "Edit Article" %}{% else %}{% trans "Create Article" %}{% endif %}</legend>
{% csrf_token %}
{% with fieldset_common as form %}{% include "form.html" %}{% endwith %}
</fieldset>
<ul class="tabs">
<li><a href="#de">{% trans "German" %}</a></li>
<li><a href="#en">{% trans "English" %}</a></li>
</ul>
<div class="tab_container">
<fieldset id="de" class="tab_content">
<legend>Deutsch</legend>
{% with fieldset_de as form %}{% include "form.html" %}{% endwith %}
</fieldset>
<fieldset id="en" class="tab_content">
<legend>English</legend>
{% with fieldset_en as form %}{% include "form.html" %}{% endwith %}
</fieldset>
</div>
<p class="buttonbar">
<button type="reset"><img src="{{STATIC_URL}}icons/arrow_undo.png" alt="{% trans 'reset' %}" /> {% trans 'reset' %}</button>
<button type="submit"><img src="{{STATIC_URL}}icons/disk.png" alt="{% trans 'save' %}" /> {% trans 'save' %}</button>
</p>
</form>
{% endblock %}
{% block javascript %}
CKEDITOR.replace( 'id_content_de' );
CKEDITOR.replace( 'id_content_en' );
{% endblock %}
{% block buttonbar %}{% endblock %}

View File

@@ -0,0 +1,27 @@
{% extends "base.html" %}
{% load comments %}
{% block meta_title %}{{ page.title }}{% endblock %}
{% block title %}{{page.title}}{% endblock %}
{% block opengraph %}
<meta property="og:type" content="website" />
<meta property="og:title" content="{{page.title}}" />
<meta property="og:url" content="http://www.kasu.at{{ page.get_absolute_url }}" />
<meta property="og:image" content="http://www.kasu.at/static/img/logo.png" />
<meta property="og:description" content="{{ page.content|striptags|truncatewords:25 }}" />
{% endblock %}
{% block maincontent %}
<h2 class="grid_12">{{ page.title }}</h2>
{{ page.content }}
{% endblock %}
{% block comments %}
{% if page.enable_comments %}
{% render_comment_list for page %}
{% render_comment_form for page %}
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,36 @@
{% extends "base.html" %}
{% load comments i18n %}
{% block meta_title %}{{ title }}{% endblock %}
{% block title %}{{page.title}}{% endblock %}
{% block opengraph %}
<meta property="og:type" content="website" />
<meta property="og:title" content="{{page.title}}" />
<meta property="og:url" content="http://www.kasu.at{{ page.get_absolute_url }}" />
<meta property="og:image" content="http://www.kasu.at/static/img/logo.png" />
<meta property="og:description" content="{{ page.content|striptags|truncatewords:25 }}" />
{% endblock %}
{% block content %}
<h2>{{ page.title }}</h2>
{{ page.content }}
{% endblock %}
{% block sidebar %}
{% if current_top_page.subpages %}
<h2>{% trans "Subpages" %}</h2>
{% for subpage in current_top_page.subpages.all %}
<h3><a href="{{ subpage.get_absolute_url }}">{{subpage.menu_name}}</a></h3>
<ul class="list">
{% for subpage in subpage.subpages.all %}<li class="{{subpage.css_class}}"><a href="{{ subpage.get_absolute_url }}">{{ subpage.menu_name }}</a></li>{% endfor %}
</ul>
{% endfor %}
{% endif %}
{% endblock %}
{% block comments %}{% if page.enable_comments %}
{% render_comment_list for page %}
{% render_comment_form for page %}
{% endif %}{% endblock %}

View File

@@ -0,0 +1,58 @@
{% extends "base.html" %}
{% load i18n fieldset_extras %}
{% block title %}{% if object.pk %}{% trans "Edit Page" %}: {{ page.title }}{% else %}{% trans "Add Page" %}{% endif %}{% endblock %}
{% block extra_head %}
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/language_tabs.js" ></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/ckeditor/ckeditor.js"></script>
{% endblock %}
{% block maincontent %}
{% get_fieldset "parent, slug, content_type, status" from form as fieldset_common %}
{% get_fieldset "menu_name_de, title_de, pdf_de, content_de" from form as fieldset_de %}
{% get_fieldset "menu_name_en, title_en, pdf_en, content_en" from form as fieldset_en %}
{% get_fieldset "template, enable_comments" from form as fieldset_html %}
<form method="post" enctype="multipart/form-data" class="grid_12">
{% csrf_token %}
<fieldset>
<legend>{% if object.pk %}{% trans "Edit Page" %}{% else %}{% trans "Add Page" %}{% endif %}</legend>
{% with fieldset_common as form %}{% include "form.html" %}{% endwith %}
</fieldset>
<ul class="tabs">
<li><a href="#de">{% trans "German" %}</a></li>
<li><a href="#en">{% trans "English" %}</a></li>
</ul>
<div class="tab_container">
<fieldset id="de" class="tab_content">
<legend>{% trans "German" %}</legend>
{% with fieldset_de as form %}{% include "form.html" %}{% endwith %}
</fieldset>
<fieldset id="en" class="tab_content">
<legend>{% trans "English" %}</legend>
{% with fieldset_en as form %}{% include "form.html" %}{% endwith %}
</fieldset>
</div>
<fieldset>
<legend>{% trans "HTML Specific" %}</legend>
{% with fieldset_html as form %}{% include "form.html" %}{% endwith %}
</fieldset>
<p class="buttonbar">
<button type="reset"><img src="{{STATIC_URL}}icons/arrow_undo.png" alt="{% trans 'reset' %}" /> {% trans 'reset' %}</button>
<button type="submit"><img src="{{STATIC_URL}}icons/page_save.png" alt="{% trans 'save' %}" /> {% trans 'save' %}</button>
</p>
</form>
{% endblock %}
{% block javascript %}
CKEDITOR.replace( 'id_content_de' );
CKEDITOR.replace( 'id_content_en' );
{% endblock %}

View File

@@ -0,0 +1,66 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>{% block title %}{{page.title}}{% endblock %}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
@font-face {
font-family: 'Amerika Sans';
src: url('{{ STATIC_ROOT }}/fonts/amerika_sans.ttf');
}
@font-face {
font-family: 'Philosopher';
src: url('{{ STATIC_ROOT }}/fonts/philosopher-regular.ttf');
font-weight: normal;
font-style: normal;
}
h1,h2,h3,h4,h5,h6 {
font-family: 'Amerika Sans', Helvetica;
font-variant: small-caps;
font-weight: bold;
margin: 0.5em 0 0.2em 0;
}
body {
font-family: Philosopher;
font-size: 12pt;
}
#page_header {
text-align: right;
}
@page {
margin-right: 0mm;
margin-bottom: 0mm;
margin-top: 35mm;
margin-left: 2cm;
@frame header {
-pdf-frame-content : page_header;
top: 0mm;
margin: 5mm;
height: 4cm;
}
@frame footer {
-pdf-frame-content: page_footer;
bottom: 0cm;
height: 2cm;
margin: 5mm;
}
}
</style>
</head>
<body>
<h1>{{ page.title }}</h1>
{{ page.content }}
<div id="page_header">
<img src="{{STATIC_ROOT}}/img/logo.png" alt="Kasu">
</div>
<div id="page_footer">
{{ page.title }} Seite:
<pdf:pagenumber>
</div>
</body>
</html>

View File

View File

@@ -0,0 +1,43 @@
'''
Created on 10.06.2012
@author: christian
'''
from django import template
from django.utils.datastructures import SortedDict
import copy
register = template.Library()
class FieldSetNode(template.Node):
def __init__(self, form_variable, variable_name, fields):
self.fields = fields
self.variable_name = variable_name
self.form_variable = form_variable
def render(self, context):
form = template.Variable(self.form_variable).resolve(context)
new_form = copy.copy(form)
# new_form.fields = SortedDict([(key, value) for key, value in
# form.fields.items() if key in self.fields])
new_form.fields = SortedDict(
[(key, form.fields[key]) for key in self.fields]
)
context[self.variable_name] = new_form
return u''
def get_fieldset(parser, token):
try:
_name_, fields, _from_, form, _as_, variable_name = \
token.split_contents()
fields = fields[1:-1]
fields = [field.strip() for field in fields.split(',')]
except ValueError:
raise template.TemplateSyntaxError(
'bad arguments for %r' % token.split_contents()[0]
)
return FieldSetNode(form, variable_name, fields)
get_fieldset = register.tag(get_fieldset)

16
content/tests.py Normal file
View File

@@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

216
content/views.py Normal file
View File

@@ -0,0 +1,216 @@
# Create your views here.
from . import models, forms
from aggregator.models import Feed
from django.conf import settings
from django.contrib import comments
from django.http import HttpResponse, Http404
from django.utils.translation import ugettext as _
from django.views import generic
from utils.mixins import PermissionRequiredMixin
import events.models
import os
from django.shortcuts import get_object_or_404
class ArticleArchiveMixin(object):
def get_context_data(self, **kwargs):
context = super(ArticleArchiveMixin, self).get_context_data(**kwargs)
context['categories'] = models.Category.objects.all()
context['active_category'] = self.category
context['feeds'] = Feed.objects.active()
return context
class ArticleArchiveIndex(ArticleArchiveMixin, generic.ArchiveIndexView):
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
date_field = 'date_created'
paginate_by = 5
context_object_name = 'article_list'
allow_empty = True
def get_queryset(self):
queryset = generic.ArchiveIndexView.get_queryset(self)
self.category = self.kwargs.get('category')
if self.category:
try:
self.category = models.Category.objects.get(slug=self.category)
queryset = queryset.filter(category=self.category)
except models.Category.DoesNotExist:
raise Http404(_("This Category does not exist."))
return queryset
class ArticleYearArchive(ArticleArchiveMixin, generic.YearArchiveView):
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
date_field = 'date_created'
paginate_by = 5
year_format = '%Y'
make_object_list = True
allow_empty = True
def get_queryset(self):
queryset = generic.YearArchiveView.get_queryset(self)
self.category = self.kwargs.get('category')
if self.category:
self.category = get_object_or_404(models.Category, slug=self.category)
queryset = queryset.filter(category=self.category)
return queryset
class ArticleMonthArchive(ArticleArchiveMixin, generic.MonthArchiveView):
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
date_field = 'date_created'
month_format = '%m'
paginate_by = 5
make_object_list = True
allow_empty = True
def get_queryset(self):
queryset = generic.MonthArchiveView.get_queryset(self)
self.category = self.kwargs.get('category')
if self.category:
self.category = models.Category.objects.get(slug=self.category)
queryset = queryset.filter(category=self.category)
return queryset
class ArticleDetail(generic.DetailView):
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
class ArticleForm(PermissionRequiredMixin, generic.UpdateView):
model = models.Article
form_class = forms.ArticleForm
permission_required = 'content.change_article'
def get_object(self):
if self.kwargs.get('pk', None):
return models.Article.objects.get(pk=self.kwargs['pk'])
else:
return models.Article(author=self.request.user)
class ImageList(generic.View):
def get(self, kwargs):
image_list = []
response = HttpResponse(content_type='text/javascript')
response.write('var tinyMCEImageList = new Array(')
os.chdir(settings.MEDIA_ROOT)
for dirpath, dirnames, filenames in os.walk('images'): # @UnusedVariable @IgnorePep8
filenames.sort()
for filename in filenames:
image_list.append('["%(name)s", "%(path)s"]' % {
'name': os.path.join(dirpath, filename),
'path': os.path.join(settings.MEDIA_URL, dirpath, filename)
})
response.write(', '.join(image_list))
response.write(');')
return response
class PageAddForm(PermissionRequiredMixin, generic.CreateView):
form_class = forms.PageForm
template_name = 'content/page_form.html'
permission_required = 'content.add_page'
def get_initial(self):
path = os.path.splitext(self.kwargs['path'])[0]
if path.startswith('/'):
path = path[1:]
if path.endswith('/'):
path = path[:-1]
parent = models.Page.objects.get(path=path)
return {'parent': parent}
class PageEditForm(PermissionRequiredMixin, generic.UpdateView):
form_class = forms.PageForm
permission_required = 'content.change_page'
def get_object(self, queryset=None):
path = os.path.splitext(self.kwargs['path'])[0]
if path.startswith('/'):
path = path[1:]
if path.endswith('/'):
path = path[:-1]
return models.Page.objects.get(path=path)
class PageHtml(generic.DetailView):
def get_object(self, queryset=None):
try:
return models.Page.objects.get(path=self.kwargs['path'],
content_type=1)
except models.Page.DoesNotExist:
raise Http404(
_("No Page found matching the Path %s") % self.request.path
)
def get_template_names(self):
return self.object.template
class PagePdf(generic.DeleteView):
def get_object(self, queryset=None):
try:
return models.Page.objects.get(path=self.kwargs['path'],
content_type=2)
except models.Page.DoesNotExist:
raise Http404(
_("No PDF Document found matching the Path %s") %
self.request.path
)
def render_to_response(self, context, **response_kwargs):
try:
pdf_file = open(self.object.pdf_file.path, 'rb')
response = HttpResponse(pdf_file.read(),
content_type='application/pdf')
pdf_file.close()
return response
except:
raise Http404('File not Found %s.pdf' % self.kwargs['path'])
class PageList(generic.View):
def get(self, kwargs):
response = HttpResponse(content_type='text/javascript')
response.write('var tinyMCELinkList = new Array(')
page_list = []
for page in models.Page.objects.filter(status=models.STATUS_PUBLISHED):
page_list.append('["%(name)s", "%(path)s"]' % {
'name': page.menu_name,
'path': page.get_absolute_url()
})
response.write(', '.join(page_list))
response.write(');')
return response
class StartPage(generic.TemplateView):
template_name = 'index.html'
def get_context_data(self, **kwargs):
page = models.Page.objects.get(slug='index')
random_photo = events.models.Photo.objects.get_random(startpage=True)
recent_comment_list = comments.get_model().objects.filter(
site__pk=settings.SITE_ID,
is_public=True,
is_removed=False,
)
recent_comment_list = recent_comment_list.order_by('-submit_date')[:10]
context = {
'title': page.title,
'content': page.content,
'random_photo': random_photo.callout,
'current_event': events.models.Event.objects.current_event(),
'next_event': events.models.Event.objects.next_event(),
'upcoming_events': events.models.Event.objects.upcoming(),
'recent_article_list': models.Article.objects.published()[:3],
'recent_comment_list': recent_comment_list,
}
return context
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)