Added base blog app
This commit is contained in:
parent
8ad0e87c18
commit
9e404aeb9b
|
@ -20,3 +20,6 @@ psycopg2==2.5.2
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
django-filer==0.9.5
|
django-filer==0.9.5
|
||||||
|
|
||||||
|
# Blog
|
||||||
|
django-ckeditor-updated==4.4.0
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
from .models import Entry, Tag
|
||||||
|
from django import forms
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django import forms
|
||||||
|
from django.db import models
|
||||||
|
from ckeditor.widgets import CKEditorWidget
|
||||||
|
import reversion
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# ENTRY
|
||||||
|
#
|
||||||
|
class EntryAdmin(reversion.VersionAdmin):
|
||||||
|
list_display = ('title', 'date', 'status', 'tag_list', 'preview_link')
|
||||||
|
list_display_links = ('title', )
|
||||||
|
|
||||||
|
list_filter = ('date', 'draft', )
|
||||||
|
search_fields = ('title', 'content', )
|
||||||
|
|
||||||
|
prepopulated_fields = {"slug": ("title",)}
|
||||||
|
|
||||||
|
suit_form_tabs = (
|
||||||
|
('general', _('General')),
|
||||||
|
('content', _('Content')),
|
||||||
|
)
|
||||||
|
|
||||||
|
fieldsets = [
|
||||||
|
(None, {
|
||||||
|
'classes': ('suit-tab suit-tab-general',),
|
||||||
|
'fields': ('title', 'slug', 'draft', 'date', 'tags', )
|
||||||
|
}),
|
||||||
|
(None, {
|
||||||
|
'classes': ('suit-tab suit-tab-content full-width',),
|
||||||
|
'fields': ('content', )
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
|
||||||
|
def preview_link(self, obj):
|
||||||
|
return '<a href="%s">View »</a>' % (
|
||||||
|
obj.get_absolute_url()
|
||||||
|
)
|
||||||
|
preview_link.allow_tags = True
|
||||||
|
|
||||||
|
def tag_list(self, obj):
|
||||||
|
return ", ".join([x.name for x in obj.tags.all()])
|
||||||
|
|
||||||
|
def save_model(self, request, obj, form, change):
|
||||||
|
if not change:
|
||||||
|
obj.author = request.user
|
||||||
|
super(self.__class__, self).save_model(request, obj, form, change)
|
||||||
|
|
||||||
|
class Media:
|
||||||
|
#css = {
|
||||||
|
# "all": ("ckeditor/redactor.css",)
|
||||||
|
#}
|
||||||
|
# js = (
|
||||||
|
# "ckeditor/ckeditor.js",
|
||||||
|
# "js/wysiwyg.js",
|
||||||
|
# )
|
||||||
|
pass
|
||||||
|
|
||||||
|
admin.site.register(Entry, EntryAdmin)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# TAG
|
||||||
|
#
|
||||||
|
class TagAdmin(reversion.VersionAdmin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
admin.site.register(Tag, TagAdmin)
|
|
@ -0,0 +1,108 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from south.utils import datetime_utils as datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Adding model 'Entry'
|
||||||
|
db.create_table(u'blog_entry', (
|
||||||
|
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||||
|
('title', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||||
|
('date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(2014, 9, 4, 0, 0))),
|
||||||
|
('content', self.gf('ckeditor.fields.RichTextField')()),
|
||||||
|
('slug', self.gf('django.db.models.fields.SlugField')(max_length=128)),
|
||||||
|
('draft', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||||
|
('author', self.gf('django.db.models.fields.related.ForeignKey')(related_name='author', to=orm['auth.User'])),
|
||||||
|
))
|
||||||
|
db.send_create_signal('blog', ['Entry'])
|
||||||
|
|
||||||
|
# Adding M2M table for field tags on 'Entry'
|
||||||
|
m2m_table_name = db.shorten_name(u'blog_entry_tags')
|
||||||
|
db.create_table(m2m_table_name, (
|
||||||
|
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||||
|
('entry', models.ForeignKey(orm['blog.entry'], null=False)),
|
||||||
|
('tag', models.ForeignKey(orm['blog.tag'], null=False))
|
||||||
|
))
|
||||||
|
db.create_unique(m2m_table_name, ['entry_id', 'tag_id'])
|
||||||
|
|
||||||
|
# Adding model 'Tag'
|
||||||
|
db.create_table(u'blog_tag', (
|
||||||
|
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||||
|
('name', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||||
|
('color', self.gf('django.db.models.fields.CharField')(max_length=6, blank=True)),
|
||||||
|
))
|
||||||
|
db.send_create_signal('blog', ['Tag'])
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Deleting model 'Entry'
|
||||||
|
db.delete_table(u'blog_entry')
|
||||||
|
|
||||||
|
# Removing M2M table for field tags on 'Entry'
|
||||||
|
db.delete_table(db.shorten_name(u'blog_entry_tags'))
|
||||||
|
|
||||||
|
# Deleting model 'Tag'
|
||||||
|
db.delete_table(u'blog_tag')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
u'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
u'auth.permission': {
|
||||||
|
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
u'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'blog.entry': {
|
||||||
|
'Meta': {'ordering': "['-date']", 'object_name': 'Entry'},
|
||||||
|
'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'author'", 'to': u"orm['auth.User']"}),
|
||||||
|
'content': ('ckeditor.fields.RichTextField', [], {}),
|
||||||
|
'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 9, 4, 0, 0)'}),
|
||||||
|
'draft': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '128'}),
|
||||||
|
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['blog.Tag']", 'null': 'True', 'blank': 'True'}),
|
||||||
|
'title': ('django.db.models.fields.CharField', [], {'max_length': '128'})
|
||||||
|
},
|
||||||
|
'blog.tag': {
|
||||||
|
'Meta': {'ordering': "['name']", 'object_name': 'Tag'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'max_length': '6', 'blank': 'True'}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
|
||||||
|
},
|
||||||
|
u'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['blog']
|
|
@ -0,0 +1,71 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.conf import settings
|
||||||
|
from datetime import datetime
|
||||||
|
from django.utils.timezone import utc
|
||||||
|
from ckeditor.fields import RichTextField
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.utils.translation import activate
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# ENTRY
|
||||||
|
#
|
||||||
|
class Entry(models.Model):
|
||||||
|
title = models.CharField(max_length=128)
|
||||||
|
date = models.DateTimeField(default=datetime.now(tz=utc))
|
||||||
|
content = RichTextField()
|
||||||
|
slug = models.SlugField(max_length=128)
|
||||||
|
draft = models.BooleanField(default=True)
|
||||||
|
author = models.ForeignKey(
|
||||||
|
settings.AUTH_USER_MODEL,
|
||||||
|
editable=False,
|
||||||
|
related_name='author'
|
||||||
|
)
|
||||||
|
tags = models.ManyToManyField('Tag', null=True, blank=True)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.title
|
||||||
|
|
||||||
|
def status(self):
|
||||||
|
status = 'Published'
|
||||||
|
|
||||||
|
if self.date > datetime.now(tz=utc):
|
||||||
|
status = 'Scheduled'
|
||||||
|
|
||||||
|
if self.draft:
|
||||||
|
status = 'Draft'
|
||||||
|
|
||||||
|
return status
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
kwargs = {
|
||||||
|
'year': self.date.year,
|
||||||
|
'month': self.date.strftime("%m"),
|
||||||
|
'day': self.date.strftime("%d"),
|
||||||
|
'slug': self.slug
|
||||||
|
}
|
||||||
|
url = reverse('blog:item', kwargs=kwargs)
|
||||||
|
|
||||||
|
return url
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = 'blog'
|
||||||
|
ordering = ['-date']
|
||||||
|
verbose_name_plural = 'Entries'
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# TAG
|
||||||
|
#
|
||||||
|
class Tag(models.Model):
|
||||||
|
name = models.CharField(max_length=128)
|
||||||
|
color = models.CharField(max_length=6, blank=True)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = 'blog'
|
||||||
|
ordering = ['name']
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.contrib.sitemaps import Sitemap
|
||||||
|
|
||||||
|
from .models import Entry
|
||||||
|
|
||||||
|
|
||||||
|
class BlogSitemap(Sitemap):
|
||||||
|
changefreq = "monthly"
|
||||||
|
priority = 0.5
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
return Entry.objects.filter(draft=False, date__lte=datetime.now())
|
||||||
|
|
||||||
|
def lastmod(self, obj):
|
||||||
|
return obj.date
|
|
@ -0,0 +1,10 @@
|
||||||
|
from django_jinja import library
|
||||||
|
|
||||||
|
from fmartingrcom.apps.config.models import SiteConfiguration
|
||||||
|
|
||||||
|
|
||||||
|
@library.filter
|
||||||
|
def readmore(content):
|
||||||
|
config = SiteConfiguration.objects.get()
|
||||||
|
summary, rest = content.split(config.readmore_tag, 1)
|
||||||
|
return summary
|
|
@ -0,0 +1,18 @@
|
||||||
|
from pytz import timezone
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.utils.encoding import smart_unicode
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
from django_jinja import library
|
||||||
|
|
||||||
|
|
||||||
|
@library.filter
|
||||||
|
def dt(t, fmt=None):
|
||||||
|
"""
|
||||||
|
Call ``datetime.strftime`` with the given format string.
|
||||||
|
"""
|
||||||
|
tz = timezone(settings.TIME_ZONE)
|
||||||
|
if fmt is None:
|
||||||
|
fmt = _('%B %e, %Y')
|
||||||
|
return smart_unicode(tz.normalize(t).strftime(fmt)) if t else u''
|
|
@ -0,0 +1,38 @@
|
||||||
|
from django.conf.urls import patterns, url
|
||||||
|
|
||||||
|
from .views import ListView, EntryView, SearchView, RSSView
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = patterns(
|
||||||
|
None,
|
||||||
|
# Post list with page
|
||||||
|
url(
|
||||||
|
r'^page/(?P<page_number>\d+)/$',
|
||||||
|
ListView.as_view(),
|
||||||
|
name='list'
|
||||||
|
),
|
||||||
|
# Post list
|
||||||
|
url(
|
||||||
|
r'^$',
|
||||||
|
ListView.as_view(),
|
||||||
|
name='list'
|
||||||
|
),
|
||||||
|
# Single entry
|
||||||
|
url(
|
||||||
|
r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[\w\-]+)/$',
|
||||||
|
EntryView.as_view(),
|
||||||
|
name='item'
|
||||||
|
),
|
||||||
|
# RSS
|
||||||
|
url(
|
||||||
|
r'^rss\.xml$',
|
||||||
|
RSSView.as_view(),
|
||||||
|
name='rss'
|
||||||
|
),
|
||||||
|
# Search
|
||||||
|
url(
|
||||||
|
r'^search/$',
|
||||||
|
SearchView.as_view(),
|
||||||
|
name='search',
|
||||||
|
)
|
||||||
|
)
|
|
@ -0,0 +1,55 @@
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.core.paginator import Paginator
|
||||||
|
from django.utils import translation
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.paginator import Paginator
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from .models import Entry
|
||||||
|
|
||||||
|
|
||||||
|
class Config(object):
|
||||||
|
entries_per_page = 10
|
||||||
|
|
||||||
|
config = Config()
|
||||||
|
|
||||||
|
|
||||||
|
def get_posts(query=None, limit=None):
|
||||||
|
items = Entry.objects.filter(
|
||||||
|
draft=False,
|
||||||
|
date__lt=datetime.now()
|
||||||
|
)
|
||||||
|
if query and len(query) > 0:
|
||||||
|
items = items.filter(
|
||||||
|
Q(title__icontains=query) | \
|
||||||
|
Q(content__icontains=query) | \
|
||||||
|
Q(tags__name__iexact=query)
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
items = items.order_by('-date')
|
||||||
|
|
||||||
|
if limit:
|
||||||
|
items = items[:limit]
|
||||||
|
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
def get_paginator(request, page_number=1, item=None, **kwargs):
|
||||||
|
item_index = None
|
||||||
|
page = None
|
||||||
|
items = get_posts(query=kwargs.get('query', None))
|
||||||
|
entries_per_page = config.entries_per_page
|
||||||
|
paginator = Paginator(items, entries_per_page)
|
||||||
|
if item:
|
||||||
|
for index, obj in enumerate(items):
|
||||||
|
if obj == item:
|
||||||
|
item_index = index
|
||||||
|
break
|
||||||
|
if item_index:
|
||||||
|
page_number = (item_index / entries_per_page) + 1
|
||||||
|
|
||||||
|
if page_number:
|
||||||
|
page = paginator.page(page_number)
|
||||||
|
|
||||||
|
return paginator, page
|
|
@ -0,0 +1,103 @@
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.shortcuts import render_to_response
|
||||||
|
from django.template import RequestContext
|
||||||
|
from django.http import Http404, HttpResponseRedirect
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
from shelfzilla.views import View
|
||||||
|
import utils as blog_utils
|
||||||
|
from .models import Entry
|
||||||
|
|
||||||
|
|
||||||
|
class ListView(View):
|
||||||
|
section = 'blog'
|
||||||
|
template = 'blog/list.html'
|
||||||
|
|
||||||
|
def get(self, request, page_number=1):
|
||||||
|
if 'page' in request.GET:
|
||||||
|
page_number = int(request.GET['page'])
|
||||||
|
|
||||||
|
paginator, page = blog_utils.get_paginator(request, page_number)
|
||||||
|
|
||||||
|
context = {}
|
||||||
|
|
||||||
|
context['page'] = page
|
||||||
|
context['page_number'] = page_number
|
||||||
|
context['paginator'] = paginator
|
||||||
|
|
||||||
|
context = RequestContext(request, context)
|
||||||
|
return render_to_response(self.template, context_instance=context)
|
||||||
|
|
||||||
|
|
||||||
|
class EntryView(View):
|
||||||
|
section = 'blog'
|
||||||
|
template = 'blog/entry.jinja'
|
||||||
|
|
||||||
|
def get(self, request, year, month, day, slug):
|
||||||
|
try:
|
||||||
|
filters = {
|
||||||
|
'slug': slug,
|
||||||
|
'date__year': int(year),
|
||||||
|
'date__month': int(month),
|
||||||
|
'date__day': int(day),
|
||||||
|
}
|
||||||
|
|
||||||
|
item = Entry.objects.get(**filters)
|
||||||
|
except Entry.DoesNotExist:
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
paginator, page = blog_utils.get_paginator(request, item=item)
|
||||||
|
|
||||||
|
context = {}
|
||||||
|
context['page'] = page
|
||||||
|
context['paginator'] = paginator
|
||||||
|
context['item'] = item
|
||||||
|
|
||||||
|
context = RequestContext(request, context)
|
||||||
|
return render_to_response(self.template, context_instance=context)
|
||||||
|
|
||||||
|
|
||||||
|
class SearchView(ListView):
|
||||||
|
template = 'blog/search.jinja'
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
page_number = 1
|
||||||
|
if 'page' in request.GET:
|
||||||
|
page_number = int(request.GET['page'])
|
||||||
|
|
||||||
|
search_query = request.POST['query']
|
||||||
|
|
||||||
|
if not search_query:
|
||||||
|
return HttpResponseRedirect(reverse('blog:list'))
|
||||||
|
|
||||||
|
paginator, page = blog_utils.get_paginator(
|
||||||
|
request, page_number, query=search_query
|
||||||
|
)
|
||||||
|
|
||||||
|
context = {}
|
||||||
|
context['page'] = page
|
||||||
|
context['page_number'] = page_number
|
||||||
|
context['paginator'] = paginator
|
||||||
|
context['search_query'] = search_query
|
||||||
|
|
||||||
|
context = RequestContext(request, context)
|
||||||
|
return render_to_response(self.template, context_instance=context)
|
||||||
|
|
||||||
|
|
||||||
|
class RSSView(View):
|
||||||
|
template = 'blog/rss.jinja'
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
limit = 20
|
||||||
|
items = blog_utils.get_posts(limit=limit)
|
||||||
|
context = {}
|
||||||
|
context['items'] = items
|
||||||
|
|
||||||
|
context = RequestContext(request, context)
|
||||||
|
return render_to_response(
|
||||||
|
'blog/rss.jinja',
|
||||||
|
context_instance=context,
|
||||||
|
mimetype='text/xml'
|
||||||
|
)
|
|
@ -58,6 +58,7 @@ INSTALLED_APPS = (
|
||||||
|
|
||||||
# Staticfiles
|
# Staticfiles
|
||||||
"compressor",
|
"compressor",
|
||||||
|
'ckeditor',
|
||||||
|
|
||||||
# Apps
|
# Apps
|
||||||
'shelfzilla.apps._admin',
|
'shelfzilla.apps._admin',
|
||||||
|
@ -66,6 +67,7 @@ INSTALLED_APPS = (
|
||||||
'shelfzilla.apps.homepage',
|
'shelfzilla.apps.homepage',
|
||||||
'shelfzilla.apps.landing',
|
'shelfzilla.apps.landing',
|
||||||
'shelfzilla.apps.manga',
|
'shelfzilla.apps.manga',
|
||||||
|
'shelfzilla.apps.blog',
|
||||||
'shelfzilla.apps.pjax',
|
'shelfzilla.apps.pjax',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -261,6 +263,11 @@ SUIT_CONFIG = {
|
||||||
'label': 'Settings',
|
'label': 'Settings',
|
||||||
'icon': 'icon-cog',
|
'icon': 'icon-cog',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'app': 'blog',
|
||||||
|
'label': 'Blog',
|
||||||
|
'icon': 'icon-book',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'app': 'manga',
|
'app': 'manga',
|
||||||
'label': 'Manga',
|
'label': 'Manga',
|
||||||
|
@ -273,3 +280,15 @@ SUIT_CONFIG = {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# CKEDITOR
|
||||||
|
#
|
||||||
|
CKEDITOR_UPLOAD_PATH = 'ckeditor/'
|
||||||
|
|
||||||
|
CKEDITOR_CONFIGS = {
|
||||||
|
'default': {
|
||||||
|
'toolbar': 'Standard',
|
||||||
|
'width': '100%',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
{% extends "_layout.html" %}
|
||||||
|
|
||||||
|
{% block page_title %}{{ block.super }} | Blog{% endblock %}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{% extends "blog/_layout.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block main_content %}
|
||||||
|
<div class="container">
|
||||||
|
<ul class="media-list">
|
||||||
|
{% for item in page.object_list %}
|
||||||
|
<li class="media well {% if item.draft %}draft{% endif %}">
|
||||||
|
<a class="pull-left" href="#">
|
||||||
|
<!--<img class="media-object img-rounded" src="{{ item.author.avatar }}">-->
|
||||||
|
</a>
|
||||||
|
<div class="media-body">
|
||||||
|
<h2 class="media-heading">{{ item.title }}</h2>
|
||||||
|
<div>
|
||||||
|
Por <strong>{{ item.author.first_name }}</strong> el
|
||||||
|
<time datetime="{{ item.date }}" pubdate="" data-updated="true">{{ item.date }}</time>
|
||||||
|
</div>
|
||||||
|
<p>{{ item.content|safe }}</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -9,10 +9,12 @@ admin.autodiscover()
|
||||||
|
|
||||||
urlpatterns = patterns(
|
urlpatterns = patterns(
|
||||||
'',
|
'',
|
||||||
|
url(r'^ckeditor/', include('ckeditor.urls')),
|
||||||
url(r'^messages/$', MessagesView.as_view(), name="contrib.messages"),
|
url(r'^messages/$', MessagesView.as_view(), name="contrib.messages"),
|
||||||
url(r'^$', include('shelfzilla.apps.homepage.urls')),
|
url(r'^$', include('shelfzilla.apps.homepage.urls')),
|
||||||
url(r'^', include('shelfzilla.apps.landing.urls')),
|
url(r'^', include('shelfzilla.apps.landing.urls')),
|
||||||
url(r'^', include('shelfzilla.apps.users.urls')),
|
url(r'^', include('shelfzilla.apps.users.urls')),
|
||||||
|
url(r'^blog/', include('shelfzilla.apps.blog.urls', namespace='blog')),
|
||||||
url(r'^series/', include('shelfzilla.apps.manga.urls.series')),
|
url(r'^series/', include('shelfzilla.apps.manga.urls.series')),
|
||||||
url(r'^volumes/', include('shelfzilla.apps.manga.urls.volumes')),
|
url(r'^volumes/', include('shelfzilla.apps.manga.urls.volumes')),
|
||||||
url(r'^publishers/', include('shelfzilla.apps.manga.urls.publishers')),
|
url(r'^publishers/', include('shelfzilla.apps.manga.urls.publishers')),
|
||||||
|
|
Reference in New Issue