A winning combination: Plone as CMS and your favorite Python web framework as front end

Embed Size (px)

DESCRIPTION

What if you could use Plone only as a CMS and program a frontend in whichever Python web framework you want, with transparent access to the content? This way you get a proven, high-reward, low-maintenance CMS as a content backend and are free to write your application on top of that using the power and flexibility of your favorite web framework.

Citation preview

  • 1. A Winning combination: Plone and your favorite web framework

2. Why? 3. Plone is the best CMS that is NOT written in PHP 4. Plone has lots of great features

  • Easy to use and install
  • Standards and accessibility compliant
  • Best security track record of any major CMS
  • Available in more than 40 languages
  • Workflow capabilities and rules engine
  • Versioning, history and reverting content
  • And, of course...

5. Python 6. but... 7. Plone is complex 8. Plone can be slow 9. Caching is not always the answer to traffic 10. Plone is NOT a general web development framework

  • But sometimes we forget that...
  • Or clients push us to add features We want Plone, only take this out and add a couple of features
  • Or we simply don't think we have an option
  • So, we end up with...

11. Frankenplone 12. It doesn't have to be like this. You can work with your favorite tools. 13. Content Mirror by Kapil Thangavelu 14. Content Mirror serializes Plone content into a relational database

  • Out of the Box support for Default Plone Content Types and all built-in Archetypes Fields.
  • Supports Any 3rd Party / Custom Archetypes Content.
  • Supports Capturing Containment / Content hierarchy in the serialized database.
  • Completely Automated Mirroring, zero configuration required beyond installation.
  • Support for Plone 2.5, 3.0, and 3.1

15. It's simple 16. Now we can:

  • Use Plone only to manage content
  • Use whatever framework we like to work with the content
  • Take Plone out of the deployment plans
  • Stop worrying about how to do something in terms of Plone and instead think about what we want to accomplish
  • Simplify, simplify

17. And we can serve Plone content fast! 18. How does it work?

  • Integrates into Plone's event stream and subscribes to content lifecycle events (object added, edited, deleted).
  • Transform Plone content schemas into relational tables, using SQLAlchemy.
  • All objects get a default content schema, including files and relations.
  • Each Plone content type gets its own table.

19. 20. Installation

  • Download:http://code.google.com/p/contentmirror/downloads/list
  • Install
  • Configure database
  • Configure custom content types
  • Generate tables
  • Bulk load pre-existing content

21. Configure the database with ZCML 22. Configure custom content types For each custom content type installed on the site: 23. Generate tables and upload content dropdb plone createdb plone --encoding=UTF-8 # generate table definitions and create tables bin/instance run parts/productdistros/ContentMirror/ddl.py postgres > mirror.sql psql plone < /home/andy/plone/zinstance/mirror.sql # optionally, load existing content bin/instance run parts/productdistros/ContentMirror/bulk.py Plone 24. That's it. We're ready to rock & roll 25. The changes are sent synchronously to the database plone# select content_id, id, title from content where id = 'front-page'; content_id |id|title ------------+------------+---------------- 8 | front-page | Content Mirror sent this (1 row) 26. What kind of sites can take advantage of this strategy?

  • Sites with a small number of content managers and a large number of users.
  • Which can clearly separate content management and presentation.
    • Magazines
    • Newspapers
    • Government
    • Non-profits

27. Repoze.BFG front end class WebSite(UserDict): implements(IWebSite,ILocation) __acl__ = [ (Allow, Everyone, 'view') ] def __init__(self, website_id): UserDict.__init__(self) self.__name__ = None self.__parent__ = None self.website_id = website_id session = Session() website =session.query( PloneContent ).with_polymorphic(PloneWebSite ).filter( PloneContent.id==website_id ).first() self.title = website.title 28. Plango, by Andy McKay from django.db import models from django.contrib.contenttypes.models import ContentType from utils import normalize_name class Content(models.Model): class Meta: db_table = u'content' content_id = models.IntegerField(primary_key=True, editable=False) id = models.CharField(max_length=256, editable=False) uid = models.CharField(unique=True, max_length=36, editable=False) portal_type = models.CharField(max_length=64, editable=False) status = models.CharField(max_length=64, editable=False, null=False) type = models.CharField(max_length=64, editable=False) container = models.ForeignKey('self', related_name="parent", editable=False) 29. Anyone?

  • Turbogears
  • Pylons
  • Werkzeug
  • Anything goes!

30. Content Mirror is easily extended

  • How about?
    • Reporting against the content
    • Audits of changes
    • Export to formats like JSON
    • Other storage backends
  • Content mirror Uses the Zope Component Architecture
  • We can easily plug in something other than a relational database

31. By the way, don't worry about the Component Architecture. We have studied the Zope CA so you don't have to. 32. A Google App Engine frontend

  • Take advantage of Google's infrastructure
  • Use their user authentication facilities
  • Let them worry about scaling
  • Of course, kinds of sites are limited, due to GAE's strict quotas
  • More like a toy, but shows what can be possible using Content Mirror with Plone

33. GAE front end application import os import wsgiref.handlers from google.appengine.ext import webapp from google.appengine.ext.webapp import template from google.appengine.ext import db from google.appengine.ext.db import polymodel from google.appengine.api import users class PloneContent(polymodel.PolyModel): id = db.StringProperty() uid = db.StringProperty() portal_type = db.StringProperty() status = db.StringProperty() type = db.StringProperty() 34. Plone content in GAE 35. All discussed front ends will be made available during the sprints. Keep an eye on: http://contentmirror.googlecode.com/ 36. Case study The Library of Congress in Chile 37. Create multiple sites in one instance 38. Select content from a shared store 39. Define a unique site layout and style 40. Deploy sites using repoze.bfg 41. Let Plone be a part of the Python universe 42. Thank you! Carlos de la Guardia email:[email_address] twitter: cguardia blog: http://blog.delaguardia.com.mx