When working with eXo Platform, it is important not to modify the source code. This will ensure compatibility with future upgrades, and support will be simplified.
To customize your portal, you need to create an extension project by providing your own artifacts as a set of wars/jars/ears.

This chapter will show you how to create a portal via the following topics:

* [Create your extension project|#DEV.CreateYourOwnPortal.CreateExtensionProject]
* [Structure of portal, pages and menus|#DEV.CreateYourOwnPortal.StructureOfPortalPages&Menus]
* [Add/Remove a language|#DEV.CreateYourOwnPortal.AddOrRemoveLanguages]
* [Create custom look and feel|#DEV.CreateYourOwnPortal.CreateCustomLookAndFeel]
** [Structure stylesheet|#DEV.CreateYourOwnPortal.StructureStylesheet]
** [Configure skin in eXo Platform|#DEV.CreateYourOwnPortal.ConfigureSkinInPlatform]
** [Configure skin in WCM|#DEV.CreateYourOwnPortal.ConfigureSkinInWCM]
** [Create and apply Global stylesheet|#DEV.CreateYourOwnPortal.CreateAndApplyGloabalStylesheet]
** [Customize the Admin bar|#DEV.CreateYourOwnPortal.CustomizeAdminbar]
* [Add JavaScript to your portal|#DEV.CreateYourOwnPortal.AddJavaScriptToYourPortal]

h1. Create your extension project {anchor:id=DEV.CreateYourOwnPortal.CreateExtensionProject}

A custom extension contains two mandatory items:
* *extension webapp* contains resources and kernel configurations.
* *extension activator jar* identifies your webapp as a dependency of the portal container.

To see the sample extension package, visit [here|http://anonsvn.jboss.org/repos/gatein/portal/trunk/examples/extension/].

Once you have modified the sample extension to build your own portal, use the _maven clean install_ command to create the archive files.

{docbook}
<para>
<citetitle>
<emphasis role="bold">
Deploy your extension in Tomcat
</emphasis>
</citetitle>
</para>
{docbook}

*1.* Add the _sample-ext.war_ file from the _sample/extension/war/target/_ to the _tomcat/webapps_ directory.

*2.* Add the _starter_ folder from _starter/war/target/_ to the _tomcat/webapps_ directory.

*3.* Rename the _starter_ directory (unzipped folder) to _starter.war_.

{note}
This will only work if the starter.war is the last .war file to be loaded, so you may need to rename it if your war files are loaded in the alphabetical order.
{note}

*4.* Add the .jar file named _exo.portal.sample.extension.config-X.Y.Z.jar_ from _sample/extension/config/target/_ to the _tomcat/lib_ directory.

*5.* Add the .jar file named _exo.portal.sample.extension.jar-X.Y.Z.jar_ from _sample/extension/jar/target/_ to the _tomcat/lib_ directory.

For the JBoss deployment with more details, refer to the [GateIn Reference Guide|../../../reference/html/bk02.html].

h1. Structure of portal, pages and menus {anchor:id=DEV.CreateYourOwnPortal.StructureOfPortalPages&Menus}

You can create multiple pages within a single portal. Permissions can be defined to make them visible only to specific groups and/or users. This chapter describes how to define this structure.

h2. Portal navigation {anchor:id=DEV.CreateYourOwnPortal.PageLayout}

The portal navigation incorporates the pages that can be accessed even when the user is not logged in assuming the applicable permissions allow the public access). For example, several portal navigations are used when a company owns multiple trademarks, and sets up a website for each of them.

The configuration of the "classic" portal can be found in the _/src/main/WEB-INF/conf/portal/portal/classic_ directory of your extension webapp.


{docbook}
<citetitle>
<para>
<emphasis role="bold">portal.xml</emphasis>
</para>
</citetitle>
{docbook}

The _portal.xml_ file describes the layout and portlets that will be shown on all pages. The layout usually contains the banner, footer, menu and breadcrumbs portlets. eXo Platform 3.5 is extremely configurable as every view element (even the banner and footer) is a portlet.

{code:xml}
<portal-config
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.gatein.org/xml/ns/gatein_objects_1_0 http://www.gatein.org/xml/ns/gatein_objects_1_0"
   xmlns="http://www.gatein.org/xml/ns/gatein_objects_1_0">
   <portal-name>classic</portal-name>
   <locale>en</locale>
   <access-permissions>Everyone</access-permissions>
   <edit-permission>*:/platform/administrators</edit-permission>
   <properties>
      <entry key="sessionAlive">onDemand</entry>
      <entry key="showPortletInfo">1</entry>
   </properties>

   <portal-layout>
      <portlet-application>
         <portlet>
            <application-ref>web</application-ref>
            <portlet-ref>BannerPortlet</portlet-ref>
            <preferences>
               <preference>
                  <name>template</name>
                  <value>par:/groovy/groovy/webui/component/UIBannerPortlet.gtmpl</value>
                  <read-only>false</read-only>
               </preference>
            </preferences>
         </portlet>
         <access-permissions>Everyone</access-permissions>
         <show-info-bar>false</show-info-bar>
      </portlet-application>

      <portlet-application>
         <portlet>
            <application-ref>web</application-ref>
            <portlet-ref>NavigationPortlet</portlet-ref>
         </portlet>
         <access-permissions>Everyone</access-permissions>
         <show-info-bar>false</show-info-bar>
      </portlet-application>

      <portlet-application>
         <portlet>
            <application-ref>web</application-ref>
            <portlet-ref>BreadcumbsPortlet</portlet-ref>
         </portlet>
         <access-permissions>Everyone</access-permissions>
         <show-info-bar>false</show-info-bar>
      </portlet-application>

      <page-body> </page-body>

      <portlet-application>
         <portlet>
            <application-ref>web</application-ref>
            <portlet-ref>FooterPortlet</portlet-ref>
            <preferences>
               <preference>
                  <name>template</name>
                  <value>par:/groovy/groovy/webui/component/UIFooterPortlet.gtmpl</value>
                  <read-only>false</read-only>
               </preference>
            </preferences>
         </portlet>
         <access-permissions>Everyone</access-permissions>
         <show-info-bar>false</show-info-bar>
      </portlet-application>

   </portal-layout>

</portal-config>
{code}

Each portlet can be configured with a set of preferences, which will be further detailed in [Chapter 5|#DEV.WorkingwithApplications].

It is also possible to apply a nested container that can also contain portlets. Row, column or tab containers are then responsible for the layout of their child portlets.

Each application references a portlet using the id: _{{{portal#{portalName}:/{portletWarName}/{portletName}/{uniqueId}}}}_

The <page-body> </page-body> tag is a placeholder for the different pages of your portal, it defines where Platform should render the current page. When the user opens a new portal page, all portlets of the portal layout (_portal.xml_) are remained, whereas the content of <page-body> switches to the page opened by the user.

The defined "classic" portal is accessible to "Everyone" (at _/portal/public/classic_) but only members of the group _/platform/administrators_ can edit it.

{docbook}
<citetitle>
<para>
<emphasis role="bold">pages.xml</emphasis>
</para>
</citetitle>
{docbook}

The structure of the _pages.xml_ configuration file is very similar to that in the _portal.xml_ of the "classic" portal and it can also contain container tags. Each application can decide whether to render the portlet border, the window state, the icons or portlet's mode.

This is the example of the _pages.xml_ file of the "classic" portal.

{code:xml}
<page-set
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.gatein.org/xml/ns/gatein_objects_1_0 http://www.gatein.org/xml/ns/gatein_objects_1_0"
   xmlns="http://www.gatein.org/xml/ns/gatein_objects_1_0">

   <page>
      <name>homepage</name>
      <title>Home Page</title>
      <access-permissions>Everyone</access-permissions>
      <edit-permission>*:/platform/administrators</edit-permission>
      <portlet-application>
         <portlet>
            <application-ref>web</application-ref>
            <portlet-ref>HomePagePortlet</portlet-ref>
            <preferences>
               <preference>
                  <name>template</name>
                  <value>system:/templates/groovy/webui/component/UIHomePagePortlet.gtmpl</value>
                  <read-only>false</read-only>
               </preference>
            </preferences>
         </portlet>
         <title>Home Page portlet</title>
         <access-permissions>Everyone</access-permissions>
         <show-info-bar>false</show-info-bar>
         <show-application-state>false</show-application-state>
         <show-application-mode>false</show-application-mode>
      </portlet-application>
   </page>

   <page>
      <name>sitemap</name>
      <title>Site Map</title>
      <access-permissions>Everyone</access-permissions>
      <edit-permission>*:/platform/administrators</edit-permission>
      <portlet-application>
         <portlet>
            <application-ref>web</application-ref>
            <portlet-ref>SiteMapPortlet</portlet-ref>
         </portlet>
         <title>SiteMap</title>
         <access-permissions>Everyone</access-permissions>
         <show-info-bar>false</show-info-bar>
      </portlet-application>
   </page>
   .......
</page-set>
{code}

{note}
See [Chapter 5|#DEV.WorkingwithApplications] to learn more about the portlet configuration within the _pages.xml_ file.
{note}

{docbook}
<citetitle>
<para>
<emphasis role="bold">navigation.xml</emphasis>
</para>
</citetitle>
{docbook}

The _navigation.xml_ file defines all the navigation nodes of the portal. The syntax is simply using the nested node tags. Each node refers to a page defined in the _pages.xml_ file that will be explained later.

If the administrator wants to create node labels for each language, he will have to use _xml\:lang_ attribute in the label tag with the value of _xml\:lang_ is set to the relevant locale.

Otherwise, if the administrator wants the node label is localized by resource bundle files, the _\#{{{{...}}}}_ syntax will be used. The enclosed property name serves as a key that is automatically passed to the internationalization mechanism. Thus, the emphasis property name is replaced with a localized value taken from the associated properties file matching the current locale.

{code:xml}
<node-navigation>
  <owner-type>portal</owner-type>
  <owner-id>classic</owner-id>
  <priority>1</priority>
  <page-nodes>
    <node>
      <uri>home</uri>
      <name>home</name>
      <label>#{portal.classic.home}</label>
      <page-reference>portal::classic::homepage</page-reference>
    </node>
    <node>
      <uri>webexplorer</uri>
      <name>webexplorer</name>
      <label>#{portal.classic.webexplorer}</label>
      <page-reference>portal::classic::webexplorer</page-reference>
    </node>
  </page-nodes>
</node-navigation>
{code}


This navigation tree is shown and reused in different portlets, such as sitemap, navigation or breadcrumbs. The breadcrumbs portlet renders the position of the current navigation node.

{note}
For the top nodes, the URI and the navigation node name must have the same value. For other nodes, the URI is composed like _<uri>contentmanagement/fileexplorer</uri>_ where 'contentmanagement' is the name of the parent node, and 'fileexplorer' is the name of node (_<name>fileexplorer</name>_).
{note}

h2. Visibility of pages {anchor:id=DEV.CreateYourOwnPortal.VisibilityPages}

When you configure the _navigation.xml_ file, sometimes you need to set the visibility of page (node).

To configure the page visibility, simply put _<visibility>type\_of\_visibility</visibility>_ as a child of the _<node>_ tag.

eXo Platform supports 4 types of page visibility, including:

* DISPLAYED: The page will be displayed.
* HIDDEN: The page is not visible in the navigation but can be accessed directly with its URL.
* SYSTEM: It is a system page which is visible to superusers. In particular, only superusers can change or delete this system page. 
* TEMPORAL: The page is displayed in related time range. When the visibility of TEMPORAL page is configured, the start and end date can be specified by using _<startpublicationdate>_ and _<endpublicationdate>_. For example:

{code:xml}
<node>
  ...
  <visibility>TEMPORAL</visibility>
  <startpublicationdate>01/13/2011 12:46:38</startpublicationdate>
  <endpublicationdate>01/20/2011 18:46:42</endpublicationdate>
</node>
{code}

* To hide a page from menu and navigation, use _<visibility>HIDDEN</visibility>_:

{code:xml}
<node-navigation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.gatein.org/xml/ns/gatein_objects_1_0 http://www.gatein.org/xml/ns/gatein_objects_1_0" xmlns="http://www.gatein.org/xml/ns/gatein_objects_1_0">
  <page-nodes>
    <node>
      <uri>sitemap</uri>
      <name>sitemap</name>
      <label>#{portal.classic.sitemap}</label>
      <visibility>HIDDEN</visibility>
      <page-reference>portal::classic::sitemap</page-reference>
    </node>
    ...
  </page-nodes>
</node-navigation>
{code}

h2. Page access permission {anchor:id=DEV.CreateYourOwnPortal.PagesAccessPermission}
You can easily restrict the access of selected pages and navigation nodes to certain groups and users. You just need to create _pages.xml_ and _navigation.xml_ files in folders named after groups and users to which you want to give permission:

* _sample-ext/portal/group/group-name/your files_

* _sample-ext/portal/user/username/your files_

As you know, the permission on a page has two types: access (view the page) and edit. 

To configure them, edit the _pages.xml_ file and put tags: _<access-permissions>_ and _<edit-permission>_.

Currently, eXo Platform supports several access permissions but only one edit permission. It means that you can configure to make many groups to have the access permission but you can only set one group for edit permission.

For example:

{code:xml}
<page>
  <name>newStaff</name>
  <title>New Staff</title>
  <access-permissions>manager:/organization/management/executive-board;member:/organization/management/executive-board</access-permissions>
  <edit-permission>manager:/organization/management/executive-board</edit-permission>
  ...
</page>
{code}
h1. Enable/Disable a drive creation during the portal creation {anchor:id=DEV.CreateYourOwnPortal.EnableDisableDriveCreation}
{include:document=customize/Enable_drive_creation.wiki|syntax=confluence/1.0}

h1. Add/Remove a language {anchor:id=DEV.CreateYourOwnPortal.AddOrRemoveLanguages}

Developer can define new or remove a defined language through the locale configuration file. The resource is managed by _org.exoplatform.services.resources.LocaleConfigService_ as following:

{code:xml}
<component>
    <key>org.exoplatform.services.resources.LocaleConfigService</key>
    <type>org.exoplatform.services.resources.impl.LocaleConfigServiceImpl</type>
      <init-params>
        <value-param>
          <name>locale.config.file</name>
          <value>war:/conf/common/locales-config.xml</value>
        </value-param>
      </init-params>
  </component>
{code}

All languages defined in the _locale-config.xml_ file are listed in the [*Interface Language Settings*|#DEV.Interface_Language_Setting_window] window.

h2. Add a new language {anchor:id=DEV.CreateYourOwnPortal.AddNewLanguages}

To add a new language, you need to add the corresponding language node in the _locale-config.xml_ file. Next, you must create a new _resource bundle_ file containing the suffix name as the key of the added node.

For example, to add Italian, do as follows:

*1.* Add the following node to the _locale-config.xml_ file.

{code:xml}
<locale-config>
  <locale>it</locale>
  <output-encoding>UTF-8</output-encoding>
  <input-encoding>UTF-8</input-encoding>
  <description>Default configuration for Italian locale</description>
</locale-config>
{code}

*2.* Create a new _resource bundle_ as *_{{{webui_it.properties}}}_* in the _myextension.war/WEB-INF/classes/locale/portal_ folder.

{note}
This step is necessary because the Resource Bundle Service of the portal will find keys and values in the _resource bundle_ of each corresponding language. 
{note}

*3.* Restart the server.

To check if the added language takes effect, hover the mouse over your username on the *Administration* bar and click *Change Language*. In the *Interface Language Settings* window that appears, you will see the Italian is listed as below:

{anchor:id="DEV.Interface_Language_Setting_window"}

!images/example_addItalian.png|align="center"  width="150mm" fo:scalefit="1" html:scalefit="0"!

h2. Remove a language {anchor:id=DEV.CreateYourOwnPortal.RemoveLanguages}

To remove an existing language, you need to delete the relevant language node in the _locale-config.xml_ file and all files containing the suffix name as the key of language.

For example, to remove French, do as follows:

*1.* Find and remove the following node from the _locale-config.xml_ file.

{code:xml}
<locale-config>
  <locale>fr</locale>
  <output-encoding>UTF-8</output-encoding>
  <input-encoding>UTF-8</input-encoding>
  <description>Default configuration for france locale</description>
</locale-config>
{code}

*2.* Continue removing all _resource bundle_ files containing the suffix name as *fr* in all folders.

{note}
It is recommended this step be done to delete unnecessary data in the application.
{note}
 
*3.* Restart the server.

To check if French is removed, hover the mouse over your username on the *Administration bar* and click the *Change Language*.

In the *Interface Language Settings* window that appears, French is no longer listed.

!images/example_removeFrench.png|align="center"  width="150mm" fo:scalefit="1" html:scalefit="0"!

h1. Create a custom look and feel {anchor:id=DEV.CreateYourOwnPortal.CreateCustomLookAndFeel}

{include:document="customize/How_to_create_custom_look_and_feel.wiki"}

h1. Add JavaScript to your portal {anchor:id=DEV.CreateYourOwnPortal.AddJavaScriptToYourPortal}

This can be done entirely within your extension by customizing the _gatein-resources.xml_ configuration.

To add a JavaScript library, for example jQuery, create the _war:/WEB-INF/gatein-resources.xml_ file.

{code:xml}
<javascript>
  <param>
    <js-module>jQuery</js-module>
    <js-path>/javascript/jQuery.js</js-path>
    <js-priority>0</js-priority>
  </param>
</javascript>
{code}

In which:

* _<js-module>_ is the namespace of your JavaScript.

* _<js-path>_ is the path to your JavaScript file.

* _<js-priority>_ is an optional tag. This tag is used to indicate the loading order of JavaScript files across all eXo Platform. Its value is of the integer type. If its value is not negative (>=0), the loading priority is sorted by the descending order. If its value is negative (<0), the loading priority of the JavaScript file depends on the loading order of the web app (.war file) containing the JavaScript file.

h1. Create custom templates for pages {anchor:id=DEV.CreateYourOwnPortal.AddJavaScriptToYourPortal.Create_custom_templates_for_pages}

eXo Platform 3.5 provides you with some built-in templates when you create a new page via *Page Creation Wizard*. In this section, you will learn how to create a custom page template for *Page Creation Wizard*.

You should use the extension to add the page layout configuration. In this guide, you are going to work with the _/examples/extension_ project.

{docbook}
<para>
<citetitle>
<emphasis role="bold">
Create a custom page template
</emphasis>
</citetitle>
</para>
{docbook}

*1.* Add your sample template "FourRowsLayout" by overriding the _PageConfigOptions.groovy_ file (portal.war).

Add it to this path: _/examples/extension/war/src/main/webapp/WEB-INF/conf/uiconf/portal/webui/page/PageConfigOptions.groovy_

!images/PageConfigOptions.groovy.png|align="center" width="150mm" fo:scalefit="1" html:scalefit="0"!

Sample code:

{code:groovy}
...
SelectItemCategory samplePageConfigs = new SelectItemCategory("samplePageConfigs"):
categories.add(samplePageConfigs):
samplePageConfigs.addSelectItemOption(new SelectItemOption("samplePage.FourRowsLayout","four-rows","FourRowsLayout:"));
...
{code}

*2.* Add your template file into the _/examples/extension/war/src/main/webapp/WEB-INF/conf/portal/template/pages/four-rows/page.xml_ file.

!images/page.xml.png|align="center" width="150mm" fo:scalefit="1" html:scalefit="0"!

Sample code:

{code}
<page
xmlns:xsi="http://www.w3.org.2001/XMLSchema-instance"
xsi:schemaLocation="httlp://www.gatein.org/xml/ns/gatein_object_1_2.xsd http://gatein.org/xml/ns/gatein_object_1_2.xsd"
xmlns:"http://gatein.org/xml/ns/gatein_object_1_2.xsd">
<name></name>
<container template="system:/groovy/portal/webui/container/UIContainer.gtmpl">
<access-permission>Everyone<access-permission>
</container>

<container template="system:/groovy/portal/webui/container/UIContainer.gtmpl">
<access-permission>Everyone<access-permission>
</container>

<container template="system:/groovy/portal/webui/container/UIContainer.gtmpl">
<access-permission>Everyone<access-permission>
</container>

<container template="system:/groovy/portal/webui/container/UIContainer.gtmpl">
<access-permission>Everyone<access-permission>
</container>
</page>
{code}

You can refer to the default template of eXo Platform in this path: _/web/portal/src/main/webapp/WEB-INF/conf/portal/template/pages_

*3*. Add the stylesheet to make the template preview image.

Add your own stylesheet in your extension webapp:

{code:css}
.UIItemSelector .<FourRowsLayout>{
 width: 270px; height: 170px;
 margin: auto;
 background: url('background/ItemSelector.gif') no-repeat left -1700px;
}
{code}

You can refer to the eXo Platform 3.5's default stylesheet in this path: _/web/eXoResources/src/main/webapp/skin/DefaultSkin/webui/component/UISelector/UIItemSelector/Stylesheet.css_

*4*. Deploy your extension project. You will see the template and its preview image in the *Page Creation Wizard*.
