plone / plone.app.mosaic

Plone Mosaic main repository
https://pypi.python.org/pypi/plone.app.mosaic
GNU General Public License v2.0
35 stars 26 forks source link

Recommended CSS classes for mosaic-grid-row #593

Open mauritsvanrees opened 9 months ago

mauritsvanrees commented 9 months ago

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 and mosaic-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:

basic.html:        <div class="mosaic-grid-cell col">
basic.html:        <div class="mosaic-grid-cell col">
document.html:        <div class="mosaic-grid-cell col-12 mosaic-position-0">
document.html:        <div class="mosaic-grid-cell col-12 mosaic-position-0">
document.html:        <div class="mosaic-grid-cell col-12 mosaic-position-0">
news_item.html:        <div class="mosaic-grid-cell col-12 mosaic-position-0">
news_item.html:        <div class="mosaic-grid-cell col-12 mosaic-position-0">
news_item.html:        <div class="mosaic-grid-cell col-12 mosaic-position-0">

Is mosaic-position-0 still needed? A further search in Mosaic gives no result.

col or col-* 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 (nor col-*)? 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.

mauritsvanrees commented 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.")
petschki commented 8 months ago

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