Plone integration with Volto blocks
9. Plone integration with Volto blocks#
When developing for Volto websites, don't neglect the server-side, Plone. Beyond the regular endpoints and expanders that plone.restapi offers, there's a few dedicated features that can improve the quality of Volto-powered websites.
9.1. Block transformations#
The main feature that applies to Volto blocks is called the "blocks transformers". They are adaptors that can be registered per block type. They can alter the output on serialization (when the fetching information from Plone), as well as on deserialization (when information arrives in Plone, from the client).
@implementer(IBlockFieldDeserializationTransformer) @adapter(IBlocks, IBrowserRequest) class DatabaseQueryDeserializeTransformer(object): order = 100 block_type = 'database_listing' def __init__(self, context, request): self.context = context self.request = request def __call__(self, value): value["items"] = db.query(value) # pseudo code return value
Then register it as a subscription adapter:
<subscriber factory=".blocks.DatabaseQueryDeserializeTransformer" provides="plone.restapi.interfaces.IBlockFieldDeserializationTransformer"/>
Note that you'll probably want to also register the reverse.
9.2. Smart fields#
It is possible to register a generic block transformer that applies to all block types. By doing so we can process block information consistently for all blocks, providing us with the "smart fields" concept.
A "smart field" is a convention: "all block fields named
url will be
transformed on serialization/deserialization, to store them with a resolveuid".
9.3. Searchable text from blocks#
@implementer(IBlockSearchableText) @adapter(IBlocks, IBrowserRequest) class ImageSearchableText(object): def __init__(self, context, request): self.context = context self.request = request def __call__(self, block_value): return block_value['alt_text']
This adapter needs to be registered as a named adapter, where the name is the
same as the block type (its
@type property from the block value).
<adapter name="image" factory=".indexers.ImageBlockSearchableText" />
Examples of potential smart fields:
_v_*blocks, to provide volatile data from the backend
blob, which would deserialize base64-encoded binary data to an attachment store, then serialize back as a simple download link
These smart fields don't exist right now. But it would be great if they did exist.