With Site Studio contributor, every Save/Update is checked in as a new revision that is then immediately released by the content server. While I think this is status quo for many instances, I urge you to reconsider this out-of-the-box functionality on a case-by-case basis.
Why? One word: drafting
Tuesday, April 19, 2011
Monday, March 7, 2011
► Create your own Tracing Section
If you've written custom java filters, idoc scripts, or services, you've probably added some basic logging using SystemUtils.trace("system", "log message");. However, wouldn't it be nice to separate your logs by creating your own UCM tracing section (GET_SYSTEM_AUDIT_INFO)? It's easier than you think.
Friday, February 18, 2011
► How "secure" is your Site Studio site?
NOTE: This only applies to sites hosted directly off of Site Studio; meaning, not published via the Site Studio Publishing Utility (SSPU).
If you don't know how content is secured within Site Studio, expand this:
Inherently, Oracle UCM uses two levels of content security: security groups and, optionally, accounts. Site Studio sits on top of the content server as the presentation layout for the web sites it hosts, but the content is still secured in the same manner.
A Site Studio page consists of:
In my experience, many places have a poorly designed security and metadata model (not to mention an un-normalized one). As a result, I have seen many implementations give the anonymous user (R)ead access to ALL security groups and the #all account. In my opinion, there is no chance that 100% of your content is "web ready" and insensitive by nature. Is it possible? Sure, but I'm more likely to be the Redskins' quarterback next year, so why expose your web site and content server unnecessarily?

What's my point in all this?
What if I were to say that I could obtain copies of your entire fragment libraries, along with your layout pages, and also know the names and email addresses of those who edited them?
How?
If you don't know how content is secured within Site Studio, expand this:
Inherently, Oracle UCM uses two levels of content security: security groups and, optionally, accounts. Site Studio sits on top of the content server as the presentation layout for the web sites it hosts, but the content is still secured in the same manner.
A Site Studio page consists of:
- Fragments
- Layout Files/Page Templates (.hcsp files)
- Content (data files, native documents, etc)
- Assets (images, javascript, etc)
In my experience, many places have a poorly designed security and metadata model (not to mention an un-normalized one). As a result, I have seen many implementations give the anonymous user (R)ead access to ALL security groups and the #all account. In my opinion, there is no chance that 100% of your content is "web ready" and insensitive by nature. Is it possible? Sure, but I'm more likely to be the Redskins' quarterback next year, so why expose your web site and content server unnecessarily?

What's my point in all this?
What if I were to say that I could obtain copies of your entire fragment libraries, along with your layout pages, and also know the names and email addresses of those who edited them?
How?
Thursday, February 17, 2011
► Credential Maps - Tips & Tricks
NOTE: This post assumes you authenticate externally with Active Directory (AD), have a basic understanding of its schema and Security Groups (ADSGs), already have a working LDAP provider, and have a separate LDAP role/account prefix for each of your UCM instances.
Chances are that if you authenticate externally, you've tested your luck with credential maps. I say "luck" because deciphering its syntax for the first time is akin to waiting in line to use the restroom: frustratingly painful. In a nutshell, credential maps are a part of the ProxyConnections8 component that allow you to link ADSGs (and their members) to Oracle UCM roles and/or accounts.
Chances are that if you authenticate externally, you've tested your luck with credential maps. I say "luck" because deciphering its syntax for the first time is akin to waiting in line to use the restroom: frustratingly painful. In a nutshell, credential maps are a part of the ProxyConnections8 component that allow you to link ADSGs (and their members) to Oracle UCM roles and/or accounts.
If you need a credential map that can link everything one-to-one:
ADSG Role/Account admin » admin contributor » contributor intern » intern Corporate_R » Corporate(R) ImageLibrary_RW » ImageLibrary(RW)
use the following:
#Maps all roles|#all|, %%
#Maps all accounts@|#all|, @%%
Note: the #all term does not refer to an ADSG named #all; it is a reserved keyword to signify ALL ADSGs listed within the LDAP Role/Account Prefix OU.
As powerful as the above map is, it has one fundamental flaw:
It doesn't map the #none and #all accounts
Saturday, February 12, 2011
► Build a smarter workflow approval step
Even though workflow has its uses, it's pretty rough around the edges. One thing that should be built in is recognition of its own approvers; meaning, it should be smart enough to skip any step if the dDocAuthor is one of the assigned approvers of the step. Why should you needlessly approve your own content if you're one of its approvers?
Bypass this redundant workflow step by adding this token to it: +Expand
<$executeService("GET_ALIASES")$><$skipStep=0$><$aliasToUse="[AliasName]"$><$if rsExists("AliasUserMap")$><$loop AliasUserMap$><$if strEquals(AliasUserMap.dAlias, aliasToUse)$><$if strEquals(AliasUserMap.dUserName, #active.dDocAuthor)$><$skipStep=1$><$break$><$endif$><$endif$><$endloop$><$if isFalse(skipStep)$><$exec rsFirst("AliasUserMap")$><$loop AliasUserMap$><$if strEquals(AliasUserMap.dAlias, aliasToUse)$><$if not strEquals(AliasUserMap.dUserName, #active.dDocAuthor)$><$wfAddUser(AliasUserMap.dUserName, "user")$><$endif$><$endif$><$endloop$><$endif$><$endif$>
Just remember to change [AliasName] to an actual alias that exists in your system.
Good luck.
Saturday, February 5, 2011
► Custom Property: null vs blank
To determine if a custom property is null (ie. does not exist) vs. blank, use the following code snippet:
Note: It is a misprint in both the 10gR3 and 11g Site Studio Technical Reference Guides when it says the SS_GET_ALL_CUSTOM_NODE_PROP_DEFS service returns a ResultSet named "CustomNodePropertyDefs"; it is actually "CustomNodePropDefs". In fact, my blog has the only reference to "CustomNodePropDefs" on the internet...seriously. Also, SS_GET_ALL_CUSTOM_NODE_PROP_DEFS requires write access to call it so make sure to handle that accordingly.
Good luck.
<!--$executeService("SS_GET_ALL_CUSTOM_NODE_PROP_DEFS")-->
<!--$if rsExists("CustomNodePropDefs")-->
<!--$if isTrue(rsFindRowPrimary("CustomNodePropDefs", "[customPropName]"))-->
[custom property exists]
<!--$else-->
[custom property doesn't exist]
<!--$endif-->
<!--$endif-->
Note: It is a misprint in both the 10gR3 and 11g Site Studio Technical Reference Guides when it says the SS_GET_ALL_CUSTOM_NODE_PROP_DEFS service returns a ResultSet named "CustomNodePropertyDefs"; it is actually "CustomNodePropDefs". In fact, my blog has the only reference to "CustomNodePropDefs" on the internet...seriously. Also, SS_GET_ALL_CUSTOM_NODE_PROP_DEFS requires write access to call it so make sure to handle that accordingly.
Good luck.
Thursday, January 27, 2011
► What website section is this?
As you know, the Web Site Section metadata field (xWebsiteSection) is in the format: siteId:nodeId
That's not particularly helpful when using the default Headline View on search results pages of the content server. Display the section label instead by adding this dynamic HTML resource:
<@dynamichtml slim_table_cell_text@><$if ColumnProperties.id like "xWebsiteSection"$><$"<$theSection = eval(#active.xWebsiteSection)$>"$><$"<$siteID = strSubstring(theSection, 0, strIndexOf(theSection, \":\"))$>"$><$"<$sectionID = strSubstring(theSection, strIndexOf(theSection, \":\")+1)$>"$><$"<$if strLength(theSection) > 0$>"$><$"<$ssGetWebsiteName(siteID) & \" : \" & ssGetNodeLabel(siteID,sectionID)$>"$><$"<$endif$>"$><$else$><$include super.slim_table_cell_text$><$endif$><@end@>
Good luck.
Wednesday, January 26, 2011
► What's my exact dDocAccount access?
It's often helpful to know what access rights (RWDA) you have to account(s). By default, "My Profile" only displays the account(s) that you have at least (R)ead access to. A simple change to the user_info.htm template should clear things up (putting this in a custom component is a best practice, but won't be discussed here):
Around line 150, you will find:
<td colspan=2 nowrap><span class=infoLabel><$lc("wwAccounts")$></span></td><td colspan=2><span class=tableEntry><$if UserAccounts$><$UserAccounts$><$else$><$lc("wwNoAccountsDefined")$><$endif$></span></td><td></td>
Insert the bold:
<td colspan=2 nowrap><span class=infoLabel><$lc("wwAccounts")$></span></td><td colspan=2><span class=tableEntry><$if UserAccounts$><$rsMakeFromString("UserAccountsRS", UserAccounts)$><$rsSort("UserAccountsRS", "row")$><$accountOutput = ''$><$loop UserAccountsRS$><$if userHasAccessToAccount(row, 15)$><$accountOutput = accountOutput & row & ' (RWDA)<br />'$><$elseif userHasAccessToAccount(row, 7)$><$accountOutput = accountOutput & row & ' (RWD)<br />'$><$elseif userHasAccessToAccount(row, 3)$><$accountOutput = accountOutput & row & ' (RW)<br />'$><$elseif userHasAccessToAccount(row, 1)$><$accountOutput = accountOutput & row & ' (R)<br />'$><$endif$><$endloop$><$accountOutput$><$else$><$lc("wwNoAccountsDefined")$><$endif$></span></td><td></td>
Good luck.
Subscribe to:
Posts (Atom)