Image scales wrongly regenerating

I had a problem with my Frankenstein stack of Plone 4 with various bits (core libraries) upgraded on it. Here’s a description of my bug: When I upload an image and try to use it in a Volto block that referenced its image scales download url (such as @@images/<random-uuid4>.jpg) the image URL didn’t work, it resulted in 404 error. When I reindexed the image in the catalog, then it worked. Now, the funky part is that I could reproduce the problem not only on my “doomed” Plone 4 stack, but also in the modern Plone 6 stack that we use for our main customer. [...]

Cleanup zc async

For my own reference, as I had to do a cleanup of zc.async tasks. The interface was too slow. bin/zeo_client debug queue = app._p_jar.root()['zc.async'][''] for i in range(len(queue)): queue.pull(0) [...]

Volto recipe for footer actions managed as site content

Managing the Footer as content is one of the common tasks on a Plone / Volto website. One typical approach is to designate some root folder, let’s say footer-links as a container for Link instances, and use those links as shortcuts to dedicated pages. So, a footer component may look like this: import React from 'react'; import { getContent } from '@plone/volto/actions'; import { useSelector } from 'react-redux'; import {UniversalLink} from '@plone/volto/components'; const Footer = () => { const footerLinks = useSelector((state) => state. [...]

Custom Volto configuration to fix Babel problems with react-leaflet

I’ve started working on a new Leaflet-powered Volto map block and the first thing that happened while loading react-leaftlet was an error reported by the browser: Module parse failed: Unexpected token (10:41) in @react-leaflet/core/esm/path.js ... const options = props.pathOptions ?? {}; ... The problem is that is, for some reasons, the transpiled JS bundle includes code using the nulish coalescing operator This is already a problem reported in react-leaflet and it happens because the distributed transpiled library includes that code. [...]

A Volto gotcha when dealing with async calls

Just some quick notes, in case this might help someone. After quite a bit of time and tests in trying to use asyncConnect to get data in a Volto component view (strictly focusing on the SSR side), I’ve realized that what I’m trying to do is not supported by the redux-connect library. In Volto, right now there are two components that use asyncConnect: App.jsx and Search.jsx. The purpose of asyncConnect is to have the server side rendered page “dynamic”, depending on the input from the originating request. [...]

Speedup volto razzle builds

I’ve been looking for a way to speedup Volto razzle/webpack builds, both while developing and for “production” mode, when building the final bundle. Fortunately, this solution exists and it’s extremely easy to integrate. Let’s define the problem, to see how to approach it: what is Volto actually? What do you get when you open, in your browser, a Volto frontend Plone website? To greatly simplify (and I hope I didn’t get anything wrong as I am not a Volto core developer): [...]

A quick and dirty mini-plugin system for Python

Inspired by Pyramid’s and venusian’s scan() call, I’ve reimplemented an auto-discovery system for plugins. The problem is simple. Suppose we want to “register” a series of functions that can run automatically, based on aspects set in the calling environment. The simples and easiest solution is something like: # in some module, as a global declaration: from somethingA import runner_A from somethingB import runner_B runners = [ runner_A, runner_B ] # then, maybe in some function: def main(): # . [...]

Identifying and fixing broken objects in a Plone website

I’ve removed plone.app.stagingbehavior from a website because the new plone.app.iterate has the same functionality. In addition, the p.a.s package was overriding adapters that I wanted to write. Now, my problem was that I could no longer save any related items, I would get an error: Module ZPublisher.Publish, line 138, in publish Module ZPublisher.mapply, line 77, in mapply Module ZPublisher.Publish, line 48, in call_object Module plone.z3cform.layout, line 66, in __call__ Module plone. [...]

My recipe for cronjobs with Docker

One of the bigger annoyances when it comes to bigger application stacks (such as the typical Plone/Zope) is dealing with cron jobs and, in general, async tasks. The problem is that of the number of “pieces”: having to deal with cron, in addition to the rest of the stack only increases the maintainance burden: it’s easy to forget that the stack needs to have cronjobs installed, etc. One way to avoid it is to include the cron jobs in the stack, with a buildout recipe. [...]

Running Pyramid with Flask, in the same Python process

Thanks to the wonders of WSGI and well behaved frameworks, it is now trivial to mix and match applications and have them run in the same Python process. Normally, in a production scenario, uwsgi would be used to split and map the URL spaces to different apps, but for development it is simpler to just use good old PythonPaste. In my case, I’ve wanted to have the RQ Dashboard (which is based on Flask) integrated with a Pyramid app that I’m working on. [...]