Two days ago I got a question from a friend that wanted to know how to push files to the weblayout from withing a UCM (WebCenter Content) component. We knew it was no longer supported to do things the way we used to in 10g, but how it should be done was not immediately obvious. So I set out on a quest to find out. The two resources I found most helpful were Kyle's blog (that touches this subject briefly) and most importantly the 11g UCM default components (those in the middleware home), especially the YahooUserInterfaceLibrary and the ContentFolios component.
Note: Although most weblayout publishing features are already available in UCM 10g, not all features in UCM 11g are supported in UCM 10g. This article will focus on how to properly setup resource publishing for 11g and may therefore not work as expected on UCM 10g.
When to use WebLayout Publishing
A lot of times when you develop some functionality in an UCM component you will end up making UI templates which use external resources like images, cascading stylesheets and Javascript files. These external resources are the primary candidates for weblayout publishing. Of course you could put the CSS and Javascript inline in your templates, but having them as external resources gives us caching possibilities.
Different types of WebLayout Publishing
There are basically two ways of publishing resources to the weblayout, either copy files from the component to the weblayout (static files) or generate the weblayout files based on an iDoc template (dynamic files).
In UCM there are three mechanisms to do weblayout publishing, which will be discussed one at a time.
- Publishing Static Files
- Publishing Dynamic Files
- Bundling Published Files
But first we need to touch the concept of 'class' which is used by all three mechanisms. A class can be thought of as a package, a namespace or a tree structure (like DOM), each part separated by a ':' (colon). An example will make it all clear (at least I hope so).
image:companyX:functionalityZ
The class name in the above example I could use for all images at company X for functionality Z. It is primarily a grouping mechanism (at least as far as I understand). It will be more obvious once we start using it, I promise.
Publishing Static Files
Static resources will just be copied as-is to the desired weblayout location (this is most like the old way of doing this by adding a weblayout entry in the build settings). These resources will only be rarely published automatically (think disabling/enabling component).
You can publish static files by creating a static table in the Component Wizard that merges with 'PublishedStaticFiles' (you can pick it from dropdown list). The tables has the following columns:
srcPath
: the source path to the file or directory contained in the component, relative to the component directory (field is idoc evaluated)
path
: the target path to a file or directory in the weblayout directory, relative to the weblayout directory (field is idoc evaluated)
class
: the class of this resource, as discussed above
loadOrder
: the load order of this resource, the higher the load order, the later it will be published, allowing you to override already published resources
doPublishScript
: a piece of idoc script that should set the idoc variable 'doPublish' (it defaults to 0 (false) which means the resource will not be published) (obviously this field is idoc evaluated)
canDeleteDir
: whether or not the directories in the 'path' can be deleted when the component is disabled/uninstalled (note: it should only delete a directory when there is no longer a published resource using that directory)
Time for an example:
<@table MyPublishTestComponent_PublishedStaticFiles@>
srcPath |
path |
class |
loadOrder |
doPublishScript |
canDeleteDir |
publish/img/icons/ |
images/publishtest/ |
image:publishtest:icons |
10 |
<$doPublish = 1$> |
1 |
publish/img/other/someOtherImage.png |
images/publishtest/someOtherImage.png |
image:publishtest:other |
10 |
<$if isTrue(someConfigVar)$><$doPublish = 1$><$endif$> |
1 |
publish/js/utils.js |
resources/publishtest/js/utils.js |
javascript:publishtest:utils |
10 |
<$doPublish = 1$> |
1 |
<@end@>
The above example does the following:
- always publishing all the files from a directory in my component ($MYCOMPONENT/publish/img/icons/) to a weblayout directory ($WEBLAYOUT/images/publishtest/).
- only when someConfigVar is set to true publishing a specific image ($MYCOMPONENT/publish/img/other/someOtherImage.png) to the weblayout ($WEBLAYOUT/images/publishtest/someOtherImage.png)
- always publishing a javascript utility ($MYCOMPONENT/publish/js/utils.js) to the weblayout ($WEBLAYOUT/resources/publishtest/js/utils.js)
Publishing Dynamic Files
Dynamic resources are idoc templates that are evaluated and the result is copied to the desired weblayout location. These resources will be published regularly (at startup).
You can publish weblayout files by creating a static table in the Component Wizard that merges with 'PublishedWeblayoutFiles' table (again, you can pick it from the dropdown list). The tables has the following columns:
template
: the name of the template (defined in a component)
srcPath
: the source path to the file contained in the component, relative to the component directory. This field is only used when the template column is empty (this field is idoc evaluated)
path
: the target path to a resulting file in the weblayout directory (idoc evaluated), relative to the weblayout directory
class
: the class of this resource, as discussed above
loadOrder
: the load order of this resource, the higher the load order, the later it will be published, allowing you to override already published resources
doPublishScript
: a piece of idoc script that should set the idoc variable 'doPublish' (it defaults to 0 (false) which means the resource will not be published) (obviously this field is idoc evaluated)
Time for an example:
<@table MyPublishTestComponent_PublishedWeblayoutFiles@>
template |
srcPath |
path |
class |
loadOrder |
doPublishScript |
MY_PUBLISH_TEST_CSS |
|
resources/publishtest/css/base.css |
css:publishtest:base |
10 |
<$doPublish = 1$> |
MY_PUBLISH_TEST_VALIDATIONS |
|
resources/publishtest/js/validations.js |
javascript:publishtest:validations |
10 |
<$doPublish = 1$> |
|
templates/constants.idoc |
resources/publishtest/js/constants.js |
javascript:publishtest:constants |
10 |
<$doPublish = 1$> |
<@end@>
The above example does the following:
- always publish the result of the MY_PUBLISH_TEST_CSS to a weblayout file ($WEBLAYOUT/resources/publishtest/css/base.css).
- always publish the result of the MY_PUBLISH_TEST_VALIDATIONS to the weblayout file ($WEBLAYOUT/resources/publishtest/js/validations.js)
- always publish the result of the specified template file ($MYCOMPONENT/templates/constants.idoc) to the weblayout file ($WEBLAYOUT/resources/publishtest/js/constants.js)
Publishing Bundles
Now this is where the fun really starts and where the use of classes finally make sense. Bundle publishing packs together multiple published resources into a single file (a bundle). As far as I know this works only for Javascript and CSS resources (starting with class 'javascript' or 'css').
To use this functionality by creating a static table in the Component Wizard that merges with 'PublishedWeblayoutBundles' table (again, you can pick it from the dropdown list). The tables has the following columns:
bundlePath
: the target path to a resulting file in the weblayout directory, relative to the weblayout directory
includeClass
: include certain classes from the bundle
excludeClass
: exclude certain classes from the bundle
loadOrder
: the load order of this resource, the higher the load order, the later it will be published, allowing you to override already published resources
Time for an example:
<@table MyPublishTestComponent_PublishedWeblayoutBundles@>
bundlePath |
includeClass |
excludeClass |
loadOrder |
resources/publishtest/js/bundle.js |
javascript:publishtest: |
|
10 |
<@end@>
The above example does the following:
publish all resources with the class 'javascript:publishtest:', in this article it'll combine the statically published utils.js file ($WEBLAYOUT/resources/publishtest/js/utils.js), the dynamically generated validation.js file ($WEBLAYOUT/resources/publishtest/js/validations.js) and the dynamically generated constants.js ($WEBLAYOUT/resources/publishtest/js/constants.js) into a single javascript file, bundle.js ($WEBLAYOUT/resources/publishtest/js/bundle.js).
Thanks for reading through all my rambling, I hope you've found something useful.