Thursday, May 28, 2009

Adding Flexibility and Re-use to your Web Site Design

We are frequently asked, “How many layout templates should we have in our Site Studio site?”  The (short) correct answer is always, “As many as you need.”  But a more realistic response includes some additional thought behind it:

Take into consideration the features and functions of your site.  Are you replicating functionality in a similar manner?  Do you have pages, or a series of pages, that are remarkably similar, but functionally or structurally different in one or two areas?  (For example, do you have a special section that creates an exception to your navigation rule or has an additional dynamic list?)   These structural differences often get interpreted as a need for additional layout templates.  However, adding new layout templates comes with an added cost.
When adding layout templates, keep the following in mind:

  • These templates must be maintained.  If your site design changes, or if there is some structural change to your web site, someone will need to modify the template
  • These templates must be accounted for.  This is one more file that you will need to track during the publication process
  • These templates must maintain consistency, and the more files you have, the more difficult this task becomes. 

Ideally, a small number of templates will serve a greater good on your website.  However, companies

Fragments and parameters offer a great starting ground for allowing greater flexibility with layout templates, but they often fall short of a full solution.  When you add a fragment to a layout template and assign parameter values, those values are stored on the layout template itself.  For example, if you have a fragment that displays a dynamic list, and the query powering that list is assigned in a parameter, that value is saved directly on your layout template.  If you were to use that layout template in another section, you would be unable to change the query without affecting the page as it appears in the original section.  This severely limits the reusability and flexibility of this layout template.

Luckily, the Oracle CMS provides an alternative method of assigning that dynamic query value.  The tool used for that is “Custom Section Properties.”  Just like you can define and assign parameters to a specific fragment, you can define and assign properties to the sections of your web site.  These properties are then available on your layout templates and in your fragments.

Let’s take closer look at the dynamic query example.  Assume that your original fragment was set up in the following manner:

You have a single parameter “ssQueryText” that defines your query:



You have the following code inside your snippet:

<!--$ ssQueryText = getValue("#active", ssFragmentInstanceId & "_ssQueryText") -->
<!--$ QueryText = ssQueryText -->
<!--$ executeService("GET_SEARCH_RESULTS") -->
<!--$ loop SearchResults -->
      <!--$ dDocTitle --><br />
<!--$ endloop -->


Note: Granted, this is an overly-simplistic fragment.  You can certainly expand this to include styles, sorting, additional logic, etc.

If you were to put this fragment on a layout page and assign that layout page to two different sections of your web site, there would be no way to use the same fragment to display different lists.  This can be extremely limiting.

Let’s take a new approach with a different fragment.  Before we create the fragment though, we’ll need to set up our site to accommodate a Custom Section Property.  In the top menu of Site Studio, there is a button for “Define Custom Section Properties.”  Click that button to access the Custom Section Properties setup screen.



From the setup screen, click the “Add” button.  This will allow you to add a custom section to the Properties pane for the sections.  This process is very similar to adding a parameter to a fragment.



You’ll need to provide three values for the definition:

  • Name: must be a valid XML name, so no spaces or special characters.  We’ll call ours “SectionQuery”
  • Type: you have a wide variety of formats from which to choose.  In this case, let’s select “managedquery”
  • Description: any descriptive text to help understand the property better.  We’ve used “The query that is special to this sections


Once you’ve filled this out, click “OK.”



Your Custom Section Property is now defined, so just click “OK” again to return to Site Studio.  Click on a section and look at the bottom of the Properties pane.  You should see a new set of properties labeled “Custom section properties,” and your property should be present in the list:



Just as you can assign a different title to each section, you now have the ability to assign a different query to each section.  Using your same two sections as before, enter two different queries for those sections.  Notice that, because we selected “managedquery” as the variable type, Site Studio automatically assists us in creating a valid query.

Let’s take another look at the fragment and incorporate this new property into the code.  Create a new fragment, but do not include a parameter.  Remember, we want to get the query value from the Custom Section Property that we created.  The only thing that really needs to change in this fragment is how QueryText gets assigned.  In the previous example, we took it from a parameter.  Here, we can leverage our Custom Section Property easily:

<!--$ QueryText = ssGetNodeProperty("SectionQuery") -->

We’re using the ssGetNodeProperty function to read the value from the Properties panel and incorporate it into our code execution.  From here on out, the code is the same:

<!--$ executeService("GET_SEARCH_RESULTS") -->
<!--$ loop SearchResults -->
      <!--$ dDocTitle --><br />
<!--$ endloop -->


Save your new fragment and put it on your layout page.  Check your results.  You should see the same layout page, but with different query results!
This feature has endless possibilities.  Some common uses include:

  • Changing navigation structures; perhaps some sections require 2 levels of navigation while some require three
  • Adding a true/ false option to show an area of the layout page
  • Assigning different style sheets to different sections
  • Managing parameters for Flash objects
One caveat to Custom Section Properties:  Remember that once you create a Custom Section Property, it is available for all sections of the web site.  Having an abundance of CSPs can lead to some confusion, so choose and name your CSPs well.

Monday, April 27, 2009

Expanding Your Search Results

When you run a search in Oracle UCM, the system will max out the number of documents it returns according to the MaxResults variable.  The default value for this is 200, and you can change this number in your config.cfg file.  Be warned that increasing this number beyond 200 can have adverse effects on your search performance, so use this with caution.

Another Method of Expansion

But what if, on a rare occasion, you do need to get extra search results, but don’t want to modify the configuration file so as to affect all searches?  This post demonstrates some simple IDOC code that will expand your search results.

Sample HCSP

For this example, we’ll put the code in a simple HCSP page.  The same strategies would work just as well inside fragments, components, or other code sources.
Create a basic SearchResults.hcsp page.  I always like to put in some basic HTML code first to aid with display.   Once you have that set up, let’s start with the parameters for the search:

<!--$ QueryText = “” -->
<!--$ desiredResults = 500 -->
<!--$ maxResultsPerSearch = 200 -->


The QueryText variable is required to execute the search service.  By setting it to blank, we are getting all documents in the system.  You can put in your own properly formatted query here if you like.

The desiredResults variable is how many results we’d really like to see.  The maxResultsPerSearch variable is set to 200, the default maximum that we’ll get from a single search.  We can expand this code a little to accommodate a custom setting here:

<!--$ if MaxResults and MaxResults gt 0 -->
     <!--$ maxResultsPerSearch = MaxResults -->
<!--$ endif -->


This tests for the presence of the MaxResults configuration setting and, if it finds one, will swap that value in for maxResultsPerSearch.

We’re going to need one more variable to keep track of how many total search results we’ve found to date.

<!--$ runningTotal = 0 -->

Now that we’ve got these variables established, we can get our search results.  Remember, each time we run a search, we’ll be capped at 200 results, but we want to get 500.  This means we’ll need to run two 200-result searches and one 100-result search.  We’ll accomplish this by executing the search inside a loop.

<!--$ loopwhile runningTotal lt desiredResults -->

What we’re setting up here is a method to keep track of the total number of results we get.  As long as that number is fewer that the desiredResults, we have more searching to do.

We need to add some additional search parameters that are specific to each iteration of the search execution:

<!--$ ResultCount = desiredResults - runningTotal -->
<!--$ StartRow = runningTotal + 1 -->


I’m cheating a little bit on the ResultCount here.  Theoretically, this number could be well in excess of the search result cap.  I’m relying on Oracle’s internal processes to enforce the limit of 200 documents.  The StartRow will need to be different each time I run the search so that I don’t get duplicates.

Now that this is all set up, I can run the service and print the results:

<!--$ executeService("GET_SEARCH_RESULTS") -->
<!--$ loop SearchResults -->
     <li><!--$ dDocTitle --></li>
<!--$ endloop -->


I have a touch of housekeeping to do to make sure the loop continues (and more importantly, ends) properly:

<!--$ runningTotal = runningTotal + SearchResults.#numRows -->
<!--$ if SearchResults.#numRows eq 0 -->
     <!--$ break -->
<!--$ endif -->


I’m incrementing the runningTotal so I can keep track of my progress.  I’m also checking for a zero result set.  If that happens, then I’ve run out of results and need to break out of the loop.

All that’s left to do is end the loop!

<!--$ endloop -->

When you run this code, you should see 500 documents in your results.
Here is the code in its entirety (plus some minor formatting):

<html>
<head></head>
<body><!--$ QueryText="" -->
<!--$ desiredResults = 300 -->
<!--$ maxResultsPerSearch = 200 -->
<!--$ if MaxResults and MaxResults gt 0 -->
     <!--$ maxResultsPerSearch = MaxResults -->
<!--$ endif -->
<!--$ runningTotal = 0 -->
<ol>
<!--$ loopwhile runningTotal lt desiredResults -->
     <!--$ ResultCount = desiredResults - runningTotal -->
     <!--$ StartRow = runningTotal + 1 -->
     <!--$ executeService("GET_SEARCH_RESULTS") -->
     <!--$ loop SearchResults -->
          <li><!--$ dDocTitle --></li>
     <!--$ endloop -->
     <!--$ runningTotal = runningTotal + SearchResults.#numRows -->
<!--$ endloop -->
<ol>
<body>
<html>


One word of warning: this code will be executing a search service several times, so you may get some slower results. 

Friday, April 10, 2009

Security Groups and Accounts Overview (Part 3)

This is the third entry of a three-part series on Oracle UCM (Stellent) security.

How Access Works

Access to documents is defined by both the Security Group and the Account.  In order to perform an action (such as view the document or check in a revision), a user needs to have permissions to do so by BOTH the Role the user has (and, by extension, the Security Groups the user has) and the Accounts the user has.  Both the Role and the Account settings for that user must grant permission to perform an action.  If either the Role or the Account permission does not exist, the user will be unable to perform the action.

Note: if Accounts are not enabled, then the user needs access via the Role only; accounts are not considered.

Practical Usage

The following roles are defined in the system:

Role Security Groups
Employee Intranet (R)
IntranetManager Intranet (RW)
ExtranetManager

Extranet (RW)
Partner Extranet (R)

The following users exist in the system:

User Roles Accounts
John Employee dept (R)
Sally Employee
IntranetManager
dept (R)
dept/hr (RW)
Beth Employee
Intranet Manager
dept (R)
dept/legal (RW)
Mike Partner partner/all (R)
partner/acme (R)
Hugh Employee
IntranetManager
dept (RW)
Brian Employee
ExtranetManager
dept (R)
partner (RW)
Anne Employee
IntranetManager
ExtranetManager
#all (RWDA)


Let’s look at some sample documents in the system.

Document A

Security Group Intranet
Account dept/legal
Here’s the breakdown of how people can access this document:

User Highest Permission by Role Highest Permission by Account Final Permission
John

R

R

R

Sally

RW

R

R

Beth

RW

RW

RW

Mike

None

None

None

Hugh

RW

RW

RW

Brian

R

R

R

Anne

RWDA

RWDA

RWDA

Sally cannot check out this document, even though her Role allows it. Her account settings are too granular (dept/hr) to write to a document in the dept/legal account.  On the other hand, Hugh can check out this document, because his role allows it and his account setting of /dept (RW) will cascade down to accounts beneath it; so he has write permissions to all documents under the /dept account.

Document B

Security Group Extranet
Account partner/acme
Here’s the breakdown of how people can access this document:

User  Highest Permission by Role Highest Permission by Account Final Permission
John

R

None

None

Sally

R

None

None

Beth

R

None

None

Mike

R

R

R

Hugh

None

None

None

Brian

RW

RW

RW

Anne

RWDA

RWDA

RWDA

Most of these users cannot see this document at all because they do not have the account requirement.  Mike, the partner, can see this document just fine however.

Document C

Security Group Extranet
Account partner/abc
Here’s the breakdown of how people can access this document:

User Highest Permission by Role Highest Permission by Account Final Permission
John

R

None

None

Sally

R

None

None

Beth

R

None

None

Mike

R

None

None

Hugh

None

None

None

Brian

RW

RW

RW

Anne

RWDA

RWDA

RWDA

This document is similar to Document B, but the account is different.  Using the account, this system is able to put a document on the Partner Extranet that only some partners can see.  Notice how Mike is denied access to this document.

Monday, April 6, 2009

Security Groups and Accounts Overview (Part 2)

This is the second of a three-part series on Oracle UCM (Stellent) security.

Accounts

Accounts are an optional second layer of security that you can use inside the Oracle UCM.  To activate accounts, add the following configuration setting to you config.cfg file:

UseAccounts=1

Accounts differ from Security Groups and Roles in a couple of different ways:

  • Accounts are applied to documents and to users. 
  • Accounts have a hierarchy to them
A document can have only one account.  A user can have access to an unlimited number of accounts.
Accounts tend to be used for very granular levels of security, although the hierarchical nature of accounts allows for wide-spread access across several accounts.

A Sample Hierarchy

Accounts have a natural hierarchy to them.  This allows you to create extremely granular levels of security, but also gives you the ability to grant a wide range of access as needed.  This is fantastic for managers, executives, and administrators who need broad access to some of the content in the system.  It also allows you to fine-tune the distinction between read-access and write-access for several different types of users.

The account hierarchy is typically delineated with a slash (“/”).  The first level of the account tends to be very broad.  The account gets more and more specific as components are added to it.  For example:

Account Access
dept All departments
dept/mktg The marketing account
dept/legal The legal account
exec An account for executives
exec/ceo An account for the CEO
exec/cio An account for the CIO
exec/coo An account for the COO

A Common Account Mistake

Because Accounts get more specific and detailed the farther down the tree you go, many users of Oracle UCM create what they think is a highly secure group far down the hierarchy. 

Continuing the example from above, let’s say that you wanted to create a group of secure documents for managers within the marketing department.  Many people try this as an approach:

dept/mktg/managers

This is not a workable solution.  If you were to implement this account, all users who had access to dept/mktg would automatically get the same access to the “Managers Only” account.  This is exactly what you’re trying to avoid!  You can address this problem in a couple of ways:

  • Put the “Managers Only” account in another branch.  An account such as managers/mktg would keep these documents safe from people who have access to dept/mktg
  • Create a general account for marketing documents.  This will give you two new accounts: dept/mktg/managers and dept/mktg/general
  • Use the higher level account for more secure documents, and create a lower level account for documents with more generalized access.  This would entail putting the “Managers Only” content in dept/mktg and the regular marketing documents in a generic sub-account, such as dept/mktg/general.  Managers could have access to the dept/mktg account (and, by order of the hierarchy, dept/mktg/general as well), while regular users of the marketing department would have access into the dept/mktg/general account only.
Usually, the first option is most ideal solution.  (The other two are included just to help you get used to thinking about why account structures work in certain ways.)  The first option helps you set up your structure so that you can use high-level account assignments (such as just dept) to give broad ranges of access to users.

When dealing with accounts, it’s important to think not only about the documents, but also about how you will provide the access to users.  Some common questions to ask yourself as you’re preparing an account hierarchy:

  • How are these documents logically grouped together in terms of security?
  • Are there common groups of people who need to see the sub-groups inside this hierarchy?
  • Do we need to identify some documents for which there is either an expanded or contracted audience that has write access?
  • Do we need to identify some users who have expanded or contracted privileges for a subsection of these documents?

Predefined Accounts

System Administrators have the ability to establish Predefined Accounts in the User Admin.  By populating this list, System Administrators make the accounts available via drop-down lists.
Note: Accounts do not have to be defined in this list in order to be used, but doing so makes the management much easier.

Special Accounts

There are two special accounts defined within Oracle UCM:

  • #none
    • This is for documents with no account.  If a document has a blank or null account field, a user will need access to the #none account to perform actions on this document
  • #all
    • This is a catch-all account, and grants a user access to any and all accounts in the system.  Use this option with care.
Note: the #none and #all declarations are available only in the User Admin screen.  You assign these accounts to users, but do not assign them to documents.

Wednesday, April 1, 2009

Security Groups and Accounts Overview

Oracle (Formerly Stellent) provides several ways to restrict access to documents, and the terminology and structures can get somewhat confusing at times.  I’ve written this blog entry to help clarify some of these terms and help people get a better understanding of the concepts and terms involved with Oracle UCM security.

This blog entry is split into several sections  Today we’ll cover Security Groups and Roles, next up will be Accounts, and that will be followed by a couple of examples of how they all work together.

Security Groups

A Security Group is a categorization of security that is linked directly to a piece of content.  Documents have Security Groups; users do not.  I like to think of a Security Group as a broad section of security.  Every document must belong to one and only one Security Group.  By default, Oracle provides two Security Groups: Public and Secure.  Many people expand these to larger categories of broad security.  Some typical values are:

  • Use-based Security Groups:
    • Intranet/ Extranet/ Public
    • Internal/ External/ Officer
  • Department-based Security Groups
    • Legal/ HR/ Marketing
  • Location-based Security Groups
    • SanFrancisco/ Boston/ London
You can have as many Security Groups as you like in the system, but people tend to keep this number down to a minimum.  Remember, Security Groups tend to represent broad categorizations of security, so try to keep this number under control.  If you need more discrete control over document security, I recommend looking at Accounts.

Roles

A Role is a definition of access that a user has to specific Security Groups.  Each Role references one or many Security Groups.*  For example, the following roles may be defined in your system:

Role Access
Intranet Contributor Intranet (RW)
Reader Legal (R)
HR (R)
Marketing (R)
London Admin London (RWDA)
A Role is associated with one or many users, and a user can have many Roles. 

* Note: a Role can be used to define access to administrative applets as well; it is entirely possible to have a Role that does not address a Security Group.

Thursday, March 26, 2009

Enhancing Your Search Results

When I’m searching for a document, I’m often disappointed by the results. Not with the content items themselves, but rather with what I can do with them. You see, the default Action menu is a little thin:


There is one feature that I consistently use that isn’t available here: Update Metadata. Oracle has made it easy to add this feature.

The list of options for this menu are stored within one of the many resources included with the Standard Oracle UCM installation. The main include that controls this is called setup_search_results_action_popups. This include contains references to all the functions that can appear on the action bar. Here is an example of how that code reads:

<$exec setValue("PopupProps", "label", lc("wwGetNativeFile"))$>
<$exec setValue("PopupProps", "ifClause", "not isExternallyManagedDoc")$>
<$exec setValue("PopupProps", "function",
"<$SearchHttpCgiPath$>?IdcService=GET_FILE&dID=<$url(dID)$>&
dDocName=<$url(dDocName)$>&allowInterrupt=1")$>
<$exec setValue("PopupProps", "class", "document")$>
<$exec setValue("PopupProps", "id", "getNativeFile")$>

This adds the “Get Native File” link to the popup. There are five key properties to this:


Property


Sample Value


Description


label


Lc(“wwGetNativeFile”)


The label as it will appear in the popup menu


ifClause


not isExternallyManagedDoc


A clause that will be executed as part of an if statement to see if this particular function should appear in the popup menu.  In this sample, this function will appear if the following statement executes true:
<$ if not isExternallyManagedDoc $>


function


<$SearchHttpCgiPath$>?
IdcService=GET_FILE&
dID=<$url(dID)$>&
dDocName=<$url(dDocName)$>&
allowInterrupt=1


The function that will be executed when clicked.  Notice that we can use IDOC script in here as well as references to metadata values gathered in the search results


class


document


Defines the class of Search Results for which this is pertinent.  You will most often use “document” here, although you could use “Client Controlled” for some WebDAV/ ODMA integration.


id


getNativeFile


A unique identifier for this function.  You may want to consider using a custom prefix (such as “OV_”) for all of yours.

The key to this resource sits at the end:
<$include extra_setup_search_results_action_popups$>

Jackpot! Oracle has left this hook for use to use to bring extra code into this include. We can now go build a component that adds a new feature in here.
Use the Component Wizard to start a new component by selecting “Add” from the main screen. Select “Create New Component” and give your component a name. It’s best to leave the directory at the default setting of “custom.”


I like to prefix all of my components with OV_ so that I can distinguish them from other components that I obtained from different sources (such as Oracle support).
From here, add a Resource (of the HTML/ String varietal). I usually keep all of the default settings for file names, etc., but you are welcome to customize them as you see fit.


Once this is set, you can add the include to the final screen. You need to at least define the include here before continuing. Some people will go ahead and type the include code into this form, but I prefer to open the file in a proper text editor.


In the text editor, we can now add in our custom function. (You can find the file in your installation directory. The path is [install directory]/custom/[component name]/resources.) We only need a couple of lines of code here, and we can borrow heavily from what Oracle has already provided us.

First and foremost, since we are using a hook that is potentially used by other components, we need to make sure to include the previous versions. We use the super. construction to achieve this:
<$ include super.extra_setup_search_results_action_popups $>

Now we can add in our new function. We only need the five lines outlined above. I just pasted a copy of these lines into my include. I can then modify the values.
<$exec setValue("PopupProps", "label", “Update Metadata”))$>

This example just creates the label without accessing external string variables. For multi-language support, you may want to consider a more robust naming mechanism, but for the purposes of this demo, let’s keep it simple.
<$exec setValue("PopupProps", "ifClause", "not isExternallyManagedDoc")$>

This is the same as above. We don’t want to do this for external documents that find their way into search results.

<$exec setValue("PopupProps", "function",
"<$HttpCgiPath$>?IdcService=GET_UPDATE_FORM&dID=<$url(dID)$>&
dDocName=<$url(dDocName)$>")$>

This is the URL for the Update Metadata page. I can easily find this by using the Top Menus layout and browsing to a page. Notice that I can use IDOC inside the exec function here; this will make the URL unique based on the metadata of each search result.

<$exec setValue("PopupProps", "class", "document")$>

Again, this is the same as above.

<$exec setValue("PopupProps", "id", "OV_UpdateMetadata")$>

I’ve included a prefix in the ID here just to make sure it doesn’t clash with anything else in the system.

Once this is done, you can use Component Wizard to build and enable your component. Restart the server and voila! You’ve now got a brand new button!

I can add a variety of other functions in here; all I need to know is the service name and the required parameters. I can paste these together to form a URL that takes me directly to that function. For example, if I want to add in Dynamic Conversions or even links to external websites (Google searches on a metadata value found in the document, for example), I can use this example to build my own functions onto the user interface.

Monday, March 23, 2009

Making Content Occasionally Contributable

Every once in a while, you run into content areas of your web site where the content appears on several pages, but you want to limit access to contribution to just one page.  For example, if there’s a common footer on all of your pages, you may want users to see it on every page, but only change content from the home page.  This entry shows you how you can make contributed content non-contributable.

The Example

We want to create a series of pages where the content is contributable on the home page and re-used, but not contributed, on additional pages.  We will use a WYSIWYG element for the content.

The Execution

The Home Page

The home page is created as you would normally create any other page within Site Studio.  Create a layout page for the home page and then Create a contributable region.  Add a WYSIWYG element to that page. 
Make notes of the following information; you’ll need it later:

  • The Content ID (dDocName) of the WYSIWYG data file
  • The Region Name (not the ID) of the region you created
  • The Element Name (not the ID) of the WYSIWYG element

Assign Region Content to this page.  Save it, and go ahead and contribute some test content to the area.  We can use this later to test our implementation.

The Other Page

On this page, we want to use the same content item from above, but in a non-contributable fashion.  We’ll create a fragment that handles this.
Create a new fragment of “Other” type.  Name it what you like; I’ve named mine “Display XML Data File.” You’ll need to add two parameters to this fragment:

Name

Type

Required?

Description

ssDocName

managedDoc

Yes

The Content ID of the item to be displayed

ssXPath

Text

Yes

The XPath to the content

Create a snippet.  In the body of this snippet, right-click and use “Insert Parameter Declaration” for your two parameters.  This should create the following lines of code for you:

<!--$ssDocName = getValue("#active", ssFragmentInstanceId & "_ssDocName")-->
<!--$ssXPath = getValue("#active", ssFragmentInstanceId & "_ssXPath")-->


When we go to put this fragment on our layout pages, we can use the parameters to declare the Content ID (dDocName) of the file we want to display.  The parameters make this fragment reusable outside of the one document we’re trying to display here.
The only thing we have to do in this fragment is display the content of the document declared in ssDocName.  Site Studio provides a nice addition to IDOC code that allows us to do this: ssIncludeXml.  In fact, this is the exact command used to display the content on the home page that you created.  This command takes two parameters:

Parameter

Description

dDocName

The dDocName of the XML data file you want to display

XPath

The XPath to the content inside the XML file

Notice that these parameters are the same ones we defined in our fragment parameters!  How convenient!
So all we need is one additional line of code in our fragment to make this work:

<!--$ ssIncludeXml(ssDocName, ssXPath) -->

Save the fragment to a fragment library, and you’re good to go.

Putting it All Together

Now that you have the fragment, create a new section for your web site and create a new layout page for this page.  Add your fragment to the page.  You’ll need to provide two parameters for the fragment:

Parameter

Value

ssDocName

The dDocName you identified on the home page

ssXPath

The XPath to the content will be in the following format:

[Region Name]/[Element Name]/node()

For example, if your Region Name is MyRegion and your Element Name is FooterText, then your ssXPath will be:

MyRegion/FooterText/node()

Save the layout page, and you should see the content displayed.  This content display is powered by a fragment, not by a region, so it will not be contributable on this page.  However, because it is still managed content, any changes made to this content item on the home page will be carried forward to the display on other pages.

Other Uses

You can use this trick any time you want to re-use content from an XML data file—or any XML file for that matter!  This is a great way to keep content fresh and consistent on your site while not overwhelming users with some many different contribution boxes.