Render widgets from own code
CPSSchema's allows to render automatic pages for edit, create or view objects, based on defined portal_layouts. But, how we can render directly the widgets in theese layouts, so we can write our own page template ? Using KMKey it's simple, just inherit your view from Products.KMKeyCore.baseview.KMKeyBaseView, and use the renderWidget function:
def renderWidget(self, layout_id, widget_id, proxy=None, content=None,
portal_type=None, mode='view'):
"""
Function to render a specific widget
- layout_id and widget_id are mandatories
- if proxy or content aren't None, then use them to obtain a datamodel
- Either, portal_type should be passed to obtain an empty datamodel
- mode could be 'view' or 'edit'
"""
Used from a page template this way:
<div tal:content="structure python:view.renderWidget(layout_id='metadata', widget_id='w__Description', proxy=item)" />
If you prefer do it yourself, you can use something like this:
from Products.CPSSchemas.DataStructure import DataStructure
mode = 'edit' # Could also be 'view'
portal_type = 'KMKey Project' # The portal_type ID from portal_types
layout = 'kmkey_planning'
widget_id = 'w__end'
dm = cps.portal_types[portal_type].getDataModel(None)
ds = DataStructure(dm, datamodel=dm)
widget = cps.portal_layouts[layout][widget_id]
widget.prepare(ds)
widget.render(mode, ds)
The previous code works to obtain an empty widget. If we want to obtain the widget filled with data of an existing object, we simply should obtain its datamodel:
dm = proxy.getContent().getDataModel()