Planet Plone

This is where developers and integrators write about Plone, and is your best source for news and developments from the community.

November 26, 2015

David "Pigeonflight" Bain: Building a Self Hosted CMS Site using Webflow and Plone (Video Series)

by David Bain at 2015-11-26T14:13:00Z

One of my personal goals is to make it easier for persons to get started with web development technologies. I teach web programming at my local university, I blog about my preferred CMS (Plone). For front-end development I now point designers at Webflow. In line with that I've recently created a video series that shows how to use Plone as your CMS and Webflow for theme development. Last

November 25, 2015

Paul Everitt: Python virtualenvs: Inside project or outside?

by Paul Everitt at 2015-11-25T17:16:08Z

I’m a dummy. I pulled the old “pretend to ask an honest question but really to confirm your belief” trick and, shockingly-not, got refuted. My small sample seems to like making their Python virtual environments outside of their projects.


I do a lot of Python explaining (Py-splaining?) and, contrary to the “see how much our Won-The-War framework can do in minus ten lines of hello”, I try to suck it up and show the right way. This usually means, make a virtual environment. It also means make a package, which ranks up there with “drop a frozen turkey in a deep fryer using your teeth” on the scale of holiday fun.

Virtual environments are a little squirrelly to explain. Like “mobile first” for web dev, I have committed to Py3-first for teaching, which means you get pyvenv for free. I then show making a and doing pip install -e . (or python ./ develop), binding that virtualenv to this project.

In my mind, that means the virtualenv is part of this project directory. If I give up on the project, I delete the directory, and everything goes with it. If I’m using SQLite, I store my .sqlite file in that working directory as well. If I’m doing JS frontend stuff, my node_modules is in that directory. It thus makes sense that my virtualenv (or plural, if I’m doing multiple Python versions) should be in the same working directory. It’s an artifact of that project.

In fact, Python’s “Hitchhiker’s Guide to Python” advertises this workflow.

I posed the question on Twitter because PyCharm, when making a new project, wants the virtualenv outside of the to-be-created project directory. I was looking to bolster my viewpoint.

The Herd Is Wrong

The wisdom of crowds voted against me 12-6. That’s the trouble with crowds, they are only wise when they agree with me. I guess that’s the difference between a crowd and a mob.

I think I’ll march on, teaching to firmly associate the virtualenv with the project, holding up the Hitchhiker’s Guide as my certificate of authenticity. But I won’t file a likely-disruptive ticket in PyCharm. Security vulnerability pre-announcement: 20151208


Hotfix to patch various vulnerabilities

November 24, 2015

Paul Everitt: My O’Reilly video series on Pyramid is up

by Paul Everitt at 2015-11-24T14:58:36Z

Earlier this year, just before PyCon, I talked to O’Reilly about doing a Pyramid video course in their commercial training catalog. It’s now in “early access”, titled “Web Applications with Python and the Pyramid Framework“.

What an effort it turned out to be. I’m certainly grateful that it has wrapped up, but I’m also glad I did it. I put a serious amount of work (months) into writing, re-writing, and re-re-rewriting the narrative and the examples. Thanks go out to Chris and Tres for steering me throughout on best practices, to include the admonition that chasing best practices is a fool’s errand.

Several items of reflections:

  1. I resisted the urge to go off the beaten path. It’s routes, Jinja2, and SQLAlchemy. I originally had “traversal in SQL” in the proposal. I chopped it out, despite my ongoing attempt at “pyramid_sqltraversal” (on GitHub.)
  2. I put more emphasis than I expected on the JSON section and frontend web applications.
  3. I also put more into extensibility (aka “framework framework”) than I had planned. I’m not that good at that story, so perhaps that’s why… I finally had a reason to learn it. And damn, Pyramid’s awesome at that.
  4. Ditto for authentication and authorization combined with SQLAlchemy. I now know a lot more about how to do that, and it’s a great story. As an aside, root/route factories (and thus having a context) should be the way we teach people to start.
  5. Of course it featured PyCharm. I couldn’t have known that, as I wrapped up, I’d be talking to JetBrains about joining the PyCharm team.
  6. I got pretty good at Camtasia, geezus.
  7. Python’s packaging story is such a bear to explain to novices.

So six hours of (unedited) video later, it’s on the way out the door. Pyramid is so unique and so powerful…hope this series helps some mortals who are trying to get started.

November 23, 2015

Reinout van Rees: Fixing SSL certificate chains

by Reinout van Rees at 2015-11-23T11:37:00Z

This blog post applies when the following two cases are true:

  • Your browser does not complain about your https site. Everything seems fine.
  • Some other tool does complain about not finding your certificate or not finding intermediate certificates. What is the problem?

So: your browser doesn't complain. Let's see a screenshot:

Browser address bar with a nice green closed lock, so ssl is fine

Examples of the errors you can see

Some examples of complaining tools. First curl:

$ curl https://api.letsgxxxxxxx
curl: (60) SSL certificate problem: Invalid certificate chain
More details here:
curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

curl has the right error message: Invalid certificate chain.

Let us look at wget:

$ wget https://api.letsgxxxxxx
--2015-11-23 10:54:28--  https://api.letsgxxxxx
Resolving api.letsgxxxxxx...
Connecting to api.letsgxxxxxx||:443... connected.
ERROR: cannot verify api.letsgxxxxxx's certificate, issued by 'CN=COMODO RSA
  Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB':
  Self-signed certificate encountered.
To connect to api.letsgxxxxxx insecurely, use `--no-check-certificate'.

wget is right that it cannot verify .... certificate. But its conclusion Self-signed certificate encountered is less helpful. The certificate is not self-signed, it is just that wget has to treat it that way because the certificate chain is incorrect.

If you talk to such an https URL with java, you can see an error like this:
PKIX path building failed:
unable to find valid certification path to requested target

This looks quite cryptic, but the cause is the same. SunCertPathBuilderException: CertPath sure sounds like a path to a certificate that it cannot find.

A final example is with the python requests library:

>>> import requests
>>> requests.get('https://api.letsgxxxxxx')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/requests/", line 69, in get
    return request('get', url, params=params, **kwargs)
  File ".../requests/", line 50, in request
    response = session.request(method=method, url=url, **kwargs)
  File ".../requests/", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File ".../requests/", line 573, in send
    r = adapter.send(request, **kwargs)
  File ".../requests/", line 431, in send
    raise SSLError(e, request=request)
SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

How to determine what's wrong

So... you yourself discover the problem. Or a customer calls that he's getting an error like this. Even though everything seems right if you test the https site in the browser.

Solution: go to

If that site says everything is completely right, then you're done. If it still complains about something, you've got work to do.

Most of the checkmarks are probably green:

Green checkmarks in front of many common SSL checks

In cases like this, the problem is in the certificate chain at the bottom of the page. Here's an example of one of our own sites from a few months ago:

Broken chain icon indicating the exact problem spot

Note the "broken chain" icon halfway. Just follow the chain from top to bottom. Everything has to be perfect. We start with the * which is issued by GeoTrust SSL CA - G2.

The certificate GeoTrust SSL CA - G2 in turn is issued by GeoTrust Global CA.

The problem: the next certificate in the chain is not about GeoTrust Global CA, but about GeoTrust SSL CA, which is different. Here the chain breaks. It does not matter that the fourth certificate is about the GeoTrust Global CA we were looking for. The chain is broken. The order in which the certificates are placed must be perfect.

After fixing the order of the certificates in our certificate file, the problem was fixed:

Chain icons indicating that the chain is unbroken

Why is a chain needed?

There are lots of certificates in the wild. All the browsers (and java, and your OS and...) often only store a handful (well, 20+) "root certificates". All the other certificates have to trace their origin back to one of those root certificates.

That is where the intermediate certificates come in: they're a cryptographically signed way to trace the validity of your certificate back to one of the known-good root certificates.

How to fix it

  • If you're handling certificates yourself, you ought to know which files to edit. The main problem will be getting the right intermediary certificates from the issuing party. Often you only get "your" certificate, not the intermediary ones. Ask about it or google for it.

  • Often you won't maintain those certificates yourself. So you have to get your hosting service to fix it.

    If you let someone else take care of the certificate, point them at and tell them to make sure that page is completely happy.

    In my experience (=three times in the last two years!) they'll mail back with "everything works now". But it still won't work. Then you'll have to mail them again and tell them to really check and probably provide screenshots.

Good luck!

November 20, 2015

T. Kim Nguyen: robot testing error "Non-existing setting"


"Test case name cannot be empty."

November 19, 2015 Plone Conference Boston 2016


Boston, Massachusetts, USA, October 17-23, 2016 2015-2016 Foundation Membership Committee


welcome new members on the committee reviewing applications for Plone Foundation membership

Reinout van Rees: Nginx proxying to nginx: getting gzip compression to work

by Reinout van Rees at 2015-11-19T14:09:00Z

At work we use gunicorn as our wsgi runner. Like many, gunicorn advises you to run the nginx webserver in front of it. So on every server we have one or more websites with gunicorn. And an nginx in front.

Nginx takes care, of course, of serving the static files like css and javascript. Some gzipping of the results is a very, very good idea:

server {
    listen 80;
    gzip on;
    gzip_proxied any;

Two notes:

  • The default is to only gzip html output. We also want javascript and json. So you need to configure gzip_types.

    (I copy-pasted this from one of my config files, apparently I needed three different javascript mimetypes... Perhaps some further research could strip that number down.)

  • gzip_proxied any tells nginx that gzipping is fine even for proxied requests.

Proxied requests? Yes, because we have a lot of servers and all external traffic first hits our main nginx proxy. So: we have one central server with nginx that proxies requests to the actual servers. So: nginx behind nginx:

server {
    listen   443;
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://some-internal-server-name/;
    ssl on;
    ssl_certificate ...

Pretty standard "I listen on 443/https and proxy it on port 80 to some internal server" setup.

Works like a charm. Only drawback: gzipping does not work.

The reason? nginx defaults, in this case.

  • The gzip module has a gzip_http_version configuration parameter with a default of 1.1.

    Which means that http 1.0 requests are not gzipped, only 1.1.

  • The proxy module has a proxy_http_version configuration parameter with a default of 1.0.

    Which means that proxied requests are send from the main proxy to the actual webserver with http 1.0.

These two don't match. There are two solutions:

  • Set gzip_http_version 1.0 in the nginx configs on your webservers. This switches on gzip for the http 1.0 connections coming from the proxy.
  • Set proxy_http_version 1.1 on the main proxy so that it sends http 1.1 connections to the webservers.

My choice originally was to do the first one. But a bug report came in for another site and now I've switched it on on the main proxy so that all the sites get the benefit.

Note: you might want to make different choices. Perhaps you have a caching proxy halfway? Perhaps you want the main nginx on the proxy to do the gzipping for you? Etcetera. Check whether the above tips apply to your situation :-)

November 18, 2015

Jazkarta Blog: Plone Comes to Beantown

by Sally Kleinfeldt at 2015-11-18T21:59:08Z


I’m excited to share the news that the 2016 Plone Conference will be right here in Boston! Save the dates October 17-23 for a solid week of excellent training, informative talks, inspiring keynotes, and productive sprints like we’ve come to expect from a Plone conference – all for one reasonable (not yet finalized) price. The Microsoft New England Research and Development center has graciously agreed to host us, and we’ll be spreading ourselves liberally around Kendall Square and the MIT campus. (Yes, that’s technically Cambridge, not Boston, but that’s a distinction most non-New Englanders don’t make.)

At this conference we plan to extend the Plone community’s greetings and space to the larger Python Web community which many of us are also involved in. This happened in San Francisco several years ago; in Boston we hope to integrate these threads rather than having separate tracks. We want to include talks, trainings, and sprints on a variety of Python web frameworks, but we especially want to encourage talks and activities that compare, contrast and encourage learning and sharing across systems. (Not to mention socializing.)

The week will start with 2 days of training for developers, designers, and integrators, which will be included in the conference registration fee. Attendees will be able to mix and match full day classes on theming and development in Plone and other Python web technologies, with shorter workshops on a wide variety of topics.

The next 3 days will start with a keynote where the whole community will come together, and then we’ll break into 3 simultaneous tracks of talks. (Choosing between them is always hard!) We will be inviting talks on specific topics to give clarity and shape to the conference’s agenda. The rest will come from an open call for talk proposals. We’ll be continuing the Bucharest tradition of encouraging new speakers to present – so start jotting down your ideas.

After the talks there will be 2 days of “sprints”, focused development sessions that everyone, regardless of skill level, can participate in. This can include everything from core Plone through documentation. We plan to include Pyramid and other Python Web sprint topics to make this an event that can be shared with members of the sizable Boston Python community.

So I hope to see you all there! The Plone Conference is like a family reunion – we all look forward to it every year. I’m really excited about sharing those good vibes with Boston.

Tagged: boston, cms, ploneconf2016, python web

Paul Everitt: PyRVA meet up and type hinting

by Paul Everitt at 2015-11-18T13:59:46Z

Python’s community has long been considered as valuable as the
software, and that extends to Python local meetups. They’re fun to
attend, but what’s even more fun is watching one during its formation.

Last week I attended the second PyRVA meet up in Richmond, VA and talked about Python 3.5 type hinting in PyCharm. The user group is founded by Andrew Elbert. The location was part of Virginia Commonwealth University (VCU), a large public university in the heart of Richmond. Really nice meet up space: table seating for everyone and humongous display for presentation.

I’ve been to a lot of these, over the decades and across continents. I seem to enjoy the people in this business more than the software, so I have a fascination for how people group-up and do new things. This meetup was interesting in several ways:

  • Diverse in ethnicity, gender, age and skill level
  • First half was bootcamp-style, with experienced people working with
  • Part “CS student learning another language” and part “I have a job but want to advance my career by learning programming skills”
  • It’s a testament to the founders that they have injected this vibe in from the beginning.

The evening started with sandwiches, yummy. The room filled up, with people sitting around the sides, so almost 40 people, and this was the only the second session. Clearly they have tapped into something. The bootcamp part ran for about an hour. Then a talk on devops with Jenkins, followed by a fun talk on using Python to analyze the historical reading-level of Jeopardy questions.

I talked about type hinting in Python 3.5, as covered in an article I am finishing up this week. I also covered general questions about PyCharm. I’m learning more about the target audience, for IDEs in general and PyCharm specifically, and this was a good chance to again talk to such-minded people. One thing I’m learning: some beginners are more comfortable seeing “Python” on the screen. Not a terminal, with an editor they need to run and a shell to run a command, etc. They want something that frames their new world and gives them targets to interact with.

And of course, like all my talks, it was just a thin excuse to give two decades of Python-related funny stories.

PyRVA is one I will keep an eye on. I hope they grow, keep the enthusiasm up, and preserve the unique qualities they have started with.

November 16, 2015

Reinout van Rees: Buildout 2.5.0 has much nicer version conflict reporting

by Reinout van Rees at 2015-11-16T08:26:00Z

We use buildout for all our django projects. Nothing wrong with pip, but buildout has extension possibilities build-in (for creating directories, installing user crontabs, local development checkouts and many more) that are quite helpful. And it works better when you need to use system packages (gdal, mapnik, etc).

One area where buildout could use some improvement was the version conflict reporting. Let's say you have pinned django to 1.6.6 (old project that I'll upgrade to 1.8 this week) and you add the django debug toolbar. This is the error you get:

The constraint, 1.6.6, is not consistent with the requirement, 'Django>=1.7'.
  Updating django.
Error: Bad constraint 1.6.6 Django>=1.7

First things first. An easy one is to improve the wording of the message:

  Installing django.
Error: The requirement ('Django>=1.7') is not allowed by
your [versions] constraint (1.6.6)

Now... so there is some package that requires at least django 1.7. But which one? Buildout did not tell you. Which would mean you'd have to grep in all your requirements' sub-requirements for which package actually requires the offending "django>=1.7"...

I've now added some internal logging that stores which package required which dependency. After an error occurs, the list is searched for possible matches.

With this change you'll get a much more helpful output right before the error:

Installing django.
version and requirements information containing django:
  [versions] constraint on django: 1.6.6
  Base installation request: 'sso', 'djangorecipe'
  Requirement of djangorecipe==1.10: Django
  Requirement of djangorecipe==1.10: zc.recipe.egg
  Requirement of djangorecipe==1.10: zc.buildout
  Requirement of sso: django-nose
  Requirement of sso: django-mama-cas
  Requirement of sso: django-debug-toolbar
  Requirement of sso: django-auth-ldap
  Requirement of sso: Django<1.7,>=1.4.2
  Requirement of lizard-auth-server: django-nose
  Requirement of lizard-auth-server: django-extensions
  Requirement of lizard-auth-server: Django<1.7,>=1.6
  Requirement of django-nose: Django>=1.2
  Requirement of django-nose: nose>=1.2.1
  Requirement of django-mama-cas: requests==1.1.0
  Requirement of django-debug-toolbar: sqlparse
  Requirement of django-debug-toolbar: Django>=1.7
  Requirement of django-auth-ldap: python-ldap>=2.0
  Requirement of django-auth-ldap: django>=1.1
  Requirement of translations: Django>=1.4
  Requirement of django-extensions: six>=1.2
  Installing django.
Error: The requirement ('Django>=1.7') is not allowed by
your [versions] constraint (1.6.6)

This makes it much easier to spot the cause (in this case django-debug-toolbar).

There are some unrelated packages in here because I'm doing a textual comparison. The advantage is that it is very robust. And extracting the right package name from requirements without messing things up is harder to get right and takes more code.

So... if you use buildout, give version 2.5.0 a try!

November 13, 2015

Jazkarta Blog: New Website, New Plone

by Sally Kleinfeldt at 2015-11-13T21:31:17Z Plone Landing Page

Like the cobbler’s children who have no shoes, Jazkarta’s website was long overdue for some major work. We began working on a redesign last winter – some modest improvements that morphed into more major changes. When we were ready to move into development in the spring, the Plone 5 release was in beta, so we took the plunge and used this new and shiny Plone on our new website. We’re glad we did! We lived through some growing pains in the early months, but the software got more and more solid as the summer progressed. Plone 5 was officially released just weeks before our new website launched in October, so we have 2 things to celebrate.

Years in the making, this new version of “the ultimate open source CMS” has many, many improvements over its predecessors. A few high points:

  • Out-of-the-box responsive and improved tools for custom theming, including LESS integration (a big win for us since responsiveness was a high priority)
  • An improved content editing experience with a new toolbar, bulk editing, and TinyMCE 4
  • A new templating engine (Chameleon) which gives improved performance
  • Automatic CSRF (cross-site request forgery) protection
  • Improved accessibility, as described in a previous post
  • A new event type that supports all day, open ended, and recurring events
  • A full transition to the new “Dexterity” content type framework including support for migration of old content – better for editors (through-the-web customization) and better for developers (reusable behaviors)

And of course it’s still 100% open source and developed by our favorite community of volunteers. You can read all the details at

So check out our new website! We especially like our new projects page, our sliders for related items, and the flexibility of our tiled landing pages. A huge thank you to the team that created it!


Tagged: accessibility, chameleon, cms, content types, plone 5, tinymce

November 10, 2015

Maurits van Rees: Dutch Plone user day

by Maurits van Rees at 2015-11-10T21:35:58Z

This year my employer Zest Software organised the Dutch Plone user day in Rotterdam. Thank you to Jean-Paul and Fred for the organisation. Special thank you to Coen for translating the Plone posters to Dutch.

If you can read Dutch, head over to the Dutch version of this page for Jean-Paul's welcoming remarks and links to Dutch summaries of the talks.