Friday Sep 09, 2011

Adding your own alert messages

If you've installed WebCenter Content (UCM) or have made changes such as switching the search engine, you may have noticed an alert message at the top of the pages letting you know if there is a specific task that needs to be done such as a restart or rebuild of the search collection.

Well, these alerts are open for administrators to set as well.  So for instance, if you have a planned outage you can set a message letting users know the system is going to be down for a certain amount of time.  

Adding and managing alerts is very simple.  There are three primary services that are used:  SET_USER_ALERT, GET_USER_ALERTS, DELETE_USER_ALERT.   With SET_USER_ALERT, you simply need to pass in alertId (a unique identifier you give the alert) and alertMsg with the message you want to display.   And because it's just a service, you can simply call it in a URL to set it (as an administrator):  

http://myserver:16200/cs/idcplg?IdcService=SET_USER_ALERT&alertId=maint&alertMsg=My message.  

You can get fancy with the message by including HTML as well as Idoc Script.  That will be processed on the page as it's being rendered.  Optionally, you can pass in alertUrl which would be a URL that the message would lead to.  This value is appended to the "/cs/idcplg" path.  

To know what alerts are set, you can run the GET_USER_ALERTS service and pass in IsJava=1 to display the values back:  


It will then display the alerts in the USER_ALERTS result set.

To remove the alert, simply run the DELETE_USER_ALERT service and pass in alertId to identify which alert to remove.  Optionally, you can pass in isTempAlert=1 when you first create the alert and it will be removed the next time the server restarts.

Wednesday Aug 10, 2011

Hiding the Standard Check-In and Standard Search menu items

On 3 separate comment threads on my blog, I've had people asking how to hide the Standard Check-In and Standard Search menu items in UCM/URM navigation.  Given that it seems to be a popular topic, I thought I would cover it here.

Out of the box, UCM does not give you a way to hide these menu choices.  There aren't any secret configuration flags or tricks you can do with Idoc Script to get them to disappear.  You need to have a custom component to do it.   But the good thing is the code to do it is pretty minor.  And because the menus changed between 10g and 11g, the code is slightly different between the two.  But I'll cover both here.

In both cases, you want to modify the 'custom_finish_layout_init' resource. As the name implies, this is what gets called at the end of the JavaScript processing of the page layout and where we can insert our menu changes.  As best practice, you first want to include a 'super.' call to the resource to load any previously modified versions of the resource:

 <$include super.custom_finish_layout_init$>

The next portion depends upon the version you are running.  On 10g, the code would look like:


And that's it!  Just deploy your component and your menu choices should be gone.  Of course, you can always go beyond that and show the menus if the user is an admin or such.  Or hide just one or the other based on configuration entries.

In 11g, the code would look like:

var searchmenu= YAHOO.widget.MenuManager.getMenu("MENU_A_SEARCH");
var searchmenuitems=searchmenu.getItems();
    <$if isComponentEnabled("RecordsManagement")$>
navBuilder.deleteItem("MY_PERSONAL_SEARCHES_" + (searchmenuitems.length-<$lenghthCount$>));

var checkinmenu= YAHOO.widget.MenuManager.getMenu("MENU_A_NEW_CHECK_IN");
var checkinmenuitems=checkinmenu.getItems();
navBuilder.deleteItem("MY_PERSONAL_CHECKINS_" + (checkinmenuitems.length-1));

In this case, there isn't an Idoc variable that is maintaining a count anymore.  So it has to be calculated through the MenuManager.

For a pre-built version of the component, I have one available on our sample code site.  It has logic to detect if you are on 11g or 10g and apply the appropriate command to delete the menu items, so it can be used in either version.

Tuesday Jul 19, 2011

Copy And Paste in Java Applets

For a while now, I've noticed that copy and paste no longer works in the Admin Applets in UCM.  This was a minor annoyance as I was typically just trying to copy and paste a content ID or line of scripting.  But it suddenly became a real problem for me when I needed to create an option list of countries.  I had the list nicely formatted in my Notepad++, but no way to copy and paste it into my option list dialog.

Well, it turns out with the release of the Java Plug-in 1.6.0_24 in February 2011, copy and paste from the system clipboard was deemed a security hole and disabled.  You can copy and paste BETWEEN applets.  But if you try to use something from your main clipboard, it can't be copied in.  

So there are a couple of options for a workaround.  You can roll back to an earlier version of the plug-in.  That will work, but chances are all future releases will still keep copy and paste disabled, so you'd never be able to upgrade.  

The other alternative is to provide a custom java security policy file which enables access to the system clipboard again.  

  1. First locate your local Java Security Policy file.  The file is named java.policy and should be in the lib\security folder of your Java installation.  On Windows 7, it can be found at C:\Program Files (x86)\Java\jre6\lib\security.
  2. Copy this file to your home folder (ex. C:\Users\Kyle).
  3. Rename the file to .java.policy (note the period at the beginning). 
  4. Edit the file in a text editor.  Locate the line of text
    // "standard" properies that can be read by anyone

  5. Add the following line just below this line.
    // "standard" properies that can be read by anyone
    permission java.awt.AWTPermission "accessClipboard";

  6. Save the file.
  7. Close any open browsers and ensure that Java is not running before testing.


 While you can modify the java.policy file directly in the lib/security folder, chances are it will get overwritten again on the next JRE update.  This method should allow those changes to persist.

Tuesday Jun 14, 2011

Updating metadata in a custom element in Site Studio

I was recently asked if it was possible to edit metadata on a Site Studio data file from an element instead of having to go to the Metadata tab specifically.  Users were finding it disorienting to move back and forth between the Elements and Metadata tabs when updating both content and metadata.

So I put together an example that places a metadata update form within a custom element. It uses a couple of AJAX calls to the server to get the current metadata values (DOC_INFO) and to update them (UPDATE_DOCINFO). The sample includes 3 fields; Title, Type, and Comments. 

It can be easily changed to add additional fields.  Or you could make the entire custom element to be one particular metadata field.  Much of the code in the sample has comments, so I won't go into detail here.  

One function I did find particularly useful was the ability to pull in the dID and dDocName of the data file into the custom element form.  The functions ElementAPI.GetFormProperty('dID') and ElementAPI.GetFormProperty('dDocName') were used in order to run the services against the content to pull and push the metadata information.

The sample can be downloaded here (right-click and save). Simply submit the file with the Web Site Object Type of 'Custom Element Form'.  Then create a new Custom Element that points to the form. I've tried it in both 10gR4 and 11g.   

Hopefully some other folks will find this helpful.

Wednesday Jun 08, 2011

Importing and exporting archives as zip files in UCM

Archive ZipOne of the features of Site Studio is the ability to backup and restore websites.  It takes all of the assets associated with the website and combines them into a backup directory that is stored on the server and can be downloaded as a zip if needed.  When it comes time to restore, you simply choose that backup from the server or upload the zip file saved earlier.  The mechanism that Site Studio is using in the background is simply a specialized Archiver process.  An archive is defined dynamically with the proper export criteria to grab the site assets and they are exported to that backup directory.  Then when you request a download of that backup, UCM zips that standard archive directory and delivers the zip file to the client browser.

Well, it turns out that this ability to download and upload zipped archives does not have to be for just Site Studio sites.  You can do this for regular content archives as well. 

First, when you go to the Archiver applet, you're taken to the default collection of archives.  In the menu, go to Options -> Open Archive Collection.  There you should see another one with the name "<instance name>_sitestudiobackupcollection".  Select that collection and click Open. 

Archive Collection

This collection got created when Site Studio was installed and is where site backups are archived. And even if you aren't using Site Studio at all, as long as you have it enabled, this feature will be available. If you've done backups or restores already, you'll see those listed. Now that you have the collection open, you can add your new archives here.  You can create those just as you normally would.  

archive list

Now perform the archive Export process.  The content/table data will then get exported to the collection location on the server.

To download the archive, go to Administration ->; Site Studio Administration -> Backup and Restore.   Click the Managed Archives button.  You should now see your archive in the list.  

Manage Backups

With the Actions icon, select 'Download backup archive as ZIP'.  This will zip up the archive and allow you to download it locally.  Note, large archives may take a while to zip up and may time out if too large.  For those types of archives, I'd recommend setting up the traditional ways of migrating the archive.

Now that you have your archive, you can just as easily import it into your target instance.  On that instance, go to  Administration -> Site Studio Administration -> Backup and Restore.  In the Upload Archive section, browse to your saved archive and click Upload Archive.  You'll then be taken to the archive information screen.   

Archive Information

On the Actions menu, select 'Restore backup archive contents'.  This will now import the archived documents.  If you wish to include some import mappings, you can simply go to the Archiver applet and set up the mappings there and do the import right from the applet.

Monday May 23, 2011

Customizing Layouts and Skins in UCM 11g

custom skin

Along the same lines as my previous post on modifying the navigation menus, I thought I would cover how to customize layouts and skins in 11g.  Back in 10g, I had posted an entry on using configuration flags to continue to use the method of copying skins and layout directories under /weblayout to customize them.  I also mentioned that this method was going away in favor of using custom components to do the customizations.  Well in 11g, that is the only method. 

The technique is similar to what the 10g custom component would look like, but does include a few changes including some new approaches of using dynamicdata tables to drive data. 

To add new layouts, they get merged in the LmLayouts table.  New skins get merged into the LmLayoutSkinPairs table.  And the PublishedWeblayoutFiles and PublishedStaticFiles merged tables define what files get published to the weblayout directory.   Let's take a look at each.

In the following table, we're defining our new layout with an id, label, and marking it enabled. This is what will get merged into LmLayouts.

<@table CreateLayoutAndSkin_Layouts@>
<td>id</td> <td>label</td> <td>enabled</td> </tr>
<td>NewTopMenus</td> <td>New Top Menus</td> <td>1</td> </tr>

Next we'll define out to render the new layouts. This helps determine how the layout.js file is deployed dynamically. If you wanted to define a whole new layout altogether, you'd create a new layoutMode. This definition uses the new dynamicdata data table construct.

<@dynamicdata LayoutRenderModes@>
layoutName, layoutMode
NewTopMenus, Top Menus
NewTrays, Trays

In the next table, we'll define the skins to use for our new layout. We can also define an entirely new skin and apply it to either the new or existing layouts.

<@table CreateLayoutAndSkin_LayoutSkinPairs@>
<td>Top Menus</td><td>Gray</td><td></td><td>1</td>

The publishing of weblayout files happens in two ways. The first is the dynamic building and publishing of files. This is done for the layout JavaScript and skin CSS files.  In the case of the layout, it will use the TOP_MENUS_LAYOUT_JS template and for the skin, it will use the IDC_SKIN_CSS template.

<@table CreateLayoutAndSkin_PublishedWeblayoutFiles@>
<td>resources/layouts/NewTopMenus/layout.js</td> <td>TOP_MENUS_LAYOUT_JS</td> <td>javascript:layout:NewTopMenus</td> <td>50</td> <td><$if isLayoutEnabled("NewTopMenus") and (not DisableNewTopMenusPublishing)$><$doPublish = 1$><$endif$></td>
<td>resources/layouts/NewTopMenus/Oracle/skin.css</td> <td>IDC_SKIN_CSS</td> <td>css:layout:NewTopMenus</td> <td>50</td> <td><$if isLayoutEnabled("NewTopMenus") and (not DisableOracleSkinPublishing) and (not DisableNewTopMenusPublishing)$><$doPublish = 1$><$endif$><$tags="top_menus:oracle"$></td>

The second type of publishing is that of the static files such as images.

<@table CreateLayoutAndSkin_PublishedStaticFiles@>
<table border=1>
<td>publish/resources/layouts/NewTrays/Oracle</td><td>resources/layouts/NewTrays/Oracle</td><td>resources:layout:NewTrays</td><td>50</td> <td><$if isLayoutEnabled("NewTrays") and (not DisableOracleSkinPublishing) and (not DisableNewTraysPublishing)$><$doPublish = 1$><$endif$></td><td>0</td>

Many of the styles that get dynamically build with the skin.css file can be changed using the dynamicdata constructs.  For example, to change the link colors when in a trays layout:

<@dynamicdata css_vars_trays_oracle@>
name, value
linkColor1, #FF0000
linkColor2, #FF0000

These examples are rolled up into the sample CreateLayoutAndSkin component. It uses all the above techniques to create a new trays layout and top menus layout as well as a new skin. In the skin example, rather then creating a custom template and resources for the css file, a static one is defined within the static folders that gets published. Since it is custom, it's less likely that the css file needs to be dynamically built.

Hopefully this gets you on your way to customizing the UCM (or URM) UI for your own look & feel.

Wednesday May 11, 2011

Modifying Navigation Menus in UCM 11g

UCM Custom Navigation Menus

In UCM 11g, the way the navigation menus are constructed are done differently now.  In the past, this was handled with a navbuilder API in Javascript that allowed for menu choices to be manipulated with commands such as:

navBuilder.addChildNodeTo('ADMINISTRATION', 'item', 'id==FUNCTIONA', 'label==Function A'), 'url=='+httpCgiPath+'?IdcService=FUNCTIONA');

Well, in 11g that method has been deprecated in favor of a new method.   This new method takes advantage of a new data table construct in 11g Idoc Script called Dynamic Data Tables.  These allow you to create tables of data in Idoc Script and dynamically change them as opposed to the static table definitions.  This is useful for data that changes frequently and may be user the navigation menu.  I won't go into detail on Dynamic Data Tables here, but you can read up more about them in the Oracle Fusion Middleware Developer's Guide for Oracle Universal Content Management 11g Release 1 (11.1.1)

So for the example above, the code would now look like this in the custom component's resource file:

<@dynamicdata CoreMenuItems@>
id, label, linkType, linkData
FUNCTIONA, Function A, cgi, IdcService=FUNCTIONA

<@dynamicdata CoreMenuItemRelationships@>
parentId, id, loadOrder

Then you can add some additional information to the menu such as any flags/conditions on when it should be shown and any image to be displayed with it in the Trays view.

<@dynamicdata CoreMenuItemsFlags@>
id, flags

<@dynamicdata CoreMenuItemsImages@>
id, image, imageOpen
FUNCTIONA, ScsPageItem.gif,

To help get you started, I've posted a sample component that gives an example of these methods and includes a readme.html that goes into detail on the different options that are possible.

Tuesday Feb 22, 2011

New security configuration flag in UCM PS3

[Read More]

Thursday Jan 27, 2011

Handling URLs as content

[Read More]

Wednesday Jan 26, 2011

Searching for null values in UCM

[Read More]

Thursday Dec 30, 2010

Page debugging got easier in UCM 11g

[Read More]

Monday Dec 20, 2010

Filtering option list values based on security in UCM

[Read More]

Kyle Hatlestad is a Solution Architect in the WebCenter Architecture group (A-Team) who works with WebCenter Content and other products in the WebCenter & Fusion Middleware portfolios. The WebCenter A-Team blog can be found at: ateam_webcenter/


« July 2016