In a recent posting I outlined my plans for the next generation of the "Produce & Publish Cloud Edition".
Over the last days I found some time prototyping the new core implementation which is basically responsible for storing editoral content and published content. A major requirement for the storage implementation is that it should be "cloud-aware". Fortunately there is a very nice Python project called pyfilesystem. pyfilesystem provides a filesystem-ish layer on top of various filesystems and cloud-ish services like
- Dropbox
- Amazon S3
- Local filesystem
- Remote filesystem access through SFTP
The benefit is obvious: you write your code once and it will run (in theory) out-of-the-box either on the local filesystem or against a remote filesystem.
And in fact: my code that I wrote and tested originally only against the local filesystem worked basically out-of-the-box with Amazon S3 and over SFTP. Support for Dropbox over dropbox-fs has been added yesterday. This took longer than expected because Dropbox provides only access through OAuth. So I had to automate the complete OAuth request/acknowledge game that usually happens manually using some lines of mechanize in Python. So Dropbox supports works in general however the underlaying dropbox-fs or the Dropbox Python SDK seems to be a bit flaky - but the errors are reproducable - so there is hope that the issues can be fixed easily.
Produce & Publish now got a solid filesystem storage basis (instead of Plone-only). This will make the further progress so much easier and more straight-forward than depending on the Plone-API and Plone annoyances only.
We are currently planning a complete new architecture for Produce & Publish in order to bring web-based publishing another step forward.
Please read our position paper on Produce & Publish Cloud Edition
Lately I worked on the relaunch of my company website zopyx.de. The site is based on Plone 4.2 and uses Twitter Bootstrap for the public website. Using Bootstrap made the site out of the box responsive. But having a responsive site can mean all and nothing. Bootstrap tries to reach responsiveness basically by using CSS3 media queries (and partly Javascript). The default result using Bootstrap was nice but far away been perfect or ready for production.
Issues I had with Bootstrap:
- The site uses IFRAMES for embedding YouTube videos and Slideshare presentations. In general it is necessary to specify a fixed width or height for the IFRAME. This is not much acceptable for a responsive a design. Using some Javascript code it was possible to adjust the width and height of the IFRAME upon orientation changes or resizing of the browser window in relation to the width the outer container.
- At the bottom of the zopyx.de front-page there is an image section with reference customer logos. The number of images to be displayed depends on the width of the browser windows (for desktop browser I am using six images, iPad in landscape mode shows up with five images and iPad in portrait mode displays 4 images). By default Bootstrap on iPad moved two references logos into a second row because six images did not fit into one row...working but ugly....as a workaround I added some media queries just hiding the 5th or 6th logo depending on the width of the browser window.
- For iPhone I made the decision to disable parts of the front-page e.g. the large image slider and the customer references do not show up (display: none). However the images are still being loaded although not loaded...nasty and a waste of bandwidth.
- Image sizes - different devices require different image sizes/resolutions. This is a limitation of HTML. Although there are some Javascript approaches available as workaround or some people are using CSS tricks....this is all tinkering. There is perhaps relief available in the future since the W3C is discussing a proposal (I think it is called "image sets") in order to specify different URLs representing one image when using a particular screen width or so.
- Loading of resources: on a mobile device you are perhaps using a stripped down version of the original site (e.g. without sliders as stated above). In such a case I don't need to include related resources like Javascript/CSS for the slider for iPhone or iPad. Right now it is hard bring this in line with media queries. Using media queries I can decide what to display or not but the decision to include a particular Javascript or CSS for rendering can only be done on the server.
Although I am pretty happy with the result so far I am convinced that the current programming model for responsive sites is partly broken.
Decisions when to render what and how is scattered among different places
- CSS (with media queries)
- client-side Javascript code
- backend code
I am currently working on the relaunch of my Produce & Publish product site. I decided to go with Pyramid (instead of Plone) this time since different functionality has to be integrated under one hood. The core application is based on a twitter/bootstrap theme (nothing special so far). I wrote already a bunch of documentation using Sphinx (result hosted on docs.produce-and-publish.com). Now the Sphinx site/content should be integrated into the Pyramid application. One option would be using a dedicated twitter/bootstrap theme for Sphinx or using Diazo. I decided against both options. A twitter/bootstrap theme for Sphinx is doable but requires double work (keeping the twitter/bootstrap theme in Sphinx and Pyramid in sync). Using Diazo also was not much appealing...yet another moving part.
The solution I come up with is the following:
- Sphinx supports the export/generation of the content as JSON (JSON builder aka "make json").
- The generated JSON documents can be used easily inside my Pyramid application through a tiny traverser dealing with paths and extensions
- The traverser code can be found here: https://github.com/zopyx/zopyx.pyramid.ppdemo/blob/master/ppdemo/views.py
Now traversing to /documentation/index will cause Pyramid to traverse into a specific part of the filesystem holding the documentation JSON-ified by Sphinx, picking up the JSON data and rendering it using a tiny template (see https://github.com/zopyx/zopyx.pyramid.ppdemo/blob/master/ppdemo/templates/sphinx.pt).
Disclaimer: the code is a proof of concept and more a hack than a final solution...but it works nicely so far...all image are being display and all links are fully working
For a long time there was a test() method available in ZPT:
<td tal:attributes="class python: test(some_condition, 'even', 'odd')">
With the move to browser views the test() had gone and you had to write something like
<td tal:attributes="class python: some_condition and 'even' or 'odd')">
as a replacement. This notation may have side-effects in some rare cases.
Now with Python 2.6 or higher you can rewrite your code the following way
<td tal:attributes="class python: 'even' if some_condition else 'odd')">
in a more clean way. In addition this notation is free of side-effects.
We had some internal discussions about using LessCSS in upcoming Plone projects for simplifying work (more compact CSS code, less redundant information etc.) so I played with LessCSS a bit today. The basic problem I cam e across was the issue how to integrate LessCSS with Plone from the web designers prospective. The typical working pattern of a Plone web designer is the following:
- start your instance in debug mode
- edit the styles files (.css) on the file-system
- save style files
- reload site in browser
Working with LessCSS is slightly different:
- you need to edit a .less file
- you need to compile the .less file manually using the lessc compiler
So basically one manual step more than necessary.
Here is a quick solution for the problem:
Based on the watchdog module for Python I wrote a small observer module that can be included with your package easily (from the __init__.py file of your package). The code below will start the observer only if your Zope/Plone instance is running in foreground.
Example:
from App.config import getConfiguration
zconfig = getConfiguration()
if zconfig.debug_mode:
import lesscss
lesscss.start()
After restarting your instance a dedicated observer thread will watch for file system changes inside the current policy or theme package. The event handler listens only to files matching *.less. For modification and creation event the handler will automatically call the LessCSS compiler and generate a corresponding .css file inside the same directory.
Cavecats: you need to add the watchdog egg manually to your buildout configuration
Produce & Publish News/Plone Konferenz wrap-up
Some notes on the 1. German Plone Conference in Munich and recent developments in Produce & Publish
The first German Plone Conference is finally over. It was a great conference with about 170 attendees - both Plone developers, Plone users and interested people. Especially a lot of new people from the Plone users side made this conference an interesting event - lots of interesting people and interesting conversations.
I gave a talk on the state of producing, publishing and distribution of electronic contents using our Produce & Publish plattform (slides, German only).
By accident an attendee point me to a PDF converter with similar capabilities to our current converter PrinceXML used for professional high-quality PDF documents. The new converter is PDFreactor and is in many ways comparable to PrinceXML. It also accepts HTML/XML for the content part and supports the styling of output PDF document through CSS. In fact PDFreactor provides a similar output compared to PrinceXML when using the unmodified stylesheets of Produce & Publish by default.
Some remarkable differences (and advantages over PrinceXML) are
- support for tagged PDFs (PDF/a)
- support for images in CMYK colorspace
- generates PDF forms
- PDF signing and encryption
- support for generating barcodes and QR codes
- slightly cheaper than PrinceXML
Downsides of PDFreactor
- slower (based on Java) but supports a webservice API to avoid startup times [Update: PDFreactor is usually run as a server process and access through a webservice API)
- significant higher memory fingerprint
- no floating of images or tables [Update: floating is possible]
- font-configuration not possible through CSS (fonts must be configured as part of the PDFreactor configuration) [Update: PDFreactor version 6 now supports arbitrary webfonts]
What are the benefits for the Produce & Publish plattform?
- another high-quality PDF converter option
- more scenarios where Produce & Publish might ba good choice
- optional PDF generation of accessible PDF documents when needed
- (optional) support of PDFreactor on the Produce & Publish server side (through the newest zopyx.convert2 module with support for PDFreactor)
- (optional) support of PDFreactor through the Produce & Publish Plone client connector (converter=pdf-pdfreactor parameter)
- no direct support for PDFreactor for generating PDF from within the Produce & Publish Authoring Environment (hard-coded PDF converter name - likely to be lifted soon)
Booktype vs. Produce & Publish
A short review of Booktype and a comparison with my own Produce & Publish product.
Last week a new product Booktype appeared in public. Booktype is an open-source authoring solution for creating PDF files and EBooks through the web. Booktype is completely implemented in Python (it is uses Django). It follows the paradigm Single-Source Multi-Channel Publishing which basically means: one content-source for all kind of publications and output formats. As author of the Produce & Publish solution I became curious and did some testing.
The first visual difference to Produce & Publish is that the UI is completely task-oriented. The primary task is: I want to write a book.

Produce & Publish itself supports the same functionality but the approach is a bit more generic and basically offers only the standard Plone user interface to content authors. Produce & Publish provides infinite nesting of chapters, sections etc. while Booktype provides only chapters and sections.
Editing content in Booktype basically works the same way as in Plone. Booktype uses TinyMCE as primary content editor. The editor opens inline (similar to former Plone versions using KSS for inline editing). Honestly I love the inline editing in Booktype feature (as I loved it in Plone 3) - it gives me a better user experience.

In order to generate an Ebook or a PDF file Booktype provides some simple wizards where you can choose from some pre-defined options like fonts, font sizes etc.

The conversion request seems to end up in queue. After the conversion Booktype will present you an URL where you can download the generated output format.
So far, so good. Booktype is very easy to use. The perfect solutions for average editors since the user interface gives you only the options that you need to get your task (writing a book) done. Produce & Publish in comparison exposes many more advanced options to the average editor. So the complexity of Produce & Publish might be overwhelming for this editor type.
Comparison of features: the feature list of Produce & Publish is more complete compared to Booktype. Produce & Publish provides powerful support for features like cross-references, listings for indexes, tables and images, sophisticated handling of images and their resolution. Apart from that each content project in Produce & Publish can be configured with individual stylesheets, assets and templates. Its overall architecture appears more open and pluggable (perhaps as a result of using features of the Zope Component Architecture where needed).
Comparison of output results: at the time of writing I have no idea how content is converted to PDF or to EPUB. The open-source code base does not contain any references to external converters. I assume Booktype provides conversion as a hosted service. A tests reveal that the creator of the PDF files is "ghostscript" but there is no indication what is used for generating the input for "ghostscript". The overall PDF quality is average. Produce & Publish provides high-quality hyphenation support (similar to TeX or LaTeX) - nothing that I could detect in Booktype. Produce & Publish also support features like multi-column rendering of content in PDF, image floats etc.
Overall conclusion: Booktype is great tool for average content editors that need to write a book without having the need to deal with stylesheet or complex configurations. It provides a limited functionality and a great user interface for getting the job done. However Produce & Publish is the better solution (feature-wise and quality-wise).
Produce & Publish print production appeared from Amazon
Latin learning material produced using Produce & Publish is now available from Amazon
We are happy to announce that the first five production implemented using our Produce & Publish plattform are now available on Amazon.
The Plone-based Produce & Publish plattform is used to produce high-quality learning materials for the Latein education in German schools.
The project Lektürewerkstatt maintains the complete content inside Plone and generates a PDF from the content that is directly used for the print process without further post-processing.
References:
- www.produce-and-publish.com
- www.zopyx.com
- Case study: "Einsatz von Produce & Publish am Albrecht-Ernst Gymnasium"
ZOPYX Limited
Andreas Jung
Charlottenstr. 37/1
D-72070 Tübingen
Tel. +49-7071-793376
www.zopyx.de
Implementing content-types for Plone site is one part of every typical Plone project. Styling & testing is another one. Both testers and designer need content for testing.
As part of a new project I decided to provide example content for each new content-type. The two core components are the loremipsum module for Python and the lorempixel.com web-service. The Python module can be used to generate single sentences of text or multiple paragraphs of text. The web-service provided random images in arbitrary sizes for you.
Here is a picture of a sample glossary
and one of a simple picture database:
Here is some example code for generating content and random image from using the mentioned services:
def gen_paragraphs(num=3):
return u'/'.join([p[2] for p in loremipsum.Generator().generate_paragraphs(num)])
def gen_sentence():
return loremipsum.Generator().generate_sentence()[-1]
def gen_sentences(length=80):
return u'/'.join([s[2] for s in loremipsum.Generator().generate_sentences(length)])
def random_image(width, height):
url = 'http://lorempixel.com/%d/%d/' % (width, height)
return urllib2.urlopen(url).read()
The code for generating a gallery as seen above looks like this:
def installAssets(self, site):
service = site.restrictedTraverse('deutschland/de/service')
assets = invokeFactory(service, 'Folder', 'Assets')
for width,height in ((200,200), (400,400), (600, 400), (800, 600),
(800,800), (1024, 768))
imagefolder_id = '%sx%s' % (width, height)
images = invokeFactory(assets, 'Folder', imagefolder_id)
for i in range(20):
img = invokeFactory(images, 'Image')
img.setImage(random_image(width, height))
img.reindexObject()
The invokeFactory() method used here is just a tiny wrapper around the standard invokeFactory() method of a folder object that generates a random title and a normalized id for the new content object plus doing some pre-allocation of the description and text field (if available) on the created content-object.
The complete code can be found on the website of my Plone partner Veit Schiele (German only).

