Open mauritsvanrees opened 9 months ago
# Simplify mosaic-grid-cell classes in custom content layout.
#
# Run this with:
# bin/client1 run <path to script>
from io import StringIO
from lxml import etree
from plone.app.blocks.layoutbehavior import ILayoutAware
from plone.app.blocks.layoutbehavior import ILayoutBehaviorAdaptable
from plone import api
from pprint import pprint
from zope.component.hooks import setSite
import argparse
import sys
import transaction
parser = argparse.ArgumentParser()
parser.add_argument(
"--dry-run",
action="store_true",
default=False,
dest="dry_run",
help="Dry run. No changes will be saved.",
)
# sys.argv will be something like:
# ['.../parts/instance/bin/interpreter', '-c',
# 'scripts/script_name.py', '--dry-run', '--site=nl']
# Ignore the first three.
options = parser.parse_args(args=sys.argv[3:])
if options.dry_run:
print("Dry run selected, will not commit changes.")
def commit(note):
print(note)
if options.dry_run:
print("Dry run selected, not committing.")
return
# Commit transaction and add note.
tr = transaction.get()
tr.note(note)
transaction.commit()
parser = etree.HTMLParser()
cell_xpath = etree.XPath('.//div[contains(@class, "mosaic-grid-cell")]')
site = app.Plone
print("")
print("Handling Plone Site %s." % site.id)
setSite(site)
changed_any = False
catalog = api.portal.get_tool("portal_catalog")
for brain in catalog.unrestrictedSearchResults(object_provides=ILayoutBehaviorAdaptable.__identifier__):
obj = brain.getObject()
layout = ILayoutAware(obj)
custom = layout.customContentLayout
if not custom:
continue
print("")
print(f"Checking Mosaic custom content layout of {obj.absolute_url()}")
changed = False
input_file = StringIO(custom)
tree = etree.parse(input_file, parser=parser)
for div in cell_xpath(tree):
# We always have 'mosaic-grid-cell' in here: this is what we searched for.
# We should have 'col' in here as well, or col-12.
# Possibly mosaic-position-0.
# The rest is not wanted, at least not mosaic-position-* or mosaic-width-*.
old_classes = div.attrib["class"]
new_classes = []
for klass in old_classes.split():
if klass in ("mosaic-grid-cell", "col", "mosaic-position-0"):
new_classes.append(klass)
continue
if klass.startswith("col-"):
new_classes.append(klass)
continue
if klass.startswith("mosaic-width"):
# print(f"Removing class '{klass}'.")
continue
if klass.startswith("mosaic-position"):
# print(f"Removing class '{klass}'.")
continue
# The rest we add, but we warn.
print(f"Keeping unknown class '{klass}'.")
new_classes.append(klass)
if "mosaic-grid-cell" not in new_classes:
new_classes.insert(0, "mosaic-grid-cell")
if "col" not in new_classes and "col-12" not in new_classes:
new_classes.append("col")
new_classes = " ".join(new_classes)
if old_classes != new_classes:
changed = True
# print("Changed classes:")
# print(f"Old: '{old_classes}'")
# print(f"New: '{new_classes}'")
div.attrib["class"] = new_classes
if changed:
changed_any = True
print(f"Made changes for {obj.absolute_url()}")
new_custom = etree.tounicode(tree, method="html")
layout.customContentLayout = new_custom
if changed_any:
print("Committing...")
commit("Simplified customContentLayout of Mosaic pages.")
else:
print("No changes.")
I also made a similar script and thought about an upgrade step. But it later got very project specific, so I didn't post it here. But in general the mosaic-position-
classes are not used anymore and the col
class is added to every column to enable "auto-column" behavior in general, when you didn't customize the col widths in the editor.
We could think of updateing these "standard" classes in version 2.x
to their corresponding Bootstrap class (https://github.com/plone/plone.app.mosaic/blob/2.2.5/src/plone/app/mosaic/browser/static/css/mosaic.grid.less#L103):
.mosaic-width-full -> .col-12
.mosaic-width-half -> .col-sm-6
.mosaic-width-quarter -> .col-sm-6 .col-lg-3
.mosaic-width-three-quarters -> .col-sm-6 .col-lg-9
.mosaic-width-third -> .col-sm-6
.mosaic-width-two-thirds -> .col-sm-6 .col-lg-8
I have a site with Mosaic that started out on Plone 5.1, and was migrated to 5.2 and 6.0. It has a few custom content layouts that have classes that don't seem to do anything and that don't result in any matches in Mosaic code, nor custom code for this site. These are classes like
mosaic-width-half
andmosaic-position-leftmost
that were set by a previous Mosaic version.So I started wondering which classes are expected next to
mosaic-grid-cell
. When I search in Mosaic itself in the content layouts, I get this:Is
mosaic-position-0
still needed? A further search in Mosaic gives no result.col
orcol-*
seem fine, and help for Bootstrap 5.When using the Format menu, I can add
mosaic-grid-row-fluid/dark
. This can be expanded with custom code. And in issue #478 there is a discussion on which classes to add here in a way that works responsively.I guess if there are classes that do not do anything, then it does not hurt, except that it can get confusing for anyone who looks at the html.
Main question: does it make sense to write an upgrade step for this, removing some no longer supported classes and adding some new, especially
col
when it is not there (norcol-*
)? Or would this be something that is very project specific and does not translate well to a general Mosaic upgrade step? I will share a script in the next comment.