Introduction
First I would like to thank Four Digits for hosting the sprint and Makina-Corpus for sponsoring my participation.
The Arnhem sprint has been organized on co-activate. The main topic was about removing all the old and ugly things from Plone to make it easier, faster and more modern. I will now try to sum up the three proposals I have worked on.
Let's start the sprint https://twitter.com/fourdigits/status/399857750827466752
Mockup (widgets)
The proposal: Let's 'modernize' the way we handle javascript in Plone.
But first let's remember the past
I have always known the portal_javascript and portal_css (Products.ResourceRegistry aka RR). The concept is simple and flexible: having an ordered registry of the resources.
A resource is composed of:
- an id (the name/url of the resource to download)
- one or more conditions (say authenticated or whatever)
- compression option (none, safe, full)
- caching boolean option (for dynamic resources)
This means you have to package resources into your addons. I started a long time ago to package many resources using the collective.js.* namespace. The first was the famous jQueryUI. Now you can find almost every known jQuery plugin and more on Pypi.
But time has passed and we have more and more discovered how hard it is to control the order of resources and to have a working bundle. Yes RR was not able to handle dependencies between resources.
So what is the future?
Rok Garbas has come with a process to achieve the following goals:
- 100% tests coverage of JS provided by Plone and it's on its way (86% at the moment)
- Using a common way to write / use JS: patterns
- Integrator can't break Plone JS easily (you must know what you are doing)
- Use a modern toolchain
The toolchain is based on the following technologies:
- node / npm (the JS vm / the package manager)
- grunt (task manager like Make)
- bower (a package manager of resources for the web)
- requireJS (a dependency manager)
How do I have contributed to this project?
The first day Rok was not there but we were 6 people discussing about the project and trying to set up all the things.
I have read about technologies inside the project and the configuration of the toolchain.
- chai
- mocha
- patternlib
I have worked on a low priority ticket: trigger bower install using grunt. It's useless but easy.
I have tried to add the bower-requirejs grunt task to update the requirejs configuration automatically. I didn't succeed because the mockup project doesn't use a normal JS config file for some reason I don't remember.
Then I have worked on "bundling jQuery" with widgets (https://github.com/plone/mockup/issues/203). The main idea was to make plone.app.jquery deprecated and let mockup provides it. I had a couple of issues, let's go trough them:
Issue 1 was: We use jQuery to make some checks and load requirejs. So I had to rewrite the loader without jQuery and something funny was: how do I wait for the document being ready without jQuery? The best way we have found was to use https://github.com/ded/domready.
Issue 2 was: Using requireJS you have to wait for jQuery to be loaded, but Plone RR adds all the jQuery plugins to the page before. So I have unregistered all these plugins from RR (they will be provided by plone.app.widgets anyway). So in develop mode your javascript must use requireJS to ask for its dependencies.
And you will not have the issue if you are using the compiled version of plone.app.widgets.
Remove selected portal tools from Plone
The past
Tools are parts of CMF. It was the common way to provide features on the low level purpose, like the the resource registry, …
You can find tools in the ZMI under the name portal_XXX. As a developer you can use getToolByName(context, 'portal_url') to get that tool. The idea is that a tool contains its own way to store things like properties, data or whatever needed. They provide an API to use them. They also provide management interface so you can configure them using the ZMI.
The future
For years now we have utilities (from the zope component architecture) which is the modern way to achieve this. Since we have a way to store configuration using plone.app.registry (which is a persistent utility) we would like to remove existing tools from the database.
Some of theses tools are part of Archetypes / ATContentTypes project which are now deprecated in favor of dexterity so we need to move them from Plone to ATContentTypes.
Some work was done in the past targeting Plone 3 to do that job, but all that work was removed during the release. Let's try again :).
To sum up a tool can be:
- AT related -> move them (portal_factory, portal_atct, ???)
- Persistence not needed -> move as a utility (portal_url)
- No longer used -> removed (portal_interface)
- Hard to migrate -> don't touch (portal_catalog,…)
For more information please check the proposal.
Let's remove portal_url!
I have decided to remove portal_url. But to know how to remove a tool you first need to know how it is used.
How to remove a tool
The different ways to get a tool are the following:
- In python (restricted or not): getToolByName(context, 'portal_url')
- In python (restricted or not): context.portal_url
- In template: context/portal_url
The good news is getToolByName tries to return a utility first, so it will cover the first use.
To support context.portal_url David Glick has proposed to add a computed attribute on the Plone site with a deprecated message. This is a good idea because it's easy to remove and it works as it was before.
To support context/portal_url in template the idea was to create a browser view.
Issue 1: Not allowed exception
After having done the job and trying to run the tests, many issues appeared when using portal_url in restricted python scripts.
To understand this you first need to understand how the security works. In a restricted python script, each object is wrapped and for any access to an attribute or a method, the wrapper checks if the current use can access it or not. If it can't, it raises a not allowed exception. To know that, Zope needs to be able to check on each level of the acquisition chain.
So I have changed the implementation to make it implements the IAcquirer interface using Implicit as base class.
In that case getToolByName adds your utility in the acquisition chain of the context and so everything is working.
Main_template rebirth
The past
The main_template is the template used to render all the pages of Plone CMS. This template suffers from many issues:
- It is located in portal_skins which is deprecated
- It is complex (caching headers, ajax_load, macro, slots, viewlets, …)
- It is often customized (hard coded things inside like the viewport meta tag)
- It is old HTML4
The future of the main_template
The idea of this proposal is to make Plone render semantic pages using HTML5 markup to be framework agnostic.
The technical main aspect is to make it a browser view.
My contribution to the main_template
I have joined Ramon to work on plip-13787-main-template and I have moved every hard coded stuff into viewlets:
https://dev.plone.org/ticket/13787#comment:4
- remove KSS macros (deprecated)
- global_statusmessage: provide a slot + viewletmanager and a BBB macro
- X-UA-Compatible header -> viewlet (viewletmanager httpheaders)
- global cache settings macro -> viewlet
- viewport -> viewlet
Conclusion
A lot of work has been done during this sprint to cleanup Plone from old and ugly technologies. The future is on the way to use only one technology for one purpose, remove the others and provide a consistent and modern CMS.