WebCenter Spaces – steps to change the template and skin

April 22, 2014

By: Andreja Sambolec – Application Consultant

Create a new template and skin

If you want to change the default template and skin for your Spaces application, the first step is to create a new template and skin based on the OOTB template which looks similar to the design you want, and apply them to the Spaces application.

In our example we want to have the menu on the top of the page so we created a new template based on the ‘WebCenter Spaces Top Navigation’ template.

 

You can create a new template and skin from the ‘Resources’ tab (Administration-> Spaces-> select Space and select ‘Edit space’).

You can apply your new template and skin using the General tab:

skins1

The default menu looks like this:

skins2

We want to have something like this:

skins3

And this is how the drop-down menu should look:

skins4

 Change the template

We need to change the template because the logo icon has to be on the left side of the menu.

The best way to find what has to be changed is:

  • Create a new portal or ADF application in jDeveloper
  • Create a new .jspx page
  • Copy the templates source code and paste to .jspx file

Now you can easy see the structure of the template and decide what to change.

  1. Using browser ‘Developer Tools’ you can find which component holds the menu:
    skins5
  2. Using jDeveloper you can see the <af:decorativeBox  id =‘db1’ > component  contains  the Global navigation menu and the logo. The component with id set to ‘pt_pgl4’ holds the Top navigation menu.
  3. We decided to replace decorativeBox component with panelGroupLayout component.
    1. Replace af:decorativeBox with af:panelGroupLayut
    2. Delete facet:center
    3. Set layout property for panelGroupLayout to ‘horizontal’
    4. Create two panelGroupLayout components inside of ‘db1’ to hold the logo icon and the menu
    5. Set layout to ‘vertical’ for the second panelGroupLayout
    6. Cut and paste <cust:panelCustomizable id=”pcust1″> inside of the first panelGroupLayout
    7. Cut and paste  <af:panelGroupLayout id=”gtbppgl3″> inside of the second panelGroupLayout
    8. Cut and paste  <af:panelGroupLayout id=”pt_pgl4″> inside of the second panelGroupLayout
    9. Delete the component with id ‘gtbppbl1’
      skins6

This is the result:
skins7

  1. Place the Search input box to the right side:
    1. Using Chrome Developer tool you can see that we need to change the component with id= ‘pcust2’  because this component holds the menu:
      skins8
    2. You will see that the task-flow is used for the search component and it’s placed as the first component inside of ‘pcust2 ‘ so we just need to move it to the last place:
      skins9

New order:
skins10

 

  1. Change Spaces logo using Spaces Settings tab
    skins12
  2. Search for ‘gtbrspmxi1’ component and change the width and the height property for af:image component to 74px and also change the source property to “#{WCPrepareImageURL[spaceContext.space[WCAppContext.currentScope.name].metadata.logo][‘LOGO75’]}”skins13

 

  1. Set the property ‘rendered’ to false for ‘gtbrspmxgl2’ (to hide the link next to logo icon)

The result:
skins14

Change the skin

Next we want to change the menus background color.

The background color for the global menu should be in white.

Steps to change:

  1. Using browser Developer Tool, check which style is used to apply this color

When we deselect the background image for .WCSiteTemplateBackground, .x1r4,

we don’t see the  background color  anymore  on the top of the page .
skins15

  1. So, open the source of your custom skin and add this:

.WCSiteTemplateBackground{

background-image:none;

}
skins16

When you are checking out the styles for some components, you will not see the name of the component but some code, for example, .x106 (the skin is compressed).

You can apply changes using those compressed names or if you know, for example, which component is used you can try with af|commandLink. You could also open the page fragment in jdeveloper and check which component and style class is used and use it in your skin to add changes.

 

Change the navigation model

We also want to add some new pages, so we are going to change the navigation model.

  1. Create a new one based on default one (you can check which model is currently used using the General tab when you are editing your spaces app)
    skins17
  2. Edit your newly created navigation model (add links for your pages – you can create pages later and update Path for links)
    skins18
    skins19
    skins20
  1. Select custom navigation model as the default one for your spaces app
    skins21
    skins22We currently don’t see any sub-menus, so next we are going to change the menu component in our template.

 

Change the Top Menu

 

  1. Using the browser Developer Tool, you can see the menu is placed in the component with id  ‘T:spcNavPanel’.

Search for this component in your template file and you can see a region (task-flow) is used to display the menu.

We are going to replace this region with this code (loop through the navigation model and its children):

  <div class=menu>

    <c:set var=”navNodes”    value=”${navigationContext.defaultNavigationModel.listModel[‘startNode=/, includeStartNode=false’]}” scope=”session”/>

    <ul id=topnav>

      <c:forEach var=”menu” varStatus=”vs” items=”${navNodes}”>

        <li><a href=“/webcenter${menu.goLinkPrettyUrl}”> ${menu.title}</a>

           <c:if test=”${not empty menu.children}”>

             <div class=“submenu”><table width=100%><tr><td>

                <ol class=“blocks-four-up”>

                <c:forEach var=”child” items=”#{menu.children}”>

                 <li>

<p><a href=“/webcenter${child.goLinkPrettyUrl}”>

${child.title}

</a></p>

                 <c:if test=”${not empty child.children}”>

                 <ol>

                 <forEach var=”child1″ items=”#{child.children}”>

                 <li><a href=/webcenter${child1.goLinkPrettyUrl}”>

${child1.title}

</a></li>

                 </c:forEach>

                 </ol>

                 </c:if>

                 </li>

                 </c:forEach>

                 </ol>

              </td></tr></table></div>

            </c:if>

         </li>

      </c:forEach>

    </ul>

  </div>

 

You can find the meaning of EL expressions related to Navigation in this   document:

http://docs.oracle.com/cd/E23943_01/webcenter.1111/e10148/jpsdg_app_els.htm#CHDCBJGJ

 

 

  1. Add this to your skin:

 

.menu ul#topnav{

margin-top: 18px;

padding: 0;

float: left;

width: 880px;

position: absolute;

liststyle: none;

position: relative;

fontsize: 1.2em;

background:url(http://1-ps.googleusercontent.com/h/www.htmldrive.net/edit_media/2010/201007/20100728/Horizontal%20Subnav/images/xtopnav_s.gif.pagespeed.ic.v1mnjAEAt5.webp) repeat-x;

}

.menu ul#topnav li .submenu{  

padding: 15px 0;

position: absolute;

left: 0; top:35px;

display: none;

width: 760px;

background: #282828;;

color: #fff;

z-index:1;

-moz-border-radius-bottomright: 5px;

-khtml-border-radius-bottomright: 5px;

-webkit-border-bottom-right-radius: 5px;

-moz-border-radius-bottomleft: 5px;

-khtml-border-radius-bottomleft: 5px;

-webkit-border-bottom-left-radius: 5px;

}

.menu ul#topnav li{

float: left;

list-style: none;

}

.menu ul#topnav li:hover.submenu{

display:block;

}

.menu ul#topnav li a {

padding: 10px 15px;

display: block;

text-decoration: none;

color: #f0f0f0;

}

.menu.blocks-four-up{

list-style: none;

position:relative:;

}

.menu.blocks-four-up>li {

float: left;

width: 25%;

}

.menu#topnav.blocks-four-up>li ol li{

float: none;

}

.menu ul#topnav li .submenu a {

padding: 10px 0;

display: inline;

color: #f0f0f0;

text-decoration: none;

}

 

  1. To display four (4) submenus in one row, we have to use nth-child selector. If we include the selector in our skin file it’s not going to work, so we can just add it to the template:

<af:resource type=”css”>

.blocks-four-up>li:nth-child(4n+1)

{clear:left;}

</af:resource>

The result:
skins23

 

Next, we want to display the ‘More Info’ menu at the bottom.

How do we know which menu we are going to use as a bottom menu?  We can add some attribute (menuType) to the menu using the navigation model:

skins24

Change the template :

<c:forEach var=”child” items=”#{menu.children}”>

<li>

<c:if test=”${child.attributes.menuType != ‘bottom’}”>

    <p>

    <a href=/webcenter${child.goLinkPrettyUrl}>${child.title}</a>

    </p>

<c:if test=”${not empty child.children}”>

<ol>

    <c:forEach var=”child1″ items=”#{child.children}”>

    <li>

    <a href=/webcenter${child1.goLinkPrettyUrl}>

    ${child1.title}</a>

    </li>

    </c:forEach>

</ol>

</c:if>

</c:if>

<c:if test=”${child.attributes.menuType == ‘bottom’}”>

    <c:set var=”bottomMenu” value=”${child}” scope=”session”/>

</c:if>

</li>

</c:forEach>

</ol>

<p class=“menu_bottom_title”>

 ${bottomMenu.title}

</p>

<ul class=“menu_botom_links”>

<c:forEach var=”child1″ items=”#{bottomMenu.children}”>

    <li>

    <a href=“/webcenter${child1.goLinkPrettyUrl}”>

    ${child1.title}</a>

    </li>

</c:forEach>

</ul>

 

Add/change this to the skin:

.menu ul#topnav li  .submenu.menu_bottom_title{

clear: both;

margin: 0 8px .5em 12px;

padding: .75em 27px 0;

border-top: 1px solid #5e5f62;

font-weight: normal;

font-size: 1.230769em;

line-height: 1.125;

}

.menu.blocks-four-up>li ol{

-webkit-padding-start: 0;

}

.menu.blocks-four-up>li {

float: left;

width: 25%;

padding-bottom: 5px;

}

skins25

Using the same directions, we are going to add some images on the right side of the menu:

  • Create a new link and add attribute ‘menuType’ with value set to ‘image’.
  • Add attribute ‘imageUrl’ with the value which points to your image:
    skins26

Change your template (apply changes related to image in red color):

<td width=85%><ol class=blocks-four-up>

<c:forEach var=”child” items=”#{menu.children}”>

    <li>

    <c:if test=”${ child.attributes.menuType != ‘bottom’ &amp;&amp; child.attributes.menuType != ‘image’}”>

        <p><a href=/webcenter${child.goLinkPrettyUrl}> ${child.title}</a></p>

    <c:if test=”${not empty child.children}”>

    <ol>

    <c:forEach var=”child1″ items=”#{child.children}”>

        <li>

        <a href=/webcenter${child1.goLinkPrettyUrl}> ${child1.title}</a>

        </li>

    </c:forEach>

    </ol>

    </c:if>

    </c:if>

    <c:if test=”${child.attributes.menuType == ‘bottom’}”>

        <c:set var=”bottomMenu” value=”${child}” scope=”session”/>

    </c:if>

    <c:if test=”${child.attributes.menuType == ‘image’}”>

        <c:set var=”linkimage” value=”${child.attributes.imageUrl}” scope=”session”/>

    </c:if>

    </li>

    </c:forEach>

    </ol>

    <p class=menu_bottom_title> ${bottomMenu.title} </p>

    <ul class=menu_botom_links>

    <c:forEach var=”child1″ items=”#{bottomMenu.children}”>

        <li>

        <a href=/webcenter${child1.goLinkPrettyUrl}> ${child1.title}</a>

        </li>

    </c:forEach>

    </ul>

</td>

<td width=“15%” valign=“top”><img src=“${linkimage}”/></td> 

 

 

Finally, we want the submenu to cover the entire page.

To do this:

  1. Create a new div container as child of ‘pt_pgl5’ component:

<af:panelGroupLayout id=”pt_pgl5″ layout=”vertical” styleClass=”WCSiteTemplateBackground”>

            <div id=submenu/>

<af:panelGroupLayout id=”pt_pbl1″ layout=”vertical” inlineStyle=”width:#{attrs.templateFixedWidth}px;margin:0px auto;padding-top:8px;”>

 

We are going to clone the submenu in a mouse over action with this container.

  1. Add javascript to the template:

<af:resource type=“javascript>

function showSubmenu(e){

var childrens = e.parentNode.children;

var  len = childrens.length;

document.getElementById(submenu).innerHTML =;

for (i = 0; i &lt; len; i++) {

if(childrens[i].className==submenu){

newNode=childrens[i].cloneNode(true);

document.getElementById(submenu).appendChild(newNode);

}

}}

</af:resource>

 

  1. Add onMouseOver event to the link

<a href=/webcenter${menu.goLinkPrettyUrl}     onmouseover=showSubmenu(this)>

 

  1. Add this to css:

.menu ul#topnav li:hover.submenu{

display:none;

}

div#submenu.blocks-four-up>li ol li{

float: none;

}

div#submenu.blocks-four-up>li {

float: left;

width: 25%;

padding-bottom: 5px;

}

div#submenu.blocks-four-up{

list-style: none;

position:relative:;

}

div#submenu.blocks-four-up>li ol{

-webkit-padding-start: 0;

}

div#submenu.menu_bottom_title{

clear: both;

margin: 0 8px .5em 12px;

padding: .75em 27px 0;

border-top: 1px solid #5e5f62;

font-weight: normal;

font-size: 1.230769em;

line-height: 1.125;

}

div#submenu div{

padding: 15px 0;

position: relative;

left: 0;

width:1000px;

display: block;

background: #282828;

color: #fff;

margin: 0 auto;

 

}

 

div#submenu  {

width:100%;

top: 90px;

position: absolute;

z-index: 3;

background: #282828;

}

 

div#submenu li{

margin-bottom: .3076923em;

}

 

div#submenu p a{

font-weight:bold

}

 

div#submenu p {

margin-bottom: 3px;

}

div#submenu a{

padding: 10px 0;

display: inline;

color: #f0f0f0;

text-decoration: none;

}

 

div#submenu div>ol {

min-height: 109px;

list-style: none;

}

div#submenu div>ol ol {

padding:0px;

list-style: none;}

div#submenu div>table tr td ol ol {

padding:0px;

list-style: none;

}

skins28

You also need to add an event to clear the container when exiting from the submenu.

Those are the basic steps to change the template and skin of your Portal application.

Using a browser Developer Tool enables you to discover which component has to be changed or what to change in your skin.

 

Any questions? Feel free to contact us.