Last active
May 21, 2024 19:43
-
-
Save cdw9/238c4e8b296264c21dd98e7295d202b4 to your computer and use it in GitHub Desktop.
Mosaic Link Integrity - A subscriber that will gather all links and references from tiles to store them and properly connect the objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<subscriber | |
for="plone.dexterity.interfaces.IDexterityContent | |
zope.lifecycleevent.interfaces.IObjectModifiedEvent" | |
handler=".events.modifiedMosaic" | |
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Acquisition | |
from plone import api | |
from plone.app.blocks import layoutbehavior | |
from plone.app.blocks import utils as blocks_utils | |
from plone.app.linkintegrity.handlers import ( | |
check_linkintegrity_dependencies, | |
getObjectsFromLinks, | |
updateReferences) | |
from plone.app.linkintegrity.parser import extractLinks | |
from plone.tiles.interfaces import ITileDataManager | |
from plone.transformchain import zpublisher | |
from repoze.xmliter import utils as xmliter_utils | |
from six.moves import urllib | |
from Testing.makerequest import makerequest | |
from zope import interface | |
# tile fields to check | |
# 'richtext': is a RichTextValue object | |
# 'reference': uses RelatedItemsFieldWidget, is a UID | |
# 'path': uses LinkFieldWidget, is a path | |
TILE_FIELDS = { | |
'text': 'richtext', | |
'cta_text': 'richtext', | |
'banner_desc': 'richtext', | |
'content': 'richtext', | |
'image': 'reference', | |
'cta_link': 'path', | |
'button_link': 'path', | |
} | |
def getObjTiles(obj): | |
""" get all tiles from a Mosaic object """ | |
request = obj.REQUEST | |
lookup = layoutbehavior.ILayoutAware(obj, None) | |
layout = lookup.content_layout() if lookup else None | |
encoding = zpublisher.extractEncoding(request.response) | |
serializer = xmliter_utils.getHTMLSerializer( | |
[layout], encoding=encoding) | |
app = makerequest( | |
Acquisition.aq_base(obj.getPhysicalRoot())) | |
interface.alsoProvides( | |
app.REQUEST, *interface.providedBy(request)) | |
tiles = [] | |
for tileNode in blocks_utils.bodyTileXPath(serializer.tree): | |
data_tile = urllib.parse.urlsplit( | |
tileNode.attrib[blocks_utils.tileAttrib]) | |
tile_path = data_tile.path[2:] | |
tile = obj.restrictedTraverse(tile_path) | |
dataManager = ITileDataManager(tile).storage | |
if getattr(dataManager, 'tile', None): | |
tiles.append(dataManager.tile) | |
return tiles | |
def getTileLinks(tile): | |
""" return a set of links as paths and a set of RelationValue objects """ | |
tile_links = set() | |
for field in TILE_FIELDS.keys(): | |
value = tile.get(field, None) | |
if not value: | |
continue | |
type = TILE_FIELDS[field] | |
if type == 'richtext': | |
if getattr(value, 'raw', None): | |
value = value.raw | |
tile_links |= set(extractLinks(value)) | |
elif type == 'reference': | |
try: | |
ref_path = ("/").join(api.content.get(UID=value).getPhysicalPath()) | |
except Exception as e: | |
continue | |
tile_links.add(ref_path) | |
elif type == 'path': | |
tile_links.add(value) | |
return tile_links | |
def modifiedMosaic(obj, event): | |
""" a Mosaic object was modified | |
this is based on plone.app.linkintegrity's modifiedContent | |
""" | |
if 'layout' not in obj.defaultView() or not check_linkintegrity_dependencies(obj): | |
return | |
tiles = getObjTiles(obj) | |
links = set() | |
for tile in tiles: | |
tile_links = getTileLinks(tile.data) | |
links |= tile_links | |
refs = getObjectsFromLinks(obj, links) | |
updateReferences(obj, refs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment