Generic fields component
2012-06-28, 18:22 by Jonas Wallden in RXML/XSLT
One little-known feature of Roxen CMS is that component-based pages can include components declared entirely in XML/XSLT without the need for a corresponding Pike module. This is ideal for parameters or settings that non-programmers should have easy access to.
The idea is that you place these components on an internal page that can be seen in the Insite Editor environment but that is hidden from external visitors, e.g. using the External Visibility property. The page can then be modified and published using familiar actions.
You will need Roxen CMS 5.0.443 or newer to find the necessary module, though older versions should run it just fine if you copy the Pike module.
Creating a fields component
To begin using this functionality, add the Generic Fields component to the site configuration. Since the Variant field of these components rarely make sense I also suggest that you disable it in the Settings tab right away. (If left enabled you will later see a rather ugly popup menu in the editor unless you also define a dummy default variant choice.)
Next, let's start with a sample parameter block. Create a file /my-params.xml and assign it the CMS Page Editor content type as you would with any regular component-based XML file. In the Content Editor, select the Edit as XML command to edit the raw code and add the following:
<fieldA rxml:edit-type="string">this is a string</fieldA>
<fieldC rxml:edit-type="checkbox" rxml:edit-title="Enable C">1</fieldC>
<fieldD rxml:edit-type="select" rxml:edit-options="0:Zero,1:One,2:Two">2</fieldD>
Save the file and switch to the Insite Editor and edit the page again. You should see something like this:
Since we have not yet associated an XSL template the preview is rather boring, but let's ignore that for a moment. Click the Generic Fields button to open the edit form instead:
You can now see that a fully functional component editor has been created from the attributes in the <fields-component> element children. Also note that the Delete button is disabled automatically since we don't want users to accidentally remove the parameter data (cut/paste and insert are disabled for the same reason).
The explanation for this magic can be found in the rxml:edit-* attributes. The rxml:edit-type attribute is required to determine the kind of input widget to show – you can read about the possible values in the CMS developer documentation. An optional title (rxml:edit-title) will take precedence over a field title that otherwise comes from capitalizing the XML tag name.
Previewing field data
Once the basic editing is in place you might want to improve the user experience a bit. Let's create an XSL stylesheet that can present the parameters nicely and also offer an edit button from a page context.
To do this, edit /cms-components.xsl and add an import statement at the end of the existing code:
and continue by creating that XSL file and inserting this code:
<div style="padding: 8px; margin: 0 0 16px; border: 1px solid #ccc">
<p><b>Field A: </b><xsl:value-of select="fieldA"/></p>
<p><b>Field B: </b><xsl:value-of select="fieldB"/></p>
<p><b>Field C: </b><xsl:value-of select="fieldC"/></p>
<p><b>Field D: </b><xsl:value-of select="fieldD"/></p>
Once saved you can browse back to the /my-params.xml file in the Insite Editor and you'll see that the existing fields are displayed in a much improved manner together with an Edit shortcut:
Handling multiple component instances
Since all instances of the Generic Fields component will go through the same template code I'm identifying each instance with a custom XML attribute: use="my-params-1". The XSL template can then test on this in the match pattern using [@use = 'my-params-1'] to make sure it's being called for the correct component instance. This works because the CMS page editor always preserves unknown attributes when it updates the XML data so my identifier will remain in place.
Of course the XSL code could be made a lot more fancy to handle many different components at once, possibly even detecting the rxml:edit-type value and rendering each field in a suitable way.
Accessing your fields
The remaining part of the puzzle is to access the fields and let them control some behavior of your site. The meaning and purpose of your fields will naturally be up to you to decide, and exactly how you incorporate them will vary. However, the simplest method is to load them in an XSL transformation:
<xsl:variable name="my-params-1" select="document('/my-params.xml')/fields-component[@use='my-params-1']"/>
<xsl:variable name="my-color" select="$my-params-1/fieldB"/>