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

5,918 views
5,165 views

Published on

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.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,918
On SlideShare
0
From Embeds
0
Number of Embeds
113
Actions
Shares
0
Downloads
72
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • A winning combination: Plone as CMS and your favorite Python web framework as front end

    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 <ul><li>Easy to use and install </li></ul><ul><li>Standards and accessibility compliant </li></ul><ul><li>Best security track record of any major CMS </li></ul><ul><li>Available in more than 40 languages </li></ul><ul><li>Workflow capabilities and rules engine </li></ul><ul><li>Versioning, history and reverting content </li></ul><ul><li>And, of course... </li></ul>
    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 <ul><li>But sometimes we forget that... </li></ul><ul><li>Or clients push us to add features “We want Plone, only take this out and add a couple of features” </li></ul><ul><li>Or we simply don't think we have an option </li></ul><ul><li>So, we end up with... </li></ul>
    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 <ul><li>Out of the Box support for Default Plone Content Types and all built-in Archetypes Fields. </li></ul><ul><li>Supports Any 3rd Party / Custom Archetypes Content. </li></ul><ul><li>Supports Capturing Containment / Content hierarchy in the serialized database. </li></ul><ul><li>Completely Automated Mirroring, zero configuration required beyond installation. </li></ul><ul><li>Support for Plone 2.5, 3.0, and 3.1 </li></ul>
    15. It's simple
    16. Now we can: <ul><li>Use Plone only to manage content </li></ul><ul><li>Use whatever framework we like to work with the content </li></ul><ul><li>Take Plone out of the deployment plans </li></ul><ul><li>Stop worrying about how to do something in terms of Plone and instead think about what we want to accomplish </li></ul><ul><li>Simplify, simplify </li></ul>
    17. And we can serve Plone content fast!
    18. How does it work? <ul><li>Integrates into Plone's event stream and subscribes to content lifecycle events (object added, edited, deleted). </li></ul><ul><li>Transform Plone content schemas into relational tables, using SQLAlchemy. </li></ul><ul><li>All objects get a default content schema, including files and relations. </li></ul><ul><li>Each Plone content type gets its own table. </li></ul>
    19.  
    20. Installation <ul><li>Download: http://code.google.com/p/contentmirror/downloads/list </li></ul><ul><li>Install </li></ul><ul><li>Configure database </li></ul><ul><li>Configure custom content types </li></ul><ul><li>Generate tables </li></ul><ul><li>Bulk load pre-existing content </li></ul>
    21. Configure the database with ZCML <configure xmlns=&quot;http://namespaces.zope.org/zope&quot; xmlns:db=&quot;http://namespaces.objectrealms.net/rdb&quot; xmlns:ore=&quot;http://namespaces.objectrealms.net/mirror&quot;> <!-- setup a database connection --> <db:engine url=&quot;postgres://localhost/plone&quot; name=&quot;mirror-db&quot; echo=&quot;True&quot;/> <!-- associate the database connection to mirror db structures --> <db:bind engine=&quot;mirror-db&quot; metadata=&quot;ore.contentmirror.schema.metadata&quot; /> </configure>
    22. Configure custom content types For each custom content type installed on the site: <ore:mirror content= &quot;Products.ATContentTypes.content.document.ATDocument&quot; />
    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? <ul><li>Sites with a small number of content managers and a large number of users. </li></ul><ul><li>Which can clearly separate content management and presentation. </li></ul><ul><ul><li>Magazines </li></ul></ul><ul><ul><li>Newspapers </li></ul></ul><ul><ul><li>Government </li></ul></ul><ul><ul><li>Non-profits </li></ul></ul>
    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=&quot;parent&quot;, editable=False)
    29. Anyone? <ul><li>Turbogears </li></ul><ul><li>Pylons </li></ul><ul><li>Werkzeug </li></ul><ul><li>Anything goes! </li></ul>
    30. Content Mirror is easily extended <ul><li>How about? </li></ul><ul><ul><li>Reporting against the content </li></ul></ul><ul><ul><li>Audits of changes </li></ul></ul><ul><ul><li>Export to formats like JSON </li></ul></ul><ul><ul><li>Other storage backends </li></ul></ul><ul><li>Content mirror Uses the Zope Component Architecture </li></ul><ul><li>We can easily plug in something other than a relational database </li></ul>
    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 <ul><li>Take advantage of Google's infrastructure </li></ul><ul><li>Use their user authentication facilities </li></ul><ul><li>Let them worry about scaling </li></ul><ul><li>Of course, kinds of sites are limited, due to GAE's strict quotas </li></ul><ul><li>More like a toy, but shows what can be possible using Content Mirror with Plone </li></ul>
    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

    ×