OU Campus components can create powerful interfaces behind the scenes while providing a simple interface for users to interact with. One of the more exciting things is that your components can export XSLT which can be interpreted by the translator when publishing.

One of the snippets UNC uses on their site is “Widget Anywhere.” As suggested, it takes any widget and places it on the page. For non-OU folks, a widget is roughly a simple include file. The snippet is clunky for the end user because it asks them for a relative path to a widget via copy and paste. This method can introduce errors in the page, including the file path mistyped, the include not published, or the table transformation being changed accidentally causing the XSLT to fail.

Here is an example of what this looks like for the end user:

Widget Anywhere Snippet

Only our more advanced users utilize this functionality, probably due to its difficulty.

Let’s use components!

Components can help solve the problems above because they can ask for a specific file path and verify that it exists. Here is the modal that the user sees :

Components for the user

When they click to browse for a widget, it takes them to the production server. The component inserts the path for the user. When they publish out the file, the widget is included.

Building the component

The component is simple to build. Create a new component with a single file chooser item. Set the label to Widget and add some helper text if you wish. This field should be required.

Create Component Basic Settings

Under the advanced tab, I set the Available File Types to htm since our widgets publish out with that extension. “Locked to Path” is turned off since we store widgets in multiple places. If you store all your widgets in /_resources/widgets then add that there. Finally, I set “Production” as the default since I want the user to choose a published file.

Create Component Basic Settings

Under the Source tab, add the following XML:

<component class="widgetAnywhere">
	<path></path>
</component>

Drag the Widget form element into the path node so it looks like this:

Create Component Basic Settings

XSLT

The component outputs XML on the page, which needs to be read by the XSLT processor. I created a new XSLT file for components which I referenced from common.xsl but that is up to you.

<xsl:template match="component[@class='widgetAnywhere']">
  <xsl:variable name="path" select="concat($ou:root, $ou:site, path)" />            

  <xsl:choose>
  <!-- Show an error if the file can not be found on staging -->
    <xsl:when test="not(doc-available(replace($path, '.htm', '.pcf')))">
      <div class="panel">
        <h2 class="normal-size">Widget Anywhere ERROR</h2>
        <p>The include file could not be found on staging.</p>
        <code><xsl:value-of select="path" /></code>
      </div>
    </xsl:when>

    <!-- On Publish call the SSI template -->
    <xsl:when test="$ou:action = 'pub'">
      <xsl:copy-of select="ou:ssiAbsolute(path)" />
    </xsl:when>

    <!-- On preview, display the content --> 
    <xsl:when test="$ou:action = 'prv'">
      <xsl:copy-of select="doc(replace($path, '.htm', '.pcf'))" />
    </xsl:when>

    <!-- On edit and compare show this panel -->
    <xsl:otherwise>
      <div class="panel">
        <h2 class="normal-size">Widget Anywhere</h2>
        <p>When this page is published out, the widget below will be included.</p>
        <code><xsl:value-of select="path" /></code>
      </div>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>

The first thing we need to do is get the OU Campus path to the file. This setup assumes that you have relative URLs set in your sites’ settings. If you use absolute URLs, then you will need to remove the https://www.domain.edu from the path node/variable.

Next, we make a choose statement checking for the following:

The file doesn’t exist

It is first checking if the file exists on staging. If the file does not exist on the staging server, it probably doesn’t exist on the production server. On UNC’s server, this will cause a 500 error and break the entire page.

The action is publish

If the action is publish, then we call the publish function which is provided by OU Campus in your installation. I’m omitting this template because it will be different depending on your server’s coding language: PHP, C#, etc.

The action is preview

If the action is “preview,” then do a doc call to the file. It replaces the extension .htm for .pcf to preview the component on the page.

The action is edit or compare

Finally, if the user is in edit mode or compare mode, show a panel with a description of what will happen.

Demos

Here is what the page will look like to the web author depending on the choose statement.

The file doesn’t exist

File does not exist error

The action is publish or preview

It is the same on both but created in two different ways. Preview uses doc() call and Publish uses ou:ssiAbsolute() function.

File does not exist error

The action is edit or compare

File does not exist error

Final Thoughts

The only downside to this so far is that if you don’t set “Lock to Path” then the file chooser starts at the root of the site and not at the location of the file that including the widget. When you insert an image, if the Default Image Folder folder variable is not selected, it starts the user in the existing directory.

I logged a ticket with OU regarding this here.