I wrote an alternative embed tile for a customer last year and now I need it again. The current embed tile was not sufficient in both case.
It is very simple and provides a tile with 100% width in its row, aspect ration kept, settings kept. You just need to paste the Youtube embed code into a text field.
This could be extended for similar video embeds (Iframe based).
Here is the code
from plone.supermodel.model import Schema
from plone.tiles import Tile
from zope import schema
from lxml import etree
from lxml import html
import logging
logger = logging.getLogger(__name__)
class IYTEmbedTile(Schema):
"""Youtube Embed tile."""
media_embed = schema.Text(title="Youtube Media Embed code", required=True)
class YTEmbedTile(Tile):
"""A tile that embeds Youtube."""
def __call__(self):
# parse embed code
embed_code = self.data.get("media_embed")
try:
parsed = html.fromstring(
'<div class="youtube-responsive-wrapper">{}</div>'.format(embed_code)
)
except Exception:
logger.exception(f"Embed parsing problem with:\n{embed_code}")
return "<div>Malformated embed code</div>"
children = parsed.getchildren()
if not (
children
and len(children) == 1
and children[0].tag == "iframe"
and "src" in children[0].attrib
and "youtube" in children[0].attrib["src"]
):
return "<div>Invalid embed code (no iframe)</div>"
iframe = children[0]
if not ("height" in iframe.attrib and "width" in iframe.attrib):
return "<div>Invalid embed code (measures missing)</div>"
try:
height, width = int(iframe.attrib["height"]), int(iframe.attrib["width"])
except Exception:
return "<div>Invalid embed code (measure no numbers)</div>"
del iframe.attrib["height"]
del iframe.attrib["width"]
parsed.attrib["style"] = f"padding-bottom: {(height/width)*100}%"
new_iframe = etree.tostring(parsed, pretty_print=True).decode("utf8")
return f"<html><body>{new_iframe}</body></html>"
ZCML:
<!-- ytembed tile -->
<plone:tile
name="kup.tiles.ytembed"
title="YT Embed"
description="Paste an Youtube embed code and get an tile-width video"
for="*"
schema=".ytembed.IYTEmbedTile"
class=".ytembed.YTEmbedTile"
permission="zope2.View"
add_permission="cmf.ModifyPortalContent"
/>
To not forget about it I create this issue. FTR:
I wrote an alternative embed tile for a customer last year and now I need it again. The current embed tile was not sufficient in both case. It is very simple and provides a tile with 100% width in its row, aspect ration kept, settings kept. You just need to paste the Youtube embed code into a text field.
This could be extended for similar video embeds (Iframe based).
Here is the code
ZCML:
Styles:
Also some
registry.xml
was needed: