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 languages|#DEV.CreateYourOwnPortal.AddOrRemoveLanguages]
* [Create custom look and feel|#DEV.CreateYourOwnPortal.CreateCustomLookAndFeel]
** [Structure stylesheet|#DEV.CreateYourOwnPortal.StructureStylesheet]
** [Configure skin in GateIn|#DEV.CreateYourOwnPortal.ConfigureSkinInGatein]
** [Configure skin in WCM|#DEV.CreateYourOwnPortal.ConfigureSkinInWCM]
** [Create and apply Global stylesheet|#DEV.CreateYourOwnPortal.CreateAndApplyGloabalStylesheet]
** [Customize 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.

*To deploy your extension in Tomcat:*

*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 Reference Guide on [here|http://platform.demo.exoplatform.org/docs/].

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. Page layout {anchor:id=DEV.CreateYourOwnPortal.PageLayout}

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

*Portal:*

The _portal.xml_ file describes the layout and portlets common to all pages of the portal.

{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>
  </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>
        ...
      </portlet>
    </portlet-application>

    <portlet-application>
      <portlet>
        ...
      </portlet>
    </portlet-application>

    <page-body> </page-body>

    <portlet-application>
      <portlet>
        ...
      </portlet>
    </portlet-application>
  </portal-layout>
</portal-config>
{code}

As you can see, each portlet can be configured with a set of preferences, which will be further detailed in Chapter 6. The tag <page-body> </page-body> is a placeholder for the different pages of your portal. 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.

*Pages:*

The _pages.xml_ file is used to describe the content of pages of your portal. In particular, pages of your portal will be inside the <page-body> tag of the _portal.xml_ file above.

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

{code:xml}
<page>
  <name>homepage</name>
  <title>Home Page</title>
  <access-permissions>Everyone</access-permissions>
  <edit-permission>*:/platform/administrators</edit-permission>
  <container id="ClassicBody" template="system:/groovy/portal/webui/container/UITableColumnContainer.gtmpl">
    <access-permissions>Everyone</access-permissions>
    <container id="ClassicLeft" template="system:/groovy/portal/webui/container/UIContainer.gtmpl">
      <access-permissions>Everyone</access-permissions>
      <portlet-application>
        <portlet>
          <application-ref>presentation</application-ref>
          <portlet-ref>SingleContentViewer</portlet-ref>
          <preferences>
            <preference>
              <name>repository</name>
              <value>repository</value>
              <read-only>false</read-only>
            </preference>
            ...
            <preference>
              <name>ShowTitle</name>
              <value>false</value>
              <read-only>false</read-only>
            </preference>
          </preferences>
        </portlet>
        <title>Introduce</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>
    </container>
  </container>
</page>
{code}

{note}
See Chapter 6 to learn more about the portlet configuration within the _pages.xml_ file.
{note}

*Navigation:*

The _navigation.xml_ is used to associate the links in your navigation with your portal pages. The navigation is a tree structure of "navigation nodes". Each navigation node points to one page (called the page node). The tree structure corresponds to a hierarchy of menus and sub-menus of a site.

If the pattern #{} is used, the link label will be loaded from the portal resource bundle. To learn more, refer to [Internationalization Configuration|http://platform.demo.exoplatform.org/docs/refguide/html/gatein/chap-Reference_Guide-Development.html#sect-Reference_Guide-Internationalization_Configuration].

{code:xml}
<?xml version="1.0" encoding="UTF-8"?>
<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, simply put _{noformat}<visibility>type_of_visibility</visibility>{noformat}_ as a child of <node> tag.

GateIn 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, 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 the group and user 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 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. Add/remove languages {anchor:id=DEV.CreateYourOwnPortal.AddOrRemoveLanguages}

All languages are put in the _myextension.war/WEB-INF/conf/common/locales-config.xml_ directory. Each language consists of information related to key, output-encoding, input-encoding, description and orientation. Different languages will be defined in corresponding _resource bundle_ files with keys specified in the _locale-config.xml_ file.

All languages defined in the _locale-config.xml_ file are listed in *Interface Language Settings*. 

h2. Add new languages {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 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, simply click the *Change Language* button on the top right corner of the portal. In the *Interface Language Setting* window, you will see Italian as shown:

!images/example_addItalian.png|align="center"!

h2. Remove languages {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 should be done to delete unnecessary data in the application.
{note}
 
*3.* Restart the server.

To check if the French removal takes effect, simply click the *Change Language* button on the top right corner of the portal. In the *Interface Language Setting* window, French will not exist on the *Interface Language Setting* window any longer. 

!images/example_removeFrench.png|align="center"!

h1. Create 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.
