Skip to content. | Skip to navigation

Personal tools
Log in
You are here: Home

Latest Plone Posts

How to allow users to create site content using PloneFormGen

By Christine Shaw from Planet Plone. Published on Jan 29, 2015.

Plone content image


Let's pretend you've got a website featuring press releases about science and technology. You'd like to let your visitors submit their own press releases without having a site login. You're in luck! In this article, we'll cover two ways to achieve this task using PloneFormGen.

Site content can be created via PloneFormGen with a Custom Script Adapter or by using an add-on adapter called PloneFormGen Save Data to Content (uwosh.pfg.d2c). Additionally, you could write python scripts to handle the submissions, but we will not be covering that method.

Creating Content using a Custom Script Adapter

1. Add and publish a new Folder to the root of your site called "User Content." This is where the new content will be saved.

2. Add a FormFolder, titled "Press Releases" and uncheck "Mailer" for the Action Adapter. Save.

3. Delete the default fields (comment, etc.) and add two required fields:

  • String Field : Press Release Title
  • Text Field : Press Release Content

4. Add a new Custom Script Adapter to the FormFolder via the Add New menu:

  • Set the Proxy Role to "Manager" (note the security risk here -- make sure your form does what you think it does and nothing else!)
  • Create the script which will create the new content. For our example, we're creating a Page (Document) in the site:
# Target folder is the newly-created Press Release folder
from Products.CMFCore.utils import getToolByName
urltool = getToolByName(context, "portal_url")
portal  = urltool.getPortalObject()
targetdir = getattr(portal, 'user-content')

# The form being submitted so we can access its contents
form = request.form

# Create a unique ID
from DateTime import DateTime
uid = str(DateTime().millis())

# Create a new Page (Document)
targetdir.invokeFactory("Document", id=uid, title=form['press-release-title'])

# Set the reference for our new Page
doc = targetdir[uid]

# Set the values for the content of the Page; use the short names of each item in the form
# (which you can see in the URL if you are viewing one of the fields directly)

# Reindexed the Page in the site

The item will be in the Private state by default, so you can review what was submitted. If you wanted to submit it for publication so that the state is Pending Review, append the following to the script:

# Submit for Review
portal_workflow = getToolByName(context, 'portal_workflow')
portal_workflow.doActionFor(doc, 'submit')

Or if you want it to go straight to Published (risky!), simply replace 'submit' with 'publish'.

Creating Content using the Save Data Adapter

If you have the ability to install add-on products in your site, another method of creating content using PloneFormGen is to use the PloneFormGen Save Data to Content adapter (uwosh.pfg.d2c).

First, we'll need to set up the content type we want to create in the ZMI. Using the same example as above, let's say we want to create a Press Release in the site. This adapter requires the content type to have 'uwosh.pfg.d2c' configured as its 'product'. This can be achieved in one of three ways: adding it programmatically, with genericsetup profile, or copying the existing one in portal_types tool. We'll use the last method in this example.

To create the type:

1. In your site as admin, go to /portal_types/manage_main

2. Clone the content type FormSaveData2ContentEntry by using copy and paste.

3. Check the box next to your new copy and select Rename. For our example, rename it to "Press Release."


Rename 2

4. Click on the type's title (now "Press Release") to edit additional fields:

  • Change the Title to "Press Release".
  • Change the Description to something informative such as "A document used for Press Releases" (or you can delete the default text and leave it blank).
  • Since we'd like the Press Release to visually appear like a Document (Page) in the site, change the value for the following fields to document_view:
    • Initial view name
    • Default view method
    • Available view methods
  • If you would also like your type to be addable without the use of the PFG form (e.g., using the Add New menu by users with permission), check the box for Implicitly Addable.

Edit Type



To create the Form used by visitors to submit a Press Release:

1. Add a FormFolder, titled "Press Releases" and uncheck "Mailer" for the Action Adapter. Save.

2. Delete the default fields (comment, etc.) and add two required fields:

  • String Field: Press Release Title
  • Text Field: Press Release Content

3. Because the document_view template used to display the Press Release expects the body content to actually be referred to as the name "text," we need to change the short name of the Press Release Content field:

  • View the folder_contents of the form
  • Check the box next to "Press Release Content" and click "rename"
  • Change the "Short Name" to "text"

Rename 3

Rename 4

4. Add a new Save Data to Content Adapter to the FormFolder via the Add New menu:

  • Title: Create Press Release
  • Title Field: press-release-title
  • Saved Entry Content Type: Press Release

You can also choose which workflow to apply to a Press Release at this time.



5. Publish your form.

Anonymous visitors to the site may now submit Press Releases without needing an account to log in with on your site.

The Press Releases will be created inside the Content Adapter (it is folderish), and will be private by default unless you selected a workflow which allows the item to be automatically published. Because the Content Adapter is still private, these items will not be available via search. Publish and move approved items to a published folder location to have them searchable and visible to users on your site.

The layout view applied (document_view) will be the same as a Document (Page), so the title will appear in the title location and the body will display the content. If we were to just use the default base_view when creating the new Press Release content type, it would instead display the field names as captions to each item.

I hope this article helped give a basic understanding of how to allow your users to create site content with PloneFormGen. Have questions or comments? Sound off in the comments section below and be sure to sign up for our Plone & Python How-To digests to receive more how-to guides as soon as they are published!

Python Meeting Düsseldorf - New Videos Online

From Planet Plone. Published on Jan 29, 2015.

The following text is in German, since we're announcing videos available from a regional user group meeting in Düsseldorf, Germany.

Was ist das Python Meeting Düsseldorf ?

Das Python Meeting Düsseldorf ist eine Veranstaltung, die alle drei Monate in Düsseldorf stattfindet und sich an Python Begeisterte aus der Region wendet.

Bei jedem Treffen werden Vorträge gehalten und anschließend in Diskussionen vertieft. Die Meetings dauern üblicherweise ca. 2 Stunden und münden anschließend in eine Restaurant-Session.

Teilnehmer kommen aus ganz Nordrhein-Westfalen, hauptsächlich allerdings aus der näheren Umgebung.

Neue Videos

Um die Vorträge auch für andere Python Enthusiasten zugänglich zu machen, nehmen wir die Vorträge auf, produzieren daraus Videos und laden diese auf unseren PyDDF YouTube Channel hoch.

In den letzten Tagen haben wir die Videos der letzten Treffen aufgearbeitet. Insgesamt sind 34 neue Videos dazugekommen. Viel Spaß damit:

Python Meeting Düsseldorf 2015-01-20

Python Meeting Düsseldorf 2014-09-30

Python Meeting Düsseldorf Sprint 2014 (2014-09-27/28)

Python Meeting Düsseldorf 2014-07-02

Python Meeting Düsseldorf 2014-04-29

Python Meeting Düsseldorf 2014-01-21

Python Meeting Düsseldorf 2013-11-19

Die vollständige Liste aller mehr als 70 Python Meeting Videos ist über unsere Video Liste verfügbar.

Weitere Informationen

Weitere Informationen und Termine rund um das Python Meeting Düsseldorf stehen auf unserer Webseite:


Viel Spaß !

Marc-Andre Lemburg,

Boot: Getting Started With Clojure In < 10 Minutes

By jjmojojjmojo from Planet Plone. Published on Jan 28, 2015.

With the power of boot, it’s possible to go from “never used java before” to budding Clojure-ist cranking out jars like a pickle factory in record time. This post walks you through the process, and provides some post-‘hello world’ examples, with pointers to more information. Prerequisites You will need the following: A JDK installed. Really, […]

Plone and Docker

From Planet Plone. Published on Jan 28, 2015.

In this post, I will try to explain how we put a new Plone site into production in our organization (IMIO, Belgium). For this process, we used some softwares as Puppet, Jenkins, but the process we use should be agnostic from these softwares.

Another Plone Site on AWS OpsWorks

By Sally Kleinfeldt from Planet Plone. Published on Jan 26, 2015.

Congratulations to YES! Magazine on the launch of their redesigned website! This award winning, ad-free, non-profit online (and print) magazine for progressive thinkers runs on Plone, our favorite CMS. Originally launched in 2009 by our friends at Web Collective and Groundwire (RIP), this is the first redesign the site has had since then. The focus […]

Sprint Report: Merging Mockup and Patternslib

From Planet Plone. Published on Jan 25, 2015.

Sprint Report: Merging Mockup and Patternslib

Alpine City Sprint

By Kees Hink from Planet Plone. Published on Jan 23, 2015.

In Innsbruck wordt hard gewerkt aan de nieuwe versie van Plone.

Kotti - avoid types addable in content root

By davide moro ( from Planet Plone. Published on Jan 23, 2015.

With Kotti CMS ( you don't have to fight against the framework: after one or two days you'll love it and you will be productive.

You can add new content types mapped on database tables, extend existing ones, add one or more object actions, easy building of add and edit views without having to touch any html file.

Kotti is shipped with the pytest framework and I love it! The tests setup is very easy and you can mock or initialize your reusable fixtures with a dependency injection technique.

If your customer wants to use Windows, no problem:

How to prevent your content types to be added in content root

This blog post will explain how to prevent your content type to be added in the content root but only in Document types (they behave like folderish items too). What's the matter? The root itself is a Document.

My solution was similar to the following one, but a bit different:


from kotti.resources import TypeInfo
from kotti.resources import get_root
from kotti.resources import Content

class YourContentTypeInfo(TypeInfo):

    def addable(self, context, request):
        root = get_root()
        if context == root:
            return False
        return super(YourContentTypeInfo, self).addable(context, request)

yourcontent_type_info_data = Content.type_info.copy(
yourcontent_type_info = YourContentTypeInfo(**course_type_info_data)

class YourContent(Content):
    """ A yourcontent type. """


    id = Column(Integer, ForeignKey(''), primary_key=True)

    type_info = yourcontent_type_info
I tried to inherit all the default options and actions from the default Content's type info. This way you'll inherit all the backend menu actions.



After using Kotti for a while I can tell that the feedback is absolutely positive. It is the right choice when you don't need a much more complex system like Plone. So join the Python, Pyramid and Kotti community and say love to Kotti!

The case against Docker

From Planet Plone. Published on Jan 21, 2015.

Trying to use Docker for production for several week finally ended in the decision to let Docker for the moment.

How to install Kotti CMS on Windows

By davide moro ( from Planet Plone. Published on Jan 19, 2015.

Yes, as expected, you can install Kotti CMS also on Windows if you have this constraint!

What is Kotti

From the official doc:

"""A high-level, Pythonic web application framework based on Pyramid and SQLAlchemy. It includes an extensible Content Management System called the Kotti CMS.

Kotti is most useful when you are developing applications that:
  • have complex security requirements
  • use workflows, and/or
  • work with hierarchical data

It is developer friendly and with a good user interface. You can easily extend it, develop new features or install one of the available third party modules (search for Kotti on if you want to browse existing modules ready to be used). Heavily inspired by Plone (
If you want to evaluate Kotti you can install it locally (no database installation is required, you can use SQLlite during evaluation or development).
Otherwise if you are particular lazy there is a working demo online with admin / qwerty administrator credentials: 


  • python (tested with python 2.7.9 but it should work also on newer versions)
  • Microsoft Visual C++ 9.0 available on the following url (needed for an issue with bcrypt)
  • virtualenv (suggested)

Installation steps

Once you have installed python from you can start installing Kotti. I assume in this article that your Python installation path is C:\Python27.
Now create a new folder (it doesn't matter the name, in this article my folder name is just kotti):
> mkdir kotti
> cd kotti
Install virtualenv and create a new isolated python environment in your kotti dir:
> C:\Python27\Scripts\pip.exe install virtualenv> C:\Python27\Scripts\virtualenv.exe --no-site-packages .
Install Kotti and its requirements:
> Scripts\pip.exe install -r
> Scripts\pip.exe install Kotti

Put inside your kotti dir the app.ini file downloaded from:
Runs Kotti:
Scripts\pserve.exe app.ini
Starting server in PID 2452
serving on


If Microsoft Visual C++ Compiler for Python 2.7 is not installed on your environment you'll get an error during the requirements installation phase (only on Windows):
> Scripts\pip.exe install -r
  Running install for py-bcrypt
    building 'bcrypt._bcrypt' extension
    error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat).
Get it from
    Complete output from command C:\Users\dmoro\kotti\Scripts\python.exe -c "imp
ort setuptools, tokenize;__file__='c:\\users\\dmoro\\appdata\\local\\temp\\pip-b
uild-mact2r\\py-bcrypt\\';exec(compile(getattr(tokenize, 'open', open)(_
_file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record c:\u
sers\dmoro\appdata\local\temp\pip-wcmy6c-record\install-record.txt --single-vers
ion-externally-managed --compile --install-headers C:\Users\dmoro\kotti\include\
    running install

    running build

    running build_py

    creating build

    creating build\

    creating build\\bcrypt

    copying bcrypt\ -> build\\bcrypt

    running build_ext

    building 'bcrypt._bcrypt' extension

    error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat).
Get it from
You just need to install this requirement and all will work fine.



Kotti's front page (from the public demo online):

Kotti's folder contents (from the public demo online), requires authentication:

eGenix Talks & Videos: Advanced Database Programming

From Planet Plone. Published on Jan 19, 2015.

eGenix Talk "Advanced Database Programming"

At last year's EuroPython 2014 conference in Berlin, Marc-André Lemburg, CEO of eGenix, gave the following talk on database programming in Python. We have now turned the talk into video presentation for easy viewing and also released the presentation slides:

EuroPython 2014 - Advanced Database Programming

Advanced concepts in Python database programming.

The Python DB-API 2.0 provides a direct interface to many popular database backends. It makes interaction with relational database very straight forward and allows tapping into the full set of features these databases provide.

This talk covers advanced database topics which are relevant in production environments such as locks, distributed transactions and transaction isolation. We also give advice on how to deal with common problems you face when working with complex database systems.

Click to proceed to the talk video and slides ...

Related Python Coaching and Consulting

If you are interested in learning more about these advanced techniques, eGenix now offers Python project coaching and consulting services to give your project teams advice on how to implement complex database architectures in Python. Please contact our eGenix Sales Team for information.

More interesting eGenix presentations are available in the presentations and talks section of the library on our website.

Enjoy !

Charlie Clark, Sales & Marketing

Pyramid starter seed template powered by Yeoman (part 2)

By davide moro ( from Planet Plone. Published on Jan 16, 2015.

In the previous blog post we have seen what are the benefits of using the Yeoman workflow fully integrated with a web development framework like Pyramid. See:

Now we'll add more technical details about:
  • how to install pyramid_starter_seed and its prerequisites

How to install pyramid_starter_seed


    As you can imagine, nodejs tools are required.

    I strongly suggest to:
    • avoid system packages because they are too old
    • install nodejs with nvm (Node Version Manager)
    I won't cover the nodejs installation but it is quite simple if you follow these instructions provided by this useful link:
    The nvm achronym stands for NodeJS Version Manager. Once installed nvm, installing nodejs it is as simple as typing nvm install VERSION (at this time of writing 0.10.32).

    Nodejs is shipped with the command line utility named npm (Nodejs Package Manager) and we will use npm for installing what we need.

    We need to install our global (-g option) dev dependencies, so just type:
    $ npm install -g bower
    $ npm install -g grunt-cli
    $ npm install -g karma

    Starter seed project installation

    Create an isolated Python environment as explained in the official Pyramid documentation and instal Pyramid.

    Once installed you can clone pyramid_starter_seed from github:
    $ git clone
    $ cd pyramid_starter_seed
    $ YOUR_VIRTUALENV_PYTHON_PATH/bin/python develop
    Not finished yet, continue.

    Yeoman initialization

    Go to the folder where it lives our Yeoman project and initialize it.

    These are the standard commands (but, wait a moment, see the "Notes and known issues" subsection):
    $ cd pyramid_starter_seed/webapp
    $ bower install
    $ npm install --loglevel verbose
    Known issues:
    • if you are behind a proxy you'll have to configure properly npm
    • if you have a slow internet connection you might experience timeout problems.

    Build phase

    Just type:
    $ grunt
    and... probably it will fail because of a couple of known issues shipped with the latest version of generator-webapp or its dependencies.

    Probably these issues will be fixed in newer generator-webapp releases. However here it is how to solve these problems, so don't worry:
    1. grunt-contrib-imagemin fix
      Problem with grunt:
      Warning: Running "imagemin:dist" (imagemin) task
      Warning: Bad argument Use --force to continue.
      $ npm cache clean
      $ rm -fR node_modules       # not sure it is needed, don't remember
      $ npm install grunt-contrib-imagemin
    2. Mocha/PhantomJS issue
    Problem with Mocha/PhantomJS launching grunt
    Warning: PhantomJS timed out, possibly due to a missing Mocha run() call. Use --force to continue.
    $ cd test
    $ bower install
    Run bower install in the test directory of webapp (pyramid_starter_seed/webapp/test). This is a known issue, see

    Run you Pyramid app

    Now can choose to run Pyramid in development or production mode.
    Just type:
    $ YOUR_VIRTUALENV_PYTHON_PATH/bin/pserve development.ini
    $ YOUR_VIRTUALENV_PYTHON_PATH/bin/pserve production.ini

    In the next blog post with topic Pyramid + Yeoman (coming soon) I'm going to talk about:
    • how to manage things with grunt and personalize pyramid_starter_seed registering other assets
    • how to clone pyramid_starter_seed. Yes, you can easily customize it creating something of more sophisticated and create your own starter seed with another name. Without having to write a package generator
     So stay tuned..


    Beats audio setup for HP Envy on recent Ubuntu

    By encolpe from Planet Plone. Published on Jan 16, 2015.

    First, you can already find this excelent article on Reddit : [HowTo] Beats Audio HP Laptop speakers on Ubuntu/PulseAudio But the package hda-jack-retask is stuck in raring. The goal here is to allow you to install the package in your brand new Ubuntu. Replace « utopic » each time it is mentionned velow by your version. sudo […]

    How to embed video on a page

    By ledwell from Planet Plone. Published on Jan 14, 2015.

    This is a work around for TinyMCE stripping out embed code. It uses the "Snippets" product created by Sam Schwartz.

    Macbook pro black screen and restart problem

    By Reinout van Rees from Planet Plone. Published on Jan 14, 2015.

    Note: updated instructions (as he did it again).

    This morning I took my macbook pro (a very nice late 2014 retina 15" one) out of my backpack, opened it and plugged in the external monitor. But it stayed black. The macbook's own screen also stayed black. Ouch? It didn't seem to wake up...

    Some standard things I checked/tried:

    • The battery couldn't be empty yet. The apple logo on the back of the screen was illuminated, right? Of course I had already attached it to the power cord. Which showed its LED, so power wasn't the problem.
    • Screen brightness. Perhaps I dialed it down to zero by accident? No.
    • Close/open again. Take out external display. Etc. Nope.

    Ok, time to press the power button. No reaction that I could see/hear. Press it 10 seconds. No. Problem with such a new macbook is that it doesn't have a harddisk. The noises a harddisk makes tend to provide pretty good feedback on what's happening normally :-)

    I just couldn't get the macbook to reset (or shut down)! If the power button doesn't work... Googling turned up two additional tricks:

    • Resetting the "SMC", the system management controller. One of the things it does is monitor the power button... Press shift-option-control-power and release them all at the same time.

      Sure enough the LED indicator on the power cord switched from red to green and back again, so the SMC reset worked.

      Only... the computer still didn't respond to the power button as far as I could notice.

    • Resetting the PRAM/NVRAM, some sort of special memory with, amongst others, video settings. Sounds good! Press command-option-p-r when your macbook boots. AAARGH! That's the whole problem! The macbook refuses to listen to the power button, so it won't restart. So I can't get at a potential fix for the restart-problem because the computer won't, well, restart.

    I asked my mac-using colleague to help me. Different google searches sometimes help. And a double-check whether I had not missed anything obvious is always handy. He also tried pinging/ssh'ing my machine. Weird thing that we started to notice that there were brief periods where the mac was pingable! Did some of the power button reset attempts work, perhaps, despite not seeing/hearing any feedback?

    Because I had removed the macbook from its regular stand and placed it directly on my desk I suddenly noticed that the logo illumination was off. Hey! Perhaps one of the resets did work. Despite not resulting in the regular "peep" from the speakers. Of course the problems I was having might have disrupted the speakers also.

    Ok, if it is off, time to do the PRAM reset mentioned above. Power button, press command-option-p-r, PEEEEEP! Bingo! The startup sound was suddenly audible and lo and behold, I saw the login screen.

    Back in business!

    Now... my only guess as to the original cause is that I plugged in the external monitor too quickly after waking my macbook. Of course this isn't something that should cause a mac any problems, but apparently it can. I'll just have to wait a couple of seconds next time.

    VERY glad that it works again...