Credit: IBM
Introducing IBM Connections Customizer
Editor’s note: The original content of this article appeared in App Dev Resources
for IBM Connections Customizer on GitHub, and has since been
updated with additional feature information.
If you’ve ever wanted to change the way IBM Connections looks or behaves,
the new IBM Connections Customizer gives you the control you’ve been
looking for. In this article, you’ll learn how Customizer lets you change
the Connections user interface, and how you can get started using
Customizer right away.
Customizer is a middleware service that lets you modify the IBM Connections
user experience. In essence, it’s a proxy between IBM Connections and the
end-user. It can intercept and modify requests and responses, so it can
customize anything that flows through it, such as the behavior of APIs and
the look-and-feel of the user interface.
The IBM Connections Customizer model is simple. The service performs
customizations by injecting JavaScript, CSS, or other web resources into
the HTML pages returned by IBM Connections in response to end-user
requests generated in standard components like Communities, Profiles,
Files, Homepage, and so on, as the user navigates the apps. The
customization details (typically, what code should be inserted and on what
requests) are defined by applications stored in the IBM Connections
Application Registry (“App Reg”).
App Reg is a centralized design repository used to store and retrieve
applications that customize and extend a variety of different IBM
Connections services, including Customizer. In the cloud, App Reg is
available to organization administrators via the Admin > Manage
Organization > Organization Extensions menu path. There you
can create and manage Customizer applications, which are simply JSON files
containing design information defining the components that need to be
targeted and the actions that need to be performed. Listing 1 shows a
simple Customizer application.
Listing 1. Hello World Connections Customizer
application
{ "services": [ "Customizer" ], "name": "Simple Customizer Sample", "title": "My First Customizer App", "description": "Perform a modification to the Connections Homepage", "extensions": [ { "name": "Hello World Extension", "type": "com.ibm.customizer.ui", "path": "homepage", "payload": { "include-files": [ "helloWorld/helloWorld.user.js" ], "include-repo": { "name": "global-samples" } } } ] }
This application simply prepends “Hello World” to the title string in the
Connections home page.
The JSON should be easy to understand.
- The app is named “Simple Customizer Sample” and it extends the
Customizer service. - It contains one extension, named “Hello World Extension”. (Note that
apps can have many extensions.) - The extension type (“com.ibm.customizer.ui”) shows that it is a
customization of the UI. - The extension path (“homepage”) shows that the customization applies
to the Connections homepage. - A file named
helloWorld.user.js
is to be injected into
the homepage.
Tables 1 and 2 summarize the properties you can use in the JSON.
Table 1. Generic Customizer application
properties
Property | Description |
---|---|
Name | String used to identify the extension |
Title | Short string description (translatable for international audiences) |
Description | Long string description (translatable for international audiences) |
Services | The service(s) with which the application is associated |
Type | String used to identify the extension point being implemented – required. Valid values: com.ibm.customizer.ui com.ibm.customizer.api |
Path | String used to identify the component to customize:
*Unlike the other path values, global does not represent a real URL path element. It is a keyword meaning “match all URLs.” |
Table 2. Payload Customizer application
properties
Name | Description |
---|---|
match: url | A regular expression used to provide more fine-grained target resource matching than the broad match specified in the path property |
match: user-name | String used to identify one or more users as the target for the customization. Note that user names may not be unique in a given organization. |
match: user-id | String used to identify one or more users as the target for the customization. This property is unique in a given organization. |
match: user-email | String used to identify one or more users based on email address value |
include-files | List of files to be inserted into the response for a matched page request |
include-repo: name | String used to identify the repository where the include-files are stored |
A closer look at Customizer properties
As shown in Table 1 and Table 2, Customizer properties fall into two
categories:
- Generic App Reg Properties
Properties defined for all App Reg
applications across all services - Customizer service properties
Properties specific to the
Customizer service (everything in Table 2)
App Reg requires that applications specify the generic
name, title,
description, service, and
type property values. The Application Registry
specification does not require the path property to be
specified when an application is created, but the Customizer service puts
it to good use for every request it processes, as we’ll soon see.
Therefore, in reality a path value is required for
Customizer applications to work properly.
Of the generic properties in Table 1, only type and
path need further discussion.
A type value is always the name of an extension point
defined by a service. At present, Customizer defines only two extension
points:
com.ibm.customizer.ui
A declaration that the
Customizer extension modifies the IBM Connections UI. The extension
will be handled in accordance with a prescribed UI extension pattern.
For example, any include files specified in the payload are injected
into the response document.com.ibm.customizer.api
This extension point is
reserved for future use. As a middleware proxy, Customizer can modify
API behaviors, but that feature is not available in the current
Customizer release.
The path property value represents a path element in the
IBM Connections request URL, which in most use cases corresponds to a
standard IBM Connections component. Consider the URLs displayed in Listing
2.
Listing 2. Examples of IBM Connections URLs
/* homepage */ //w3-connections.ibm.com/homepage/web/updates/#myStream/imFollowing/all //w3-connections.ibm.com/homepage/web/updates/#myStream/statusUpdates/all //w3-connections.ibm.com/homepage/web/updates/#myStream/discover/all //w3-connections.ibm.com/homepage/web/updates/#atMentions/atMentions /* communities */ //w3-connections.ibm.com/communities/service/html/ownedcommunities //w3-connections.ibm.com/communities/service/html/followedcommunities //w3-connections.ibm.com/communities/service/html/communityinvites /* files */ //w3-connections.ibm.com/files/app#/pinnedfiles //w3-connections.ibm.com/files/app#/person/7f37da40-8f0a-1028-938d-db07163b51b2 /* blogs */ //w3-connections.ibm.com/blogs/roller-ui/allblogs?email=joe_schmoe //w3-connections.ibm.com/blogs/roller-ui/homepage?lang=en_us /* wikis */ //w3-connections.ibm.com/wikis/home?lang=en-us#!/mywikis?role=editor
These sample URLs follow a clear pattern, in which the next element after
the IBM Connections cloud domain name identifies the Connections component
or application handling the request. The possible values of this element
are the path values in Table 1 (homepage, communities,
files, and so on).
As http requests flow through Customizer, it can query the Application
Registry for any extensions relating to a given request URL and reduce the
scope of the result set by specifying the particular in-context
path value. A typical REST request from Customizer to
App Reg for Files customizations might look like this:
appregistry/api/v3/services/Customizer/extensions?type=com.ibm.customizer.ui&path=files
This translates as, “Get all UI extensions registered for the Customizer
service that apply to Files.” This explains why Customizer extensions must
contain both a type and a path value.
One detail to note about the path value is the special
global keyword. This supports the use case where an extension needs to
apply to all requests. For example, suppose you need to display corporate
footer text at the bottom of every page in IBM Connections. Clearly, it
would be inefficient to create an extension for every possible
path value. The global
path value solves
the problem.
Processing payload properties
In response to the request shown above, App Reg returns the extensions that
match the criteria as a single collection of one or more JSON files just
like the one in Listing 1. The Customizer service implementation then
parses and applies the design metadata in the returned extensions, and
that is where the payload data comes into play.
App Reg itself does not use payload properties. It simply passes them to
the nominated service (Customizer, in this context) for processing.
Fine grained URL matching
The generic path property provides a coarse means of
querying the Application Registry for extensions pertaining to a given IBM
Connections component. The optional match properties
inside the Customizer payload let you fine-tune extension filtering, to
determine whether an extension is applied to a given URL request.
The match url property takes a regular expression and
evaluates it against the current URL. If it matches, the extension is
applied; otherwise, the extension is not applied. This is a powerful
feature, as the following code snippets demonstrate.
Listing 3 shows a Communities extension that has a fine-grained URL match
applied on lines 14 – 16. In this case, the extension is applied only if
the Communities followedcommunities
URL is being processed.
The extension is ignored for other Communities URLs like those shown in
Listing 3; for example, ownedcommunities
,
communityinvites
, and so on.
Listing 3. Customizer application with URL
matching
{ "services": [ "Customizer" ], "name": "Communities Customization", "title": "UI Customization for Communities I Follow", "description": "Sample to modify Connections Communities", "extensions": [ { "name": "Followed Communities Customizer", "type": "com.ibm.customizer.ui", "path": "communities", "payload": { "match": { "url": "followedcommunities" }, "include-files": [ "flipCard/commListCardsFlipStyle.user.js " ], "include-repo": { "name": "global-samples" } 2 } } ] }
Similarly, the following fragment shows how a single global extension can
be applied to Homepage and Communities but nothing else:
Listing 4. Global Customizer application with
URL matching
… "path": "global", "payload": { "match": { "url": "homepage|communities" }, …
Note: The design of some IBM Connections components, like
Homepage, is based on the Single Page App paradigm. For example, look at
the Homepage URLs in Listing 2. All contain hashtags, which means that new
http requests are not fired as the user navigates around the page.
Therefore, Customizer is not notified when, for example, a user moves from
imfollowing
to atmentions
. In contrast,
Customizer is notified when a user in Communities moves from
ownedcommunities
to followedcommunities
. You can
target individual Communities URLs with the match url property, but you
cannot use the same technique to match the Homepage hashtag URLs. Instead,
your homepage extension would need to inject a script that listens for
hash change events and responds accordingly. For an example, look at the
handleHashChangeEvent()
function in the homepage sample newsRiverSectionedHashChange.user.js
. (All the latest
samples are in the samples folder of ibmcnxdev/customizer on GitHub.)
It’s easy to imagine many other uses for fine-grained match criteria. For
instance, if you want to apply a customization to any Files URL that
contains a GUID, you can set the path value to
“files
” and the match url value to
“id=[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}
”. For an
example of such a URL, take another look at Listing 2.
Note: The braces in the regular expression must be escaped
(that is, preceded by a backslash character) when included in JSON stored
in App Reg.
Fine-grained matching based on the active user
The match property also accepts various user-related
conditions based on the current user’s name or id. In both cases, you can
specify single- or multi-value parameters—or, in JSON parlance, a single
string value or an array of string values. Listing 5 shows how a
Communities extension can target specific users based on their user
names.
Listing 5. Customizer application targeting
specific users by name
… "path": "communities", "payload": { "match": { "user-name":[ "Jane Doe", "Joe Schmoe" ] }, …
Since user names are not always unique in an organization, you might
inadvertently target unintended users with this technique, so that any
user with the same name see the extension. To avoid this, you can use the
user-id match property instead, as shown in Listing
6. Note that the term “subscriber id” is sometimes used in place of “user
id” in the IBM Connections user interface and documentation.
Listing 6. Customizer application targeting
specific users by ID
… "path": "communities", "payload": { "match": { "user-id":[ "20071635", "20071656" ] }, …
The story so far
So far, we’ve learned that:
- Customizer is a proxy through which all Connections requests and
responses flow. - Based on the URL requests it processes, Customizer queries App Reg to
ascertain if customizations have been registered for Connections
components. - When App Reg returns application definitions to Customizer, Customizer
uses the metadata in the JSON payload to decide if a customization
should be applied.
Figure 1 shows this request processing mechanism.
Figure 1. IBM Customizer request life cycle
Now, how does Customizer manage the file resources listed in the
include-files property?
Managing application file resources
The include-files payload property lists one or more files
to be inserted into the Connections http response, thus becoming part of
the DOM structure loaded in the user’s browser. Listing 1 shows a simple
single-item value for this parameter: “helloWorld/helloWorld.user.js”,
where helloWorld is a folder and helloWorld.user.js is a JavaScript file
in it.
On IBM Connections Cloud, files declared in the
include-files property are stored in one of two
locations:
- a private IBM GitHub organization (github.ibm.com, accessible only to
IBM) - a public IBM Connections GitHub organization
(https://github.com/ibmcnxdev)
The include-repo payload property value identifies the
name of the actual repository. For example, Listing 1 and Listing 3 show
an include-repo object with a name value of
“global-samples”. This is a reference to a repository on github.ibm.com
that contains ready-made samples that any IBM Cloud tenant can use in a
Customizer app. “Hello World”, “FlipCard,” and the other samples described
later in the Standard Samples section are all located in this repository.
IBM Customizer resolves the GitHub organization referred to in the JSON
markup; that is, whether it is in the private or public location. IBM has
control over the repositories in both locations, so duplicate names are
not allowed.
Customizer assets like global-samples are directly
provisioned to github.ibm.com by the IBM Customizer team. Since this is a
private GitHub organization, you can’t explore it to discover available
repositories, but you will of them through public samples, documentation,
and other enablement materials (such as this article). It is envisaged
that an enhanced App Reg IDE may expose these repositories through the UI
in a future release.
You can freely explore the assets available on the public IBM Connections
Developers GitHub organization. You can leverage any Customizer repository
in this organization, or collaborate with the IBM Customizer team to
create your own repository in this location. This could be a fork of an
existing repository or a brand new repository created for you from
scratch, depending on your needs.
If you are familiar with GitHub and have a GitHub account, you are well on
your way. If not, you can start learning about GitHub here
using this quick 10 minute guide. Once you know the rudiments, creating a GitHub account is straight- forward and free for
public and open-source projects.
Once you have a GitHub account, create a source repository on the public
github.com/ibmcnxdev organization to store and manage your Customizer
include files. When you are ready to deploy those resources to IBM
Connections Cloud, complete the following steps.
- Share your repository with IBM by adding “ibmcnxdev” as a
collaborator. IBM creates a fork of your repository under
github.com/ibmcnxdev and grants you read access by default. - Work on your extension in your own repository as needed, and then
issue a pull request to IBM when your extension is ready. - IBM merges your pull request once its acceptance criteria are met.
Repository files are pushed to IBM Customizer via a webhook upon
merge. - Repeat, starting with step 2, as needed for extension updates.
In Step 2, issue a pull request across forks (in GitHub parlance). Your own
repository, which contains the latest changes, is always the “head fork”,
while the “base fork” refers to the repository on
github.com/ibmcnxdev.
Step 3 involves a lightweight summary review by IBM, which looks at various
aspects of the proposed customization, primarily from a performance and
security standpoint. However, ultimate responsibility for the behaviour of
the Customizer application remains that of the customer who creates or
adopts the extension. The review process by IBM provides no guarantee
whatsoever of protection against adverse security or performance impacts.
Figure 2. IBM Connections Developers organization on
GitHub
Tip: More information on how to integrate your Customizer
include files with IBM Connections Cloud is available in the IBM Connections Customizer Episode 2 video on opencode4connections.org.
Restricting access to include-files
By default, any IBM Cloud tenant can use the contents of any repository in
either GitHub organization for its Customizer apps. This is flexible and
convenient, but may not always be the right solution. If you want to keep
the include-files for your Customizer apps private, or restrict usage to a
subset of tenants, you can use one of these solutions.
Inside a Connections Customizer include file
What exactly does the helloWorld.user.js
include file do?
Listing 8 shows the code. Certain variable names and comments have been
trimmed for readability, but nothing that affects the execution of the
script.
Listing 8. Hello World include file
if(typeof(dojo) != "undefined") { require(["dojo/domReady!"], function(){ try { // utility function to wait for a specific element to load... var waitFor = function(callback, eXpath, eXpathRt, maxIV, waitTime){ if(!eXpathRt) var eXpathRt = dojo.body(); if(!maxIV) var maxIV = 10000; // intervals before expiring if(!waitTime) var waitTime = 1; // 1000=1 second if(!eXpath) return; var waitInter = 0; // current interval var intId = setInterval( function(){ if(++waitInter < maxIV && !dojo.query(eXpath,eXpathRt).length) return; clearInterval(intId); if( waitInter >= maxIV) { console.log("**** WAITFOR ["+eXpath+"] WATCH EXPIRED!!! interval "+waitInter+" (max:"+ maxIV +")"); } else { console.log("**** WAITFOR ["+eXpath+"] WATCH TRIPPED AT interval "+waitInter+" (max:"+maxInter+")"); callback(); } }, waitTime); // end setInterval() }; // end waitFor() // here we use waitFor to wait for the // .lotusStreamTopLoading div.loaderMain.lotusHidden element // before we proceed to customize the page... waitFor( function(){ // wait until the "loading..." node has been hidden // indicating that we have loaded content. dojo.query("span.shareSome-title")[0].textContent="Hello World! "; }, ".lotusStreamTopLoading div.loaderMain.lotusHidden"); } catch(e) { alert("Exception occurred in helloWorld: " + e); } }); }
For a simple Hello World example, this may appear more complicated than you
would expect, but closer inspection simplifies matters considerably.
- Most of the code is a re-usable template.
- Only one line of code (line 32) is needed for the actual Hello World
UI update. - The IBM Connections classic user interface uses Dojo, so the code is
injected into a Dojo structured page.
The JavaScript code first validates that Dojo itself is loaded, and then
uses a standard Dojo utility (domReady
) to wait for the DOM
to fully load before calling a bound function to perform the
customization. Lines 2 – 23 define a function (waitFor()
)
that waits a maximum of 10 seconds for the page to fully load. If the page
loads within 10 seconds, the function executes a callback function.
Otherwise, an error is logged to the JavaScript console.
Figure 3. Hello World extension for IBM Connections
Homepage
The waitFor()
function call passes in the callback function to
manipulate the DOM and modify the UI. The interesting part of the callback
function (line 32) locates a DOM element and assigns “Hello World” as the
text content. When Customizer loads and runs this extension, the IBM
Connections Homepage is modified as shown in Figure 3.
If we view the source of the IBM Connections Homepage in the browser, we
can see the code injection at the bottom of the page, as shown in Listing
9.
Listing 9. Customizer script
injection
… <script type='text/javascript' src="http://www.ibm.com/files/muse-static/helloWorld/helloWorld.user.jss?repoName=global-samples"> </script> …
URLs with ‘/files/customizer’ path are handled by Customizer, and in this
example it fetches the ‘/helloWorld/helloWorld.user.js’ script from the
‘global-samples’ repository. Your JavaScript code can use such URLs to
directly load other resources from repositories you have access to in IBM
Connections Cloud. For instance, since ‘global-samples’ is a public
repository that is available to all organizations, any Customizer
application can reference resources contained inside it using links of
this format:
/files/customizer/folder-name/resource-name.xxx?repoName=global-samples
The profiles sample described later uses a JavaScript code
injection to load a CSS file from the profiles folder in the
global-samples repository. Be ware that this type of broad access to
repositories can also be prevented using the acl.ids mechanism described
earlier.
Tip: IBM Connections web pages contain many predefined
JavaScript variables that Customizer extensions can use. For instance,
lconn is an object with many properties that any extension script can
exploit. Thus on line 3, replacing “Hello World: ” with “Hello ” +
lconn.homepage.userName + ” ” dynamically includes the current user in the
Homepage customization. Exploring the lconn
object and others
like it will show you many valuable features that your extensions can
leverage.
Standard samples
Besides Hello World, a number of other ready-made Customizer examples are
available for experimentation. You can always find the latest samples in
the samples folder of ibmcnxdev/customizer on GitHub.
Each sample has its own subfolder, which contains the App Reg design
definition (JSON file) and the resources to be injected to perform the
customization (JavaScript, CSS). Take a look at the following examples:
flipcards
This extension provides an alternative rendering for the Communities
pages, so that a user’s communities can be displayed as flip cards rather
than a table of rows. Figure 4 shows a list of three communities, with the
traditional row-based rendering on the left-hand side juxtaposed with the
flip card layout on the right. Each flip card displays the Communities
logo until the user hovers over it, whereupon the card is flipped to
display the details of the community.
Figure 4. Communities page before and after flipcard
customization
flipCard.json
follows the standard App Reg pattern used in the
Hello World example. commListCardsFlipStyle.user.js
uses the
sample Dojo wrapper to envelope the customization, but the code itself is
significantly more advanced and serves to give a more real-world
indication of what’s possible with Customizer extensions. When the
customization is applied, look for the Toggle Extension control on the
Communities page. Clicking the button lets the user switch between the
standard row layout and the flip card format.
newsRiver
This extension targets the IBM Connections Homepage and reformats the
layout of the activity stream updates by accentuating the space
surrounding each entry. Figure 5 shows the Homepage with the newsRiver
customization. Note how the entries display as sections against a pink
backdrop. Also notice that the Hello World extension is also applied to
the Home page. This shows how multiple App Reg extensions can target the
same IBM Connections path. If you view the source of the page, you will
see two JavaScript file injections.
Figure 5. Multiple extensions for IBM Connections
homepage
profiles
This extension delivers a more sophisticated rendering of the page that is
displayed when the user selects the “My Profile” dropdown menu option in
IBM Connections. The new appearance is achieved with stylesheet updates.
In the profiles
subfolder,
profilesCustomization.js
simply inserts a link to
profilesCustomization.css
, which does all the work. The new
look is shown in Figure 6. Note the inclusion of a new page header
graphic, the relocation of action buttons, and so forth.
Figure 6. Profile page extension
Ordering include-files and extensions
All the preceding samples are simple standalone projects. Customizer
applications typically have one main entry point (for example, main.js),
and this resource is referenced in the include-files
payload property and rendered in the modified HTML output. However the
include-files property is an array and can contain
more than one file reference. The snippet in Listing 10 is an example from
the enhanced-activity-stream project available on the
OpenCode4Connections GitHub repository.
Listing 10. Multiple Include Files
… "payload": { "include-files": [ "enhanced-activity-stream/core.js", "enhanced-activity-stream/scroller.js", "enhanced-activity-stream/notifier.js" ] } …
The three JavaScript files referenced in Listing 10 are injected in the
order they are listed.
Although the samples we’ve looked at have just a single extension each,
Customizer applications can contain many extensions. An extension ideally
represents a project that carries out a specific task or a tightly related
set of tasks. The include-files referenced in the extension must be
contained in a single include-repo; that is, it is a strict one-to-one
mapping. This makes sense from an organizational standpoint. Extensions do
specific jobs and the tools for these jobs are typically found in a single
dedicated repository. If your application consists of many related tasks
and the tools to carry out the work are many and varied, it would make
sense for your application to have multiple extensions, where each
extension manages a discrete function and maps to a repository designed
for that purpose. However, note that Customizer loads the extensions in
alphabetical order, not the order in which they appear in the JSON
definition of the application. If your application has multiple extensions
and is sensitive to the load order of the include files, you can control
the load order by applying an ordered naming convention to your
extensions.
NOTE: The alphabetical order of extensions applies across all applications.
For example, you may have two separate apps that target the IBM
Connections homepage. The App Registry sorts the extensions defined in
both applications as a single alphabetical list and returns them to
Customizer for injection in that order into the IBM Connections homepage.
In most cases, the order of injections does not present a problem. You can
see the order at any time by viewing the Connections page source and
looking at the <script> tags inserted at the bottom of the page, as
shown in Listing 9.
Getting up and running
The sample customizations discussed in this document are available to any
IBM Connections Cloud tenant organization. Applying a sample customization
is an easy way to get started with IBM Connections Customizer. Any sample
can be used by importing the relevant JSON file into an organization’s
Application Registry. For example, you can take a copy of the
helloWorld.json file from the helloWorld samples project published on the
Customizer GitHub repository, and import it into App Reg.
- Go to https://github.com/ibmcnxdev/customizer.
- Navigate to the helloWorld.json file and copy/paste the contents to a
local file. - As Admin user in your IBM Connections Cloud organization, go to
Admin > Manage Organization > Organization
Extensions. - Click the new Apps Manager link to take you to the Pink Application
Registry. (Note that this step is temporary, while the new IBM
Connections Pink user interface components are being integrated into
the cloud.) - Click New App.
- When the App Editor appears, click the Import button.
- Select your local copy of helloWorld.json.
- Insert a match criterion like the one in Listing 5 so that the
extension is applied only to you. Match to your user-name, e-mail
address, or user id. - Click Save to save the application into Application
Registry. - Refresh the IBM Connections Homepage and verify that the Hello World
extension appears.
Tip: The steps above are covered in the ‘IBM Connections Customizer Episode 01″ enablement video on OpenCode4
Connections.
You can experiment with the other samples in a similar way. You may notice
that some samples use a JavaScript filename notation that follows the
GreaseMonkey naming convention: somename.user.js. These customizations
were originally developed as GreaseMonkey scripts using browser-based
extensions. They were then deployed on the server in IBM Connections as
Customizer extensions. This is standard practice for developing Customizer
apps. First create a new browser extension using a user script technology
like GreaseMonkey for Firefox or TamperMonkey for Chrome. Once you are
happy with the local customization, submit the resources to IBM for
review. The JavaScript and CSS files you create using GreaseMonkey or
TamperMonkey become your Customizer include files. You can then invoke the
customization by creating a Customizer extension (just like the JSON files
contained in the standard samples) in the Application Registry.
Some points to note regarding Customizer
applications
Support for Customizer applications follows the same policy as any other
customization to the IBM Connections user interface. IBM Support can
address questions about the customization process, but cannot address
questions about the particulars of your customization.
Listing 2 provides the list of currently supported paths for Customizer.
This list currently encompasses all core IBM Connections components with
the exception of the Administration URLs (BSS) and related IBM
collaboration components like Docs, Meetings, Chat, and Verse. The list
may be expanded to include these and other components in the future.
Customizer extensions are currently restricted to the organization in which
they have been added. Users from one organization may have access to
communities in other organizations if they have been invited, but they
will not see any customizations added to the “external” communities.
Useful links
Downloadable resources
Credit: IBM