HTML manipulation and transformations

Description

How to programmatically rewrite HTML in Plone.

Introduction

It is recommended to use the lxml library for all HTML DOM manipulation in Python.

Plone is no exception.

Converting HTML to plain text

The most common use case is to override SearchableText() to return HTML content for portal_catalog for indexing.

Converting plain text to HTML

You can use portal_transforms to do plain text -> HTML conversion.

Below is an example how to create a Description field rendered with new line support.

Register the view in configure.zcml:

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    xmlns:plone="http://namespaces.plone.org/plone"
    i18n_domain="example.dexterityforms">

    ...

    <browser:page
        name="description-helper"
        for="*"
        class=".description.DescriptionHelper"
        permission="zope2.View"
        />

</configure>

Create a file description.py and add the following code:

from plone import api
from zope.interface import Interface
from Products.Five.browser import BrowserView


class DescriptionHelper(BrowserView):
    """
    A helper view which exports dublin core description w/new line support
    allowing several paragraphs in Plone's description field.
    """

    def render(self):
        """
        Get a content item description w/new line support.

        Transform hard lines to breaks in HTML.
        """

        # Call archetypes accessor
        text = self.context.Description()

        # Transform plain text description with ASCII newlines
        # to one with
        portal_transforms = api.portal.get_tool(name='portal_transforms')

        # Output here is a single <p> which contains <br /> for newline
        data = portal_transforms.convertTo('text/html', text, mimetype='text/-x-web-intelligent')
        html = data.getData()
        return html

Now you can do in your page template

<metal:main-macro define-macro="main">

    <div tal:replace="structure provider:plone.abovecontenttitle" />

    <h1 metal:use-macro="here/kss_generic_macros/macros/generic_title_view">
        Title or id
    </h1>

    <div tal:replace="structure provider:plone.belowcontenttitle" />

    <div class="documentDescription">
       <tal:desc replace="structure context/@@description-helper" />
    </div>

    ...

More info