Weblog

published Nov 03, 2021, last modified Nov 04, 2021

State of the Plone Community

published Oct 12, 2022

Keynote on Wednesday at the Plone Conference 2022 by Erico Andrei.

Thank you Imio and Affinitic for organising this conference. Special thanks to Martin Peeters and Joël Lambillotte who lead these companies.

Plone is multiple things:

  • a product and api
  • a community
  • a foundation (organisation)

For the first part, our four release managers will talk about it in the keynote on Friday. As Plone Foundation president I will talk about the first and second parts.

The Plone community is global, online, open source, multilingual. We started as an online community: Alan Runyan and Alex Limi started Plone by talking on IRC, which is how old people like me used to communicate.

A good part of Plone is that we are truly open source and free. There is no big company behind it that can remove parts of the software or suddenly start asking money for it.

Plone started from the Zope community. Other communities came from Plone, like Guillotina, with people still here at the conference today.

In my home country of Brazil, the Plone community was started before the Python community. The first seven Python conferences in Brazil were organised by the Plone community.

I was welcomed into the global Plone community by people like Jens and Hanno, which was impressive to me. But mostly I thought: hey, these are nice, normal people, that you can talk to.

The community will embrace you. The community will help you overcome your fears, like I had of running for the Plone board.

I had two role models: Dorneless Treméa and Jean Ferri. They left us way too early in life. What I learned:

  • Lead by example. No one wants to organise a conference? Let's do it.
  • Be generous with your time.
  • Help people.

How can you help when you are not a developer, but a user?

  • Ask questions on community.plone.org.
  • Help with documentation. Thank you Katja Süss and Steve Piercy for doing a lot of work here. I am nervous when I add documentation because English is not my native language. Don't worry, Steve will fix it for you.
  • Translate Plone in your language.
  • Make designs for Plone. Maybe a nice photo to go with a news item.
  • Share your experience.
  • Work with issues, do code review. The past week or so, on every issue or pull request in Plone, there was a comment from either David Glick, Alessandro Pisa or Wesley Barroso.
  • Spread the word, like Rikupekka Oksanen.
  • We had Google Summer of Code students this year: Bhutan R J, Avi Mishra, Md Sahil, Robot Singh, helped by Eric Brehault and others.

Plone Foundation

The Plone Foundation is an organisation that supports the community. We promote and protect Plone. We are the legal shield for threats, or preventing companies taking over Plone, or saying they are the largest. We support community meetings and sprints. We had the World Plone Day, with lots of video content.

If you want to organise a sprint or a meeting in your region, talk to us. We can help with money or with organisation.

We had ten new Foundation members the last twelve months. I know most people here who are no members have imposter syndrome: I am not good enough. That is not true. That you are here is proof enough. Nominate yourself.

You can sponsor Plone.

Please consider joining the Plone board.

We are a diverse community. If your English is bad, you are still welcome in our community. We don't have enough women here, or people from the south of the planet.

We need to generate more content. Do a podcast, a video, a success story. In your language.

We need more events. They don't have to be big. Just a local meetup. We need to present the software and the community in other places, like Pycon or React conferences. We are going to have a new version of the Plone Symposium in Brazil, on November 18, 2022.

World Plone day will be April 26, 2023. It is great if you organise a local meeting that day.

I see that a lot of people are here at a Plone conference for the first time. There are young people here. People leave the community, others join, some come back after a while. The Plone community stays with you even after you leave.

David Ichim: What's new in Plone 6 frontend for developers

published Nov 08, 2021

Talk by David Ichim at the online Plone Conference 2021.

Distilled from the latest work done in Volto, we're showcasing some patterns, features, or enhancements that have landed in Volto from the last year to the present. We will also have a glimpse of what is ahead in the future of Volto with the new features roadmap.

In the past year we had four major releases, 40 minor releases, 36 alpha releases, 25 patch releases, for a total of 105 releases. Plus some new tooling and tool releases, like plone i18n and plone generator.

New Volto config, dubbed as Volto's Configuration Registry, introduced to fix circular import dependency problems. Hot Module Reloader was fixed. Read the upgrade guide.

New i18n (internationalisation) infrastructure. This is now a separate package. Same is used for generation of i18n in add-ons.Read the upgrade guide.

Forms as schema. Forms should be constructed from schemas instead of by hand. InlineForm allows us to create forms for blocks from a schema. Blocks can have variations, or we can extend it. Read the edit component documentation.

New widgets:

  • Object List Widget. Similar to the original DataGridField. Used in core by the Search Block facets.
  • Object Browser Widget is now a separate widget, instead of part of a block, and now allows the addition of external content.
  • Querystring Widget. Behaves like its counterpart from plone.app.querystring. Allows to create search criteria, used by the search block.
  • URL Widget. Used on text inputs, it knows to validate their value as a url, both internal and external.
  • Vocabulary Terms Widget for a JSONField, acts as a source for a SimpleVocabulary or Choice field. Play with it in the storybook.

New core blocks:

  • Search block
  • Teaser block (ongoing work).

Pluggable framework, similar to React's Portal component. See the talk by Tiberiu and see the Pluggables development recipe.

Storybook provides a sandbox to build and test visual components in isolation. Currently it is only setup to be used by Volto core. We need help with work to have storybook setup with adding. See the Storybook talk held by Victor, and see the storybook itself.

Critical CSS: inline the critical CSS for improved performance. Run critical-cli to output critical.css. This is then inlined in the headers, while regular CSS is moved to the bottom of the body. See the deployment documentation.

Lazy Loading utilities. Introduced injectLazyLibs HOC wrapper to inject lazy-loaded libraries as properties to your components. These components are only loaded once all your main libs are loaded.

Express.js middleware. Volto uses this for SSR and static resources serving. You can now write custom middleware and add it to settings.expressMiddleware.

API expanders allow the expansion of different API endpoints from Volto with calls from your custom endpoints. Avoid adding too many expanders if they are not critical to the initial page.

External routes: useful when another application is published under the same top domain as Volto. If Volto would fetch the content for that path, it will break. You can disable this path in config.settings.externalRoutes. You can also use regular expressions.

Seamless mode, introduced in Volto 13, enhanced in Volto 14, which has already seen a lot of alpha releases. Originally, we tried to unify both frontend and backend servers under the same path, but this was tricky, causing various problems. We settled on a new ++api++ traversal for getting information from the backend. Also, to come closer to zero config, you can now pass environment variables at runtime instead of build time. This means you can generate one build, and use this in all environments (testing, production). Read the deployment documentation.

Context navigation component. This is a navigation portlet component, similar to Classic Plone. The view is there, but you need to enable it. See the development recipe.

There is some work in progress:

  • Slots are Volto's answer to portlets, see the Volto Slots talk by Tiberiu Ichim for more details.
  • Image proxy: image scale generation done by a middleware instead of plone.scale.
  • Authentication from backend.
  • Replace Draft.js editor with Volto Slate. What is missing is a migration tool from one to the other. But work has started on a block conversion tool.
  • Async blocks that work with SSR.
  • Defaults in blocks form.

Future work:

  • Defaults in all widgets
  • Enable blocks enhancers in all blocks
  • Storybook in add-ons
  • Use newest react-intl package
  • Refactor the folder contents component
  • Form editing text enhancements, making it easier to modify text inputs.
  • A "group block" included with Volto
  • Quanta toolbar

I did nothing, I just brag about what others have done. So thank you Volto early adopter community!

Tiberiu Ichim: Volto Pluggables

published Nov 08, 2021

Talk by Tiberiu Ichim at the online Plone Conference 2021.

This presentation is an introduction to the new Volto developer-targeted feature, the Pluggables framework. It is more an argument for extensibility in CMS UI and in Volto.

Basically, with Pluggable a central component provides a pluggable slot that other components can fill, like this:

<div className="toolbar">
<Pluggable name="toolbar-main" />
</div>
// ...
<Plug id="quicklinks" pluggable="toobar-main">
<Button />
</Plug>

This is a Volto port of https://github.com/robik/react-view-slot.

The big picture:

  • I work with Eaudeweb Romania
  • Our client EEA is an early adopter of Volto
  • The strategy is: move everything to Volto
  • But the EEA sites are less brochure, the CMS side is really strong.
  • We build powerful UIs for power users.
  • The EEA already has 91 Volto repositories on GitHub. How can we scale that? Can we write an add-on to make it easier to write an add-on?

In React, data flow is top to bottom. A parent component passes properties to children and children communicate with the parent by emitting events. This makes sense and works well. For "out of tree" data you need Redux. There is no protocol for add-hoc communication between components.

UI state is fluid. Extensibility means reusability and scalability. This is hard. You need to design upfront. Plone backend uses the Zope Component Architecture, which means pluggability is baked in, it is very natural. You can view Pluggables as viewlets-on-demand, but they are really not. But yes, you can think about a Pluggable as a viewletmanager and a Plug as a viewlet.

You can overwrite a Plug with a Plug, by registering it with the same id. So if the original Plug gives you color blue, you can overwrite it with color red.
You can do custom rendering of Plugs within your Pluggable, by iterating over all Plugs and for example wrapping each in a div with a class name.

Showcase: volto-workflow-progress (main toolbar plugin) and volto-editing-progress ("sidebar" for plugin).

Limitations:

  • No Server Side Rendering
  • Watch out for dependency lists.
  • Limited adoption for now.

Implementation in pseudocode:

First the context:

<PluggablesProvider>
<Pluggable name="top" />
<Plug name="delete" />
</PluggablesProvider>

Then the dumb version of the Plug:

const Plug = ({id, children}) => {
const { register } = useContext(PluggablesProvider.Context);

React.useEffect(() => {
register(id, () => children);
});

return null;
}

Takes a bit of study, but in the end it is not so hard.
The Pluggable becomes a bit simpler:

const Pluggable = (name) => {
const { getPlugs } => useContext(PluggablesProvider.Context);
return getPlugs(name).map(f => f());
}

Eric Bréhault: AbFab! Come back to easy frontend development

published Nov 08, 2021

Talk by Eric Bréhault at the online Plone Conference 2021.

My talk from last year, presented on a T-shirt, was about second-guessing the SPA pattern, or Single Page App. After this year's introduction with T-shirts, I come again with a T-shirt thing, showing: AbFab: Absolutely Fabulous. It refers to the comic show from the nineties. British humor was always an inspiration for the Plone community. Or is it Spanish? Ab fab, away from the factory.

In the zeroes, the question was: why do I use 5 different jQuery versions on my page?
In the tens: why 5 different JS frameworks?
In the twenties it is just: WHYYYYY?
If you don't have the most recent problem, you are a big loser.

What if I want something simpler? Back in the nineties you had good British TV shows, and easy web development. HTML is still fabulous. HTML contains content.

Components are contents too, which is good. JS frameworks use this a lot. Idea of AbFab: push this to the backend.

Use a tree of components and subcomponents, like a filesystem with folders.

You request /polls/poll1.
You get HTML, json, a few components.
You then request /polls/poll2.
You have the HTML already, so you just needs the json, and we already have most components, so we only need for example one extra.
Updated component: serve a new version, and all pages will use it.

You have no bundles. You just serve separate components, which are dynamically loaded as dependencies.
Your browser can do that.

Low code.
I use Svelte for this. In the basis, you simply write HTML. <h1>Hello world!</h1> is a valid Svelte component. In React or Angular it is harder. In Svelte, if you need css, use a <style> tag. Need javascript? Use a <script> tag. To use another component:

<script>
import Hello from `./hello.svelte`;
</script>
<Hello></Hello>

So what is AbFab doing?
A component is stored in Guillotina, together with a compiled version.
Data in Guillotina is linked to a component.
Ask for the data, you get the needed components.
It will be tons of requests, but they will be small, and via HTTP/2 this goes quite fast.
We are using Guillotina at its finest, good for storing lots of small things in a hierarchy.

Low deployment.
My way to make it simple: Docker.

Low build.
I don't want npm installed, or webpack. At some point you do need it. I know this guy who edits CSS on GitHub, then has to wait 30 minutes for it to deploy, because it is too painful to build on his laptop. How to do this? Through The Web. Yes, it is naughtly, maybe forbidden, but I like it: the ability to change yourself.
I am 47 and have to accept who I am.
I am Eric.
I like Through-The-Web-shit.

The core of AbFab is about 200 lines. The editor is bigger.

Using an IDE is fine too. You can sync with the database. I make sure that the code I do is consistent with the documentation I am writing.

What is it good at? Small applications, like we would have done with Plomino previously. To be honest, for now I just made this for fun, so I don't care what it is good at.

Is it totally stupid? I made some disputable choices there. But it is about 200 lines frontend, 300 backend, so it can't be that bad.

Site updated from Plone 2.5 to Plone 6.0

published Nov 04, 2021

It only took ten years of making plans.

I am one of the Plone Release Managers, and have been working on Plone 6, which is now in alpha stage. But my personal website was still using the ancient Plone 2.5:

Screenshot of my website end of October 2021: still Plone 2.5

Often I have made plans to update my site to:

  • Plone 3
  • Grok
  • Plone 4
  • Plone 5
  • Plone 5.2
  • finally Plone 6

Long ago it was clear to me that an inline migration would not be practical. It would take too many steps: update the code to Plone 3.3, migrate the data, to Plone 4.3, migrate data, to Plone 5.2 Python 2.7, migrate data, Plone 5.2 Python 3, migrate data, Plone 6, migrate data.

Additionally, the question was how to handle the weblog, which is the main content. This was using Products.Quills, a Plone add-on for blogs. Updating to Plone 3 could have worked at the time, but this was made harder by some some custom code I added. This enabled me to use it as a podcast. I used this to enrich some of my summaries of sermons from my church with the actual audio of the sermon. I doubted whether to even include this content in Plone 6, as the last sermon was from 2008. I hate breaking links, so I kept it, although a bit hidden.

Another point that needed some extra attention, was that most, if not all, blog entries were not written in html, but in ReStructuredText. I make a lot of summaries of talks when there is a Plone Conference. The html editor on Plone 2.5 did not work anymore, or I disabled it to a simple textarea. I always open up the same text editor that I use for programming (previously Emacs, currently VSCode), and type the summary there. I much prefer writing ReStructuredText there, especially when I simply need text without any markup. I then paste it in Plone, without fear of losing all my work when my internet connection dies.

Lastly, I have an RSS/atom feed which is used by planet.plone.org and maybe others to stay updated when I add a new blog entry. I did not want this url to change.

Anyway, about six years ago I decided that I would use collective.jsonify to export my site, and then import it using transmogrifier. But time passed without any progress. This year, collective.exportimport was shaping up to be the preferred way to import the data. For export you can use it in Plone 4.3 as well, but definitely not in Plone 2.5.

At the beginning of this week I looked at jsonify. Didn't I have a local copy of my website on my laptop, with collective.jsonify installed? No! And it was not installed on the live site either. And installation would be hard, because the site uses Python 2.4, and currently you cannot even reach PyPI with older versions of Python 2.7.

Mildly panicked, I started on a custom script to export the content, still as json. Some details aside, this actually was not so hard. I looked at what collective.exportimport expected, and created the Python list of dictionaries accordingly. Then do a simple json.dumps() call and you are done. Except that this gave an ImportError: the json module is not available in Python 2.4. Okay, install simplejson package. But you need PyPI access for that, which does not work. Workaround:

  • Manually download an egg of Python 2.4-compatible simplejson 1.7 and save it in the buildout directory.
  • cp bin/instance bin/instance-json
  • Edit the new script and add the simplejson egg to the system path.
  • bin/instance-json run export_mvrsite25.py

After that, it was not too hard anymore. I used plonecli to create a new add-on with Plone 6.0.0a1. I actually do not yet use the add-on code, except for loading a minor patch that I added, but this gave a reasonable, modern Plone 6 buildout. Create a Classic Plone site, tweak a few settings (let Folder use folder_workflow, allow English and Dutch, navigation depth 1, enable syndication, configure caching and mail), import the content with collective.exportimport, edit a bit, and done.

The weblog now consists of standard Folders and Pages. To improve the view, I added a Collection, showing the latest pages first, and showing all content of the last seven blogs. I enabled syndication here, so it has an RSS/atom feed.

The weblog has always advertised two atom feeds:

  1. One for all weblog entries, at https://maurits.vanrees.org/weblog/atom.xml
  2. One for weblog entries with keyword 'plone' at https://maurits.vanrees.org/weblog/topics/plone/@@atom.xml

In the new site, the first one kind-of worked out of the box, but it only showed the items that were directly in the weblog folder, and this is not where my weblog entries are. I solved this with a patch to Products.CMFPlone.browser.syndication.views.FeedView: when atom.xml is viewed on a folder, check if it has a default page, and show the atom.xml of this default page instead. In this case, the default page is a Collection with the correct settings. So the general feed will keep working.

For the second one, my first idea was to create a folder 'topics' and within it a Collection with id 'plone'. Problem: 'plone' is a reserved word and cannot be used as id of a content item, so the id became 'plone-1'. Solution here: create the 'plone-1' collection directly in the weblog folder, and do a redirect in the frontend server (nginx):

 rewrite ^/weblog/topics/plone/@@atom.xml /weblog/plone-1/atom.xml last;

And that's it! My website is now on Plone 6.0.0a1:

Screenshot of Site overview in new site.

There are some more details that I could go into, like splitting up the buildout into multiple parts, with tox as main way to build everything, in preparation for moving more and more parts to pip-only. But that will have to be for another time.

Meanwhile: have a look around, and enjoy the fresh look!