from django.contrib import admin
-from philo.admin import EntityAdmin, AddTagAdmin
+from django import forms
+from philo.admin import EntityAdmin, AddTagAdmin, COLLAPSE_CLASSES
from philo.contrib.penfield.models import BlogEntry, Blog, BlogView, Newsletter, NewsletterArticle, NewsletterIssue, NewsletterView
+class DelayedDateForm(forms.ModelForm):
+ date_field = 'date'
+
+ def __init__(self, *args, **kwargs):
+ super(DelayedDateForm, self).__init__(*args, **kwargs)
+ self.fields[self.date_field].required = False
+
+
class TitledAdmin(EntityAdmin):
prepopulated_fields = {'slug': ('title',)}
list_display = ('title', 'slug')
class BlogEntryAdmin(TitledAdmin, AddTagAdmin):
+ form = DelayedDateForm
filter_horizontal = ['tags']
+ list_filter = ['author', 'blog']
+ date_hierarchy = 'date'
+ search_fields = ('content',)
+ list_display = ['title', 'date', 'author']
+ raw_id_fields = ('author',)
+ fieldsets = (
+ (None, {
+ 'fields': ('title', 'author', 'blog')
+ }),
+ ('Content', {
+ 'fields': ('content', 'excerpt', 'tags'),
+ }),
+ ('Advanced', {
+ 'fields': ('slug', 'date'),
+ 'classes': COLLAPSE_CLASSES
+ })
+ )
class BlogViewAdmin(EntityAdmin):
- pass
+ fieldsets = (
+ (None, {
+ 'fields': ('blog',)
+ }),
+ ('Pages', {
+ 'fields': ('index_page', 'entry_page', 'tag_page')
+ }),
+ ('Archive Pages', {
+ 'fields': ('entry_archive_page', 'tag_archive_page')
+ }),
+ ('Permalinks', {
+ 'fields': ('entry_permalink_style', 'entry_permalink_base', 'tag_permalink_base'),
+ 'classes': COLLAPSE_CLASSES
+ }),
+ ('Feeds', {
+ 'fields': ('feed_suffix', 'feeds_enabled'),
+ 'classes': COLLAPSE_CLASSES
+ })
+ )
+ raw_id_fields = ('index_page', 'entry_page', 'tag_page', 'entry_archive_page', 'tag_archive_page',)
class NewsletterAdmin(TitledAdmin):
class NewsletterArticleAdmin(TitledAdmin, AddTagAdmin):
- filter_horizontal = TitledAdmin.filter_horizontal + ('tags', 'authors')
- list_display = ['title', 'date', 'author_names']
- search_fields = ('title', 'authors__name',)
+ form = DelayedDateForm
+ filter_horizontal = ('tags', 'authors')
+ list_filter = ('newsletter',)
date_hierarchy = 'date'
+ search_fields = ('title', 'authors__name',)
+ list_display = ['title', 'date', 'author_names']
+ fieldsets = (
+ (None, {
+ 'fields': ('title', 'authors', 'newsletter')
+ }),
+ ('Content', {
+ 'fields': ('full_text', 'lede', 'tags')
+ }),
+ ('Advanced', {
+ 'fields': ('slug', 'date'),
+ 'classes': COLLAPSE_CLASSES
+ })
+ )
def author_names(self, obj):
return ', '.join([author.get_full_name() for author in obj.authors.all()])
class NewsletterViewAdmin(EntityAdmin):
- pass
+ fieldsets = (
+ (None, {
+ 'fields': ('newsletter',)
+ }),
+ ('Pages', {
+ 'fields': ('index_page', 'article_page', 'issue_page')
+ }),
+ ('Archive Pages', {
+ 'fields': ('article_archive_page', 'issue_archive_page')
+ }),
+ ('Permalinks', {
+ 'fields': ('article_permalink_style', 'article_permalink_base', 'issue_permalink_base'),
+ 'classes': COLLAPSE_CLASSES
+ }),
+ ('Feeds', {
+ 'fields': ('feed_suffix', 'feeds_enabled'),
+ 'classes': COLLAPSE_CLASSES
+ })
+ )
+ raw_id_fields = ('index_page', 'article_page', 'issue_page', 'article_archive_page', 'issue_archive_page',)
admin.site.register(Blog, BlogAdmin)
-from django.db import models
from django.conf import settings
-from philo.models import Tag, Titled, Entity, MultiView, Page, register_value_model, TemplateField
-from philo.exceptions import ViewCanNotProvideSubpath
from django.conf.urls.defaults import url, patterns, include
+from django.db import models
from django.http import Http404
-from datetime import date, datetime
-from philo.utils import paginate
-from philo.contrib.penfield.validators import validate_pagination_count
+from django.template import loader, Context
from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed
+from datetime import date, datetime
from philo.contrib.penfield.utils import FeedMultiViewMixin
+from philo.contrib.penfield.validators import validate_pagination_count
+from philo.exceptions import ViewCanNotProvideSubpath
+from philo.models import Tag, Titled, Entity, MultiView, Page, register_value_model, TemplateField
+from philo.utils import paginate
class Blog(Entity, Titled):
class BlogEntry(Entity, Titled):
blog = models.ForeignKey(Blog, related_name='entries', blank=True, null=True)
author = models.ForeignKey(getattr(settings, 'PHILO_PERSON_MODULE', 'auth.User'), related_name='blogentries')
- date = models.DateTimeField(default=datetime.now)
+ date = models.DateTimeField(default=None)
content = models.TextField()
excerpt = models.TextField(blank=True, null=True)
tags = models.ManyToManyField(Tag, related_name='blogentries', blank=True, null=True)
+ def save(self, *args, **kwargs):
+ if self.date is None:
+ self.date = datetime.now()
+ super(BlogEntry, self).save(*args, **kwargs)
+
class Meta:
ordering = ['-date']
verbose_name_plural = "blog entries"
return entries, context
def add_item(self, feed, obj, kwargs=None):
+ title = loader.get_template("penfield/feeds/blog_entry/title.html")
+ description = loader.get_template("penfield/feeds/blog_entry/description.html")
defaults = {
- 'title': obj.title,
- 'description': obj.content,
+ 'title': title.render(Context({'entry': obj})),
+ 'description': description.render(Context({'entry': obj})),
'author_name': obj.author.get_full_name(),
'pubdate': obj.date
}
class NewsletterArticle(Entity, Titled):
newsletter = models.ForeignKey(Newsletter, related_name='articles')
authors = models.ManyToManyField(getattr(settings, 'PHILO_PERSON_MODULE', 'auth.User'), related_name='newsletterarticles')
- date = models.DateTimeField(default=datetime.now)
+ date = models.DateTimeField(default=None)
lede = TemplateField(null=True, blank=True, verbose_name='Summary')
full_text = TemplateField(db_index=True)
tags = models.ManyToManyField(Tag, related_name='newsletterarticles', blank=True, null=True)
+ def save(self, *args, **kwargs):
+ if self.date is None:
+ self.date = datetime.now()
+ super(NewsletterArticle, self).save(*args, **kwargs)
+
class Meta:
get_latest_by = 'date'
ordering = ['-date']
return self.issue_archive_page.render_to_response(request, extra_context=context)
def add_item(self, feed, obj, kwargs=None):
+ title = loader.get_template("penfield/feeds/newsletter_article/title.html")
+ description = loader.get_template("penfield/feeds/newsletter_article/description.html")
defaults = {
- 'title': obj.title,
+ 'title': title.render(Context({'article': obj})),
'author_name': ', '.join([author.get_full_name() for author in obj.authors.all()]),
'pubdate': obj.date,
- 'description': obj.full_text,
+ 'description': description.render(Context({'article': obj})),
'categories': [tag.name for tag in obj.tags.all()]
}
defaults.update(kwargs or {})
--- /dev/null
+{{ entry.content }}
\ No newline at end of file
--- /dev/null
+{{ entry.title }}
\ No newline at end of file
--- /dev/null
+{{ article.full_text }}
\ No newline at end of file
--- /dev/null
+{{ article.title }}
\ No newline at end of file
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.core.exceptions import ObjectDoesNotExist
+from django.core.validators import RegexValidator
from django.utils import simplejson as json
from django.utils.encoding import smart_str
from philo.exceptions import AncestorDoesNotExist
class Meta:
app_label = 'philo'
+ ordering = ('name',)
class Titled(models.Model):
value_object_id = models.PositiveIntegerField(verbose_name='Value ID', null=True, blank=True)
value = generic.GenericForeignKey('value_content_type', 'value_object_id')
- key = models.CharField(max_length=255)
+ key = models.CharField(max_length=255, validators=[RegexValidator("\w+")], help_text="Must contain one or more alphanumeric characters or underscores.")
def __unicode__(self):
return u'"%s": %s' % (self.key, self.value)