View
1
Download
0
Category
Preview:
Citation preview
Framework approach to building content management systems
Wednesday, February 20, 13
Andrew Kurinnyi@zen4ever
https://github.com/zen4ever
Wednesday, February 20, 13
Monolithic CMSs• Quick initial install
• Lots of features
• Plugins/extensions
• 3rd party themes
Wednesday, February 20, 13
That that starts sweetends bitter,
and that which starts bitterends sweet.
Johnny Quid, RocknRolla
Wednesday, February 20, 13
Monolithic CMSs cons
• Customization is hard
• Users use 20% of features, other 80% confuse them
• Plugin system might be insufficient for complex functionality
Wednesday, February 20, 13
Framework approach• Easy to customize,
since you built it• You get only features
your users need• Ability to integrate
complex functionalityWednesday, February 20, 13
FeinCMS• Hierarchical page
system• Content types• 3rd party apps
integrationWednesday, February 20, 13
Page module
Wednesday, February 20, 13
Page module from django.utils.translation import ugettext_lazy as _
from feincms.module.page.models import Page
Page.register_templates({ 'title': _('Standard template'), 'path': 'page.html', 'regions': ( ('main', _('Main content area')), ('sidebar', _('Sidebar'), 'inherited'), ), })
Page.register_templates({ 'title': _('Homepage template'), 'path': 'homepage.html', 'regions': ( ('main', _('Main content area')), ), })
Wednesday, February 20, 13
Content types from feincms.module.page.models import Pagefrom feincms.content.richtext.models import RichTextContentfrom feincms.content.video.models import VideoContentfrom feincms.content.raw.models import RawContent
from photologue_extra.models import PhotoContent, GalleryContent
Page.register_extensions( 'navigation', 'titles', 'translations', 'seo')
Page.create_content_type(RichTextContent, cleanse=False)Page.create_content_type(VideoContent)Page.create_content_type(PhotoContent)Page.create_content_type(GalleryContent, regions=('main',))Page.create_content_type(RawContent)
Wednesday, February 20, 13
Custom content type
class TextileContent(models.Model): content = models.TextField()
class Meta: abstract = True
def render(self, **kwargs): return textile(self.content)
Wednesday, February 20, 13
Custom modules
Wednesday, February 20, 13
Custom modulesfrom feincms.admin import item_editorfrom feincms.models import Basefrom feincms.content.richtext.models import RichTextContentfrom feincms.content.video.models import VideoContent
from photologue_extra.models import PhotoContent, GalleryContent
class Post(Base): ...
@classmethod def register_extension(cls, register_fn): register_fn(cls, PostAdmin)
class PostAdmin(item_editor.ItemEditor): ...
Post.register_regions( ('main', _('Main content area')),)
RichTextContent = Post.create_content_type(RichTextContent)VideoContent = Post.create_content_type(VideoContent)Post.create_content_type(PhotoContent)Post.create_content_type(GalleryContent, regions=('main',))
Wednesday, February 20, 13
Custom viewsTEMPLATE_CONTEXT_PROCESSORS = ( "django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.core.context_processors.tz", "django.contrib.messages.context_processors.messages",
"feincms.context_processors.add_page_if_missing",)
Wednesday, February 20, 13
Custom apps
from feincms.content.application.models import ApplicationContentfrom feincms.module.page.models import Page
Page.create_content_type(ApplicationContent, APPLICATIONS=( ('news.urls', 'News application'),))
Register using ApplicationContent
Wednesday, February 20, 13
Custom appsfrom django.shortcuts import get_object_or_404from news.models import Entry
def entry_list(request): # TODO add pagination here return 'news/entry_list.html', {'object_list': Entry.objects.all()}
def entry_detail(request, slug): return 'news/entry_detail', {'object': get_object_or_404(Entry, slug=slug)}
views.py
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('news.views', url(r'^$', 'entry_list', name='entry_list'), url(r'^(?P<slug>[^/]+)/$', 'entry_detail', name='entry_detail'),)
urls.py
Wednesday, February 20, 13
Custom appsIn your templates
{% extends feincms_page.template.path|default:"base.html" %}
{% block ... %}{# more content snipped #}
Reverse urls
from feincms.content.application.models import app_reverseapp_reverse('mymodel-detail', 'myapp.urls', args=...)
{% load applicationcontent_tags %}
{% app_reverse “mymodel_detail” “myapp.urls” arg1 arg2 as url %}
Wednesday, February 20, 13
Caching• Nginx microcaching*• Template fragment
caching• Johnny-cache*http://fennb.com/microcaching-speed-your-app-up-250x-with-no-n
Wednesday, February 20, 13
Johnny-cache fixfrom feincms.module.page.models import Page, PageAdmin
class PageAdminNew(PageAdmin): def _refresh_changelist_caches(self): from johnny.cache import invalidate invalidate(Page)
from django.contrib import admin
admin.site.unregister(Page)admin.site.register(Page, PageAdminNew)
Wednesday, February 20, 13
Want even better performance?
Run it on PyPy
Wednesday, February 20, 13
Migrating data from Wordpress
django-wpimport*
*https://github.com/zen4ever/django-wpimportWednesday, February 20, 13
Thanks!@zen4ever
https://github.com/zen4ever
Wednesday, February 20, 13
Recommended