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.