Index: main/plugin-web/i18n/messages_en.xml
===================================================================
--- main/plugin-web/i18n/messages_en.xml	(revision 39918)
+++ main/plugin-web/i18n/messages_en.xml	(working copy)
@@ -126,7 +126,9 @@
 	<message key="PLUGINS_WEB_RIGHTS_FO_USERS_DESCRIPTION">Management of site's users</message>
     <message key="PLUGINS_WEB_RIGHTS_FO_GROUPS_LABEL">Groups of the site</message>
     <message key="PLUGINS_WEB_RIGHTS_FO_GROUPS_DESCRIPTION">Management of site's groups</message>
-	
+	<message key="PLUGINS_WEB_RIGHTS_PAGE_VISIBLE_BUTTON_LABEL">Page visibility</message>
+    <message key="PLUGINS_WEB_RIGHTS_PAGE_VISIBLE_BUTTON_DESC">Right to change page visibility</message>
+    
 	<message key="PLUGINS_WEB_UITOOL_SITEMAP_LABEL">Sitemap</message>
 	<message key="PLUGINS_WEB_UITOOL_SITEMAP_DESC">Working sitemap</message>
 	<message key="PLUGINS_WEB_UITOOL_SITEMAP_FOOTER">See Help for details</message>
@@ -1305,7 +1307,9 @@
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_FROM_DESC">This setting allows you to choose from what context the sitemap will be held: either from the root, either from the current page (page included this service).</message>
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_FROM_ALL">the root site map</message>
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_FROM_CURRENT_PAGE">the current page</message>
-	<message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT">Display</message>
+	<message key="PLUGINS_WEB_SERVICE_SITEMAP_INCLUDE_INVISIBLE_PAGE">Include invisible pages</message>
+    <message key="PLUGINS_WEB_SERVICE_SITEMAP_INCLUDE_INVISIBLE_PAGE_DESC">Check to include invisible pages in the sitemap.</message>
+    <message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT">Display</message>
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT_DESC">Select the display to use when displaying this service</message>
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT_SITEMAP_LABEL">Ametys 3.2 compatibility mode</message>
     <message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT_SITEMAP33_LABEL">Default</message>
@@ -1517,6 +1521,7 @@
 	<message key="FRONT_MODULE_SEARCH_NAV_LAST">Last</message>
 	<message key="FRONT_MODULE_SEARCH_NAV_LAST_TITLE">Go to last page</message>
 	<message key="FRONT_MODULE_SEARCH_RESULTS">Result(s) {0} to {1} of {2}</message>
+    <message key="FRONT_MODULE_SEARCH_RESULTS_NO_NB_RESULT">Result(s) {0} to {1}</message>
     <message key="FRONT_MODULE_SEARCH_NO_RESULT">No result match your search criteria.</message>
 	<message key="FRONT_MODULE_SEARCH_NO_RESULT_RESOURCE">No resource match your search.</message>
 	<message key="FRONT_MODULE_SEARCH_BUTTON_OK">Search</message>
@@ -2428,4 +2433,18 @@
     
     <message key="PLUGINS_WEB_SITE_COOKIES_GROUP">Cookies</message>
     
+    <!-- Page visible button -->
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_LABEL">Page visibility</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_DESC">Click here to change the page visibility</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_FOOT"></message>
+    
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_NO_PAGE">No page selected</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_REFRESHING">Please wait... action inactive as server is performing some operations.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_TOOMANYPAGE">Too many page are selected. Please, select just one page.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_VISIBLE_PAGE">This page is visible for site visitors.&lt;br/&gt;&lt;br/&gt;Click here to set it invisible.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_INVISIBLE_PAGE">This page is invisiblefor site visitors.&lt;br/&gt;However it still accessible with links or the search engine.&lt;br/&gt;&lt;br/&gt;Click here to set it visible.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_VISIBLE_NO_MODIFIABLE_PAGE">This page is visible for site visitors.&lt;br/&gt;&lt;br/&gt;This page can't be modifiable.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_INVISIBLE_NO_MODIFIABLE_PAGE">This page is invisiblefor site visitors.&lt;br/&gt;However it still accessible with links or the search engine.&lt;br/&gt;&lt;br/&gt;This page can't be modifiable.</message>
+    
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_ERROR">An error occurred. Page visibility doesn't changed.</message>
 </catalogue>
Index: main/plugin-web/i18n/messages_fr.xml
===================================================================
--- main/plugin-web/i18n/messages_fr.xml	(revision 39918)
+++ main/plugin-web/i18n/messages_fr.xml	(working copy)
@@ -126,7 +126,9 @@
 	<message key="PLUGINS_WEB_RIGHTS_FO_USERS_DESCRIPTION">Gestion des utilisateurs du site</message>
     <message key="PLUGINS_WEB_RIGHTS_FO_GROUPS_LABEL">Groupes du site</message>
     <message key="PLUGINS_WEB_RIGHTS_FO_GROUPS_DESCRIPTION">Gestion des groupes du site</message>
-	
+	<message key="PLUGINS_WEB_RIGHTS_PAGE_VISIBLE_BUTTON_LABEL">Visibilité de la page</message>
+    <message key="PLUGINS_WEB_RIGHTS_PAGE_VISIBLE_BUTTON_DESC">Droit de changer la visibilité de la page</message>
+    
 	<message key="PLUGINS_WEB_UITOOL_SITEMAP_LABEL">Plan du site</message>
 	<message key="PLUGINS_WEB_UITOOL_SITEMAP_DESC">Arborescence du site courant</message>
 	<message key="PLUGINS_WEB_UITOOL_SITEMAP_FOOTER">Voir l'aide pour plus de détails</message>
@@ -1306,7 +1308,9 @@
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_FROM_DESC">Ce paramètre permet de choisir à partir de quel contexte le plan du site sera déroulé : soit à partir de la racine, soit à partir de la page courante (page contenant ce service).</message>
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_FROM_ALL">la racine du plan du site</message>
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_FROM_CURRENT_PAGE">la page courante</message>
-	<message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT">Affichage</message>
+	<message key="PLUGINS_WEB_SERVICE_SITEMAP_INCLUDE_INVISIBLE_PAGE">Inclure les pages invisbles</message>
+    <message key="PLUGINS_WEB_SERVICE_SITEMAP_INCLUDE_INVISIBLE_PAGE_DESC">Cocher la case pour inclure les pages invisibles dans le plan du site.</message>
+    <message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT">Affichage</message>
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT_DESC">Rendu à utiliser pour l'affichage du service</message>
 	<message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT_SITEMAP_LABEL">Mode de compatibilité Ametys 3.2</message>
     <message key="PLUGINS_WEB_SERVICE_SITEMAP_XSLT_SITEMAP33_LABEL">Par défaut</message>
@@ -1519,7 +1523,8 @@
 	<message key="FRONT_MODULE_SEARCH_NAV_LAST">Dernier</message>
 	<message key="FRONT_MODULE_SEARCH_NAV_LAST_TITLE">Aller à la dernière page</message>
 	<message key="FRONT_MODULE_SEARCH_RESULTS">Résultat(s) {0} à {1} sur {2}</message>
-	<message key="FRONT_MODULE_SEARCH_NO_RESULT">Aucun résultat ne correspond à votre recherche.</message>
+	<message key="FRONT_MODULE_SEARCH_RESULTS_NO_NB_RESULT">Résultat(s) {0} à {1}</message>
+    <message key="FRONT_MODULE_SEARCH_NO_RESULT">Aucun résultat ne correspond à votre recherche.</message>
     <message key="FRONT_MODULE_SEARCH_NO_RESULT_RESOURCE">Aucun document ne correspond à votre recherche.</message>    
 	<message key="FRONT_MODULE_SEARCH_BUTTON_OK">Rechercher</message>
 	<message key="FRONT_MODULE_SEARCH_SELECT_OPTION_ALL">- Tous -</message>
@@ -2429,5 +2434,19 @@
     <message key="PLUGINS_WEB_SITE_COOKIE_BANNER_VALUE_ASK_REFUSE">Demander et refuser à défaut</message>
     <message key="PLUGINS_WEB_SITE_COOKIES_GROUP">Cookies</message>
     
+    <!-- Page visible button -->
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_LABEL">Visibilité de la page</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_DESC">Cliquer pour rendre la page visible/invisible</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_FOOT"></message>
+    
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_NO_PAGE">Aucune page sélectionnée</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_REFRESHING">Veuillez patienter... ce bouton est désactivé pendant que des vérifications sont en cours sur le serveur.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_TOOMANYPAGE">Il y a trop de pages séléctionnées, sélectionnez en une seule.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_VISIBLE_PAGE">Cette page est visible dans le plan du site pour les visiteurs.&lt;br/&gt;&lt;br/&gt;Cliquer ici pour la rendre invisible.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_INVISIBLE_PAGE">Cette page est invisible dans le plan du site pour les visiteurs.&lt;br/&gt;Cependant elle reste accessible au travers de liens ou du moteur de recherche du site.&lt;br/&gt;&lt;br/&gt;Cliquer ici pour la rendre visible.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_VISIBLE_NO_MODIFIABLE_PAGE">Cette page est visible dans le plan du site pour les visiteurs.&lt;br/&gt;&lt;br/&gt;Cette page n'est pas modifiable.</message>
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_INVISIBLE_NO_MODIFIABLE_PAGE">Cette page est invisible dans le plan du site pour les visiteurs.&lt;br/&gt;Cependant elle reste accessible au travers de liens ou du moteur de recherche du site.&lt;br/&gt;&lt;br/&gt;Cette page n'est pas modifiable.</message>
+    
+    <message key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_ERROR">Une erreur est survenue. La visibilité de la page n'a pas changé.</message>
 </catalogue>
 	
\ No newline at end of file
Index: main/plugin-web/plugin.xml
===================================================================
--- main/plugin-web/plugin.xml	(revision 39918)
+++ main/plugin-web/plugin.xml	(working copy)
@@ -3964,6 +3964,11 @@
 	                   	</enumeration>
 	                   	<default-value>true</default-value>
 					</parameter>
+					<parameter name="includeInvisiblePage" type="boolean">
+					    <label i18n="true">PLUGINS_WEB_SERVICE_SITEMAP_INCLUDE_INVISIBLE_PAGE</label>
+                        <description i18n="true">PLUGINS_WEB_SERVICE_SITEMAP_INCLUDE_INVISIBLE_PAGE_DESC</description>
+                        <default-value>false</default-value>
+					</parameter>
 					<parameter name="xslt" type="string">
 						<label i18n="true">PLUGINS_WEB_SERVICE_SITEMAP_XSLT</label>
 						<description i18n="true">PLUGINS_WEB_SERVICE_SITEMAP_XSLT_DESC</description>
@@ -9371,4 +9376,50 @@
             </extension>
         </extensions>
     </feature>
+    
+    <feature name="org.ametys.web.button.page.visible">
+        <extensions>
+            <extension point="org.ametys.runtime.plugins.core.right.RightsExtensionPoint"
+                       id="org.ametys.web.button.page.visible.right">
+                <right id="Web_Right_Page_Visible">
+                    <label>PLUGINS_WEB_RIGHTS_PAGE_VISIBLE_BUTTON_LABEL</label>
+                    <description>PLUGINS_WEB_RIGHTS_PAGE_VISIBLE_BUTTON_DESC</description>
+                    <category>PLUGINS_WEB_RIGHTS_SITEMAP_CATEGORY</category>
+                </right>
+             </extension>
+            
+            <extension id="org.ametys.web.button.page.visible"
+                       point="org.ametys.cms.workspace.ribbon.RibbonControlsManager" 
+                       class="org.ametys.web.clientsideelement.ModifiablePageClientSideElement">
+                <action class="org.ametys.web.page.PageVisibleButton">
+                    <param name="action">org.ametys.web.page.actions.PageVisibleActions.changeVisibility</param>
+                    
+                    <param name="label" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_LABEL</param>
+                    <param name="default-description" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_DESC</param>
+                    <param name="footer" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_FOOT</param>
+                    
+                    <param name="no-page-selected" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_NO_PAGE</param>
+                    <param name="refresh-description" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_REFRESHING</param>
+                    <param name="too-many-page" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_TOOMANYPAGE</param>
+                    <param name="no-modifiable-visible-page-selected" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_VISIBLE_NO_MODIFIABLE_PAGE</param>
+                    <param name="no-modifiable-invisible-page-selected" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_INVISIBLE_NO_MODIFIABLE_PAGE</param>
+                    <param name="page-visible" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_VISIBLE_PAGE</param>
+                    <param name="page-invisible" i18n="true">PLUGINS_WEB_PAGE_VISIBLE_BUTTON_INVISIBLE_PAGE</param>
+                     
+                    <param name="icon-small" file="true">img/page/visible_16.png</param>
+                    <param name="icon-medium" file="true">img/page/visible_32.png</param>
+                    <param name="icon-large" file="true">img/page/visible_48.png</param>
+                    
+                    <param name="icon-small-invisible" file="true">img/page/invisible_16.png</param>
+                    <param name="icon-medium-invisible" file="true">img/page/invisible_32.png</param>
+                    <param name="icon-large-invisible" file="true">img/page/invisible_48.png</param>
+                </action>
+                <scripts>
+                    <file>js/org/ametys/web/page/PageVisibleButton.js</file>
+                    <file>js/org/ametys/web/page/PageVisibleActions.i18n.js</file>
+                </scripts>
+                <right>Web_Right_Page_Visible</right>
+            </extension>
+        </extensions>
+    </feature>
 </plugin>
Index: main/plugin-web/resources/js/org/ametys/web/page/PageVisibleActions.i18n.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/page/PageVisibleActions.i18n.js	(revision 0)
+++ main/plugin-web/resources/js/org/ametys/web/page/PageVisibleActions.i18n.js	(revision 0)
@@ -0,0 +1,50 @@
+/*
+ *  Copyright 2016 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+Ext.namespace('org.ametys.web.page.actions.PageVisibleActions');
+
+/**
+ * Change page visibility
+ */
+org.ametys.web.page.actions.PageVisibleActions.changeVisibility = function(controlId, controlConfiguration, controlPluginName)
+{
+	var control = org.ametys.ribbon.RibbonManager.getInstance().getControls()[controlId];
+	var pageId = control._currentPageId;
+
+	if (pageId == null)
+		return;
+	
+	var targets = org.ametys.ribbon.RibbonManager.getInstance().getCurrentSelectionTargets();
+	var pageTarget = org.ametys.messagebus.message.MessageTargetHelper.findFirst(targets, function (target) {return target.getType() == 'page';});
+	
+	var serverMessage = new org.ametys.servercomm.ServerMessage('web', '/page/change-page-visibility', {id: pageId}, org.ametys.servercomm.ServerComm.PRIORITY_MAJOR, org.ametys.web.page.actions.PageVisibleActions._changeVisibilityCB, this, [pageTarget]);
+	org.ametys.servercomm.ServerComm.getInstance().send(serverMessage);
+}
+
+org.ametys.web.page.actions.PageVisibleActions._changeVisibilityCB = function(response, args)
+{
+	if (org.ametys.servercomm.ServerComm.handleBadResponse("<i18n:text i18n:catalogue="plugin.web" i18n:key="PLUGINS_WEB_PAGE_VISIBLE_BUTTON_ERROR"/>", response, "org.ametys.web.page.actions.PageVisibleActions"))
+	{
+		return;
+	}
+	
+	var events =[];
+	events.push(org.ametys.messagebus.bus.MessageBuilder.getInstance().createMessage(org.ametys.ribbon.RibbonManager.EVENTTYPE_METADATACHANGED, null, [args[0]]));
+	events.push(org.ametys.messagebus.bus.MessageBuilder.getInstance().createMessage("needReload", null, [args[0]]));
+	
+	org.ametys.messagebus.MessageBus.getInstance().fireMessages(events);
+}
+
Index: main/plugin-web/resources/js/org/ametys/web/page/PageVisibleButton.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/page/PageVisibleButton.js	(revision 0)
+++ main/plugin-web/resources/js/org/ametys/web/page/PageVisibleButton.js	(revision 0)
@@ -0,0 +1,170 @@
+/*
+ *  Copyright 2016 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+Ext.namespace('org.ametys.web.page');
+
+org.ametys.web.page.PageVisibleButton = function(id, configuration, pluginName)
+{
+	org.ametys.web.page.PageVisibleButton.superclass.constructor.call(this, id, configuration, pluginName);
+};
+
+Ext.extend(org.ametys.web.page.PageVisibleButton, org.ametys.ribbon.control.button.ActionButton, {});
+
+org.ametys.web.page.PageVisibleButton.prototype._currentPageId;
+
+org.ametys.web.page.PageVisibleButton.prototype.onMessage = function (messages)
+{
+	// SELECTION
+	for (var i=messages.length - 1; i >= 0; i--)
+	{
+		if (messages[i].getType().getName() == org.ametys.ribbon.RibbonManager.EVENTTYPE_SELECTIONCHANGED)
+		{
+			var targets = messages[i].getTargets();
+			var allTargets = org.ametys.messagebus.message.MessageTargetHelper.findAll(targets, function (target) { return target.getType() == 'page'});
+			
+			if (allTargets.length == 0)
+			{
+				// No page selected
+				this.getElements().each(function(element) { element.setDisabled(true); });
+				this.updateTooltip(this.getConfiguration()["no-page-selected"]);
+				
+				this._currentPageId = null;
+			}
+			else if (allTargets.length > 1)
+			{
+				// Too many pages selected
+				this.getElements().each(function(element) { element.setDisabled(true); });
+				this.updateTooltip(this.getConfiguration()["too-many-pages"]);
+				
+				this._currentPageId = null;
+			}
+			else
+			{
+				this.getElements().each(function(element) { element.refreshing(); element.setDisabled(true); });
+				this.updateTooltip(this.getConfiguration()["default-description"]);
+				org.ametys.ribbon.RibbonManager.getInstance().refreshElement('control', this, {target: allTargets[0].getParameters().id});
+			}
+			
+			return;
+		}
+		else if (messages[i].getType().getName() == org.ametys.ribbon.RibbonManager.EVENTTYPE_METADATACHANGED)
+		{
+			var targets = messages[i].getTargets();
+			var target = org.ametys.messagebus.message.MessageTargetHelper.findFirst(targets, function (target) { return target.getType() == 'page'});
+			
+			if (target != null && this._currentPageId == target.getParameters().id)
+			{
+				this.getElements().each(function(element) { element.refreshing(); element.setDisabled(true); });
+				this.updateTooltip(this.getConfiguration()["default-description"]);
+				org.ametys.ribbon.RibbonManager.getInstance().refreshElement('control', this, {target: target.getParameters().id});
+			}
+		}
+	}
+}
+
+org.ametys.web.page.PageVisibleButton.prototype.configurationChanged = function(params)
+{
+	this.getElements().each(function(element) { element.stopRefreshing(); });
+	
+	var disabledState = this._isDisabled(params);
+	var toggleState = this._isToggle(params);
+	this._toggleState = toggleState;
+	this.getElements().each(function(element) { element.setDisabled(disabledState); });
+	this.getElements().each(function(element) { element.toggle(toggleState); });
+
+	this._getIcon(params);
+	this.getElements().each(function(element) { element.updateIcon(); });
+	
+	var tooltip = this._getTooltip(params);
+	var icon = context.contextPath + this.getConfiguration()['icon-large'];
+	if (params['page-visibility'] == "false")
+	{
+		icon = context.contextPath + this.getConfiguration()['icon-large-invisible'];
+	}
+	this.updateTooltip(tooltip, icon);
+}
+
+org.ametys.web.page.PageVisibleButton.prototype._isDisabled = function(params)
+{
+    return params['page-id'] == null;
+}
+
+org.ametys.web.page.PageVisibleButton.prototype._isToggle = function(params)
+{
+	return params['page-visibility'] == "false";
+}
+
+org.ametys.web.page.PageVisibleButton.prototype._getIcon = function(params)
+{
+	if (params['page-visibility'] == "false")
+	{
+		var iconSmall = context.contextPath + this.getConfiguration()['icon-small-invisible'];
+		var iconLarge = context.contextPath + this.getConfiguration()['icon-medium-invisible'];
+		this.getElements().each(
+			function (element) 
+			{
+				element.iconSmall = iconSmall;
+				element.iconLarge = iconLarge;
+			}
+		);
+	}
+	else
+	{
+		var iconSmall = context.contextPath + this.getConfiguration()['icon-small'];
+		var iconLarge = context.contextPath + this.getConfiguration()['icon-medium'];
+		this.getElements().each(
+			function (element) 
+			{
+				element.iconSmall = iconSmall;
+				element.iconLarge = iconLarge;
+			}
+		);
+	}
+}
+
+org.ametys.web.page.PageVisibleButton.prototype._getTooltip = function(params)
+{
+	var tooltip;
+	if (params['page-id'] != null)
+	{
+		this._currentPageId = params['page-id'];
+		if (params['page-visibility'] == "false")
+		{
+			tooltip = this.getConfiguration()["page-invisible"];
+		}
+		else
+		{
+			tooltip = this.getConfiguration()["page-visible"];
+		}
+	}
+	else if (params['no-modifiable-page-selected'])
+	{
+		if (params['page-visibility'] == "false")
+		{
+			tooltip = this.getConfiguration()["no-modifiable-invisible-page-selected"];
+		}
+		else
+		{
+			tooltip = this.getConfiguration()["no-modifiable-visible-page-selected"];
+		}
+	}
+	else
+	{
+		tooltip = this.getConfiguration()["no-page-selected"];
+	}
+	
+	return tooltip;
+}
Index: main/plugin-web/sitemap-back.xmap
===================================================================
--- main/plugin-web/sitemap-back.xmap	(revision 39808)
+++ main/plugin-web/sitemap-back.xmap	(working copy)
@@ -182,6 +182,8 @@
 		  	<map:action name="get-content" src="org.ametys.cms.content.GetContentAction" logger="org.ametys.cms.content.GetContentAction"/>
 		  	
 		  	<map:action name="set-header" src="org.apache.cocoon.acting.HttpHeaderAction"/>
+		  	
+		  	<map:action name="change-page-visibility" src="org.ametys.web.repository.page.actions.ChangePageVisibilityAction"/>
 		</map:actions>
 	</map:components>
 	
@@ -1446,6 +1448,18 @@
                 </map:act>
             </map:match>
                 
+            <!-- +
+                 | PAGE VISIBILITY
+                 + -->
+            <map:match pattern="page/change-page-visibility">
+                <map:act type="change-page-visibility">
+                    <map:parameter name="id" value="{request-param:id}"/>
+                    
+                    <map:generate type="action-result"/>
+                    <map:serialize type="xml"/>
+                </map:act>
+            </map:match>    
+                     
     		<!-- +
     		     | LAST PUBLICATION
     		     + -->
Index: main/plugin-web/sitemap-front.xmap
===================================================================
--- main/plugin-web/sitemap-front.xmap	(revision 39808)
+++ main/plugin-web/sitemap-front.xmap	(working copy)
@@ -141,7 +141,8 @@
 				<map:generate type="service-sitemap">
 					<map:parameter name="depth" value="{parent-context-attr:depth}"/>
 					<map:parameter name="all" value="{parent-context-attr:all}"/>
-				</map:generate>
+				    <map:parameter name="includeInvisiblePage" value="{parent-context-attr:includeInvisiblePage}"/>
+                </map:generate>
 				<map:transform type="xslt" src="service://@xslt"/>
 				<map:transform type="i18n">
 					<map:parameter name="locale" value="{request-attr:sitemapLanguage}"/>
Index: main/plugin-web/src/org/ametys/web/clientsideelement/ModifiablePageClientSideElement.java
===================================================================
--- main/plugin-web/src/org/ametys/web/clientsideelement/ModifiablePageClientSideElement.java	(revision 0)
+++ main/plugin-web/src/org/ametys/web/clientsideelement/ModifiablePageClientSideElement.java	(revision 0)
@@ -0,0 +1,68 @@
+/*
+ *  Copyright 2016 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.web.clientsideelement;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.commons.lang.StringUtils;
+
+import org.ametys.plugins.repository.AmetysObjectResolver;
+import org.ametys.runtime.ui.impl.StaticContextualClientSideElement;
+import org.ametys.runtime.util.I18nizableText;
+import org.ametys.web.repository.page.ModifiablePage;
+import org.ametys.web.repository.page.Page;
+
+/**
+ * Client side element for modifiable page
+ */
+public class ModifiablePageClientSideElement extends StaticContextualClientSideElement
+{
+    /** Repository content */
+    protected AmetysObjectResolver _resolver;
+
+    @Override
+    public void service(ServiceManager smanager) throws ServiceException
+    {
+        super.service(smanager);
+        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
+    }
+    
+    @Override
+    public Map<String, I18nizableText> getCurrentParameters(Map<String, Object> parameters)
+    {
+        Map<String, I18nizableText> results = new HashMap<String, I18nizableText>();
+
+        String pageId = (String) parameters.get("target");
+        if (StringUtils.isNotBlank(pageId))
+        {
+            Page page = _resolver.resolveById(pageId);
+            if (page instanceof ModifiablePage)
+            {
+                results.put("page-id", new I18nizableText(page.getId()));
+            }
+            else
+            {
+                results.put("no-modifiable-page-selected", new I18nizableText("true"));
+            }
+            results.put("page-visibility", new I18nizableText(String.valueOf(page.isVisible())));
+        }
+
+        return results;
+    }
+}
Index: main/plugin-web/src/org/ametys/web/inputdata/SitemapInputData.java
===================================================================
--- main/plugin-web/src/org/ametys/web/inputdata/SitemapInputData.java	(revision 39808)
+++ main/plugin-web/src/org/ametys/web/inputdata/SitemapInputData.java	(working copy)
@@ -30,6 +30,7 @@
 import org.apache.cocoon.environment.Request;
 import org.apache.cocoon.xml.AttributesImpl;
 import org.apache.cocoon.xml.XMLUtils;
+import org.apache.commons.lang.StringUtils;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 
@@ -168,7 +169,14 @@
             if ((inBackOffice || policy == RestrictedPagePolicy.DISPLAYED || _accessManager.hasRight(page, login)) && _processPage(page))
             {
                 PageAccessInfo info = _accessManager.getAccessInfo(page);
-                _saxPage(handler, currentPagePath, currentDepth, descendantDepth, policy, login, page, info);
+                if (page.isVisible())
+                {
+                    _saxPage(handler, currentPagePath, currentDepth, descendantDepth, policy, login, page, info);
+                }
+                else if (StringUtils.isNotBlank(currentPagePath) && currentPagePath.startsWith(page.getPathInSitemap()))
+                {
+                    _saxPage(handler, currentPagePath, currentDepth, descendantDepth, policy, login, page, info);
+                }
             }
         }
     }
Index: main/plugin-web/src/org/ametys/web/repository/dom/PagesContainerElement.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/dom/PagesContainerElement.java	(revision 39808)
+++ main/plugin-web/src/org/ametys/web/repository/dom/PagesContainerElement.java	(working copy)
@@ -97,7 +97,7 @@
     {
         if (_children == null)
         {
-            _children = _object.getChildrenPages();
+            _children = _object.getChildrenPages(false);
         }
         
         return _children;
@@ -108,7 +108,7 @@
     {
         if (_children == null)
         {
-            _children = _object.getChildrenPages();
+            _children = _object.getChildrenPages(false);
         }
         
         return _children.hasNext();
@@ -120,7 +120,7 @@
     {
         if (_children == null)
         {
-            _children = _object.getChildrenPages();
+            _children = _object.getChildrenPages(false);
         }
         
         if (!_children.hasNext())
Index: main/plugin-web/src/org/ametys/web/repository/page/ModifiablePage.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/page/ModifiablePage.java	(revision 39808)
+++ main/plugin-web/src/org/ametys/web/repository/page/ModifiablePage.java	(working copy)
@@ -119,4 +119,11 @@
      * @throws AmetysRepositoryException if an error occurs.
      */
     void removeReferer(String ametysObjectId) throws AmetysRepositoryException;
+    
+    /**
+     * Set the page visibility.
+     * @param isVisible the page visibility.
+     * @throws AmetysRepositoryException if an error occurs.
+     */
+    void setVisible(boolean isVisible) throws AmetysRepositoryException;
 }
Index: main/plugin-web/src/org/ametys/web/repository/page/Page.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/page/Page.java	(revision 39808)
+++ main/plugin-web/src/org/ametys/web/repository/page/Page.java	(working copy)
@@ -136,4 +136,11 @@
      * @throws AmetysRepositoryException if an error occurs.
      */
     Set<String> getReferers() throws AmetysRepositoryException;
+    
+    /**
+     * Determine if the page is visible.
+     * @return true if the page is visible.
+     * @throws AmetysRepositoryException if an error occurs.
+     */
+    boolean isVisible() throws AmetysRepositoryException;
 }
Index: main/plugin-web/src/org/ametys/web/repository/page/PagesContainer.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/page/PagesContainer.java	(revision 39808)
+++ main/plugin-web/src/org/ametys/web/repository/page/PagesContainer.java	(working copy)
@@ -54,4 +54,12 @@
      */
     AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException;
     
+    /**
+     * Retrieves child pages.
+     * @param includeInvisiblePages true to include invisible pages
+     * @return the child pages.
+     * @throws AmetysRepositoryException if an error occurs.
+     */
+    AmetysObjectIterable<? extends Page> getChildrenPages(boolean includeInvisiblePages) throws AmetysRepositoryException;
+    
 }
Index: main/plugin-web/src/org/ametys/web/repository/page/actions/ChangePageVisibilityAction.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/page/actions/ChangePageVisibilityAction.java	(revision 0)
+++ main/plugin-web/src/org/ametys/web/repository/page/actions/ChangePageVisibilityAction.java	(revision 0)
@@ -0,0 +1,69 @@
+/*
+ *  Copyright 2016 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.web.repository.page.actions;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.acting.ServiceableAction;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.commons.lang.StringUtils;
+
+import org.ametys.plugins.repository.AmetysObjectResolver;
+import org.ametys.web.repository.page.ModifiablePage;
+import org.ametys.web.repository.page.Page;
+
+/**
+ * Change the page visibility
+ */
+public class ChangePageVisibilityAction extends ServiceableAction
+{
+    /** The ametys Object resolver */
+    protected AmetysObjectResolver _resolver;
+    
+    @Override
+    public void service(ServiceManager smanager) throws ServiceException 
+    {
+        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
+    }
+    
+    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
+    {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        String pageId = request.getParameter("id");
+        
+        if (StringUtils.isBlank(pageId))
+        {
+            return null;
+        }
+        
+        Page page = _resolver.resolveById(pageId);
+        if (page instanceof ModifiablePage)
+        {
+            ModifiablePage modifiablePage = (ModifiablePage) page;
+            modifiablePage.setVisible(!page.isVisible());
+            modifiablePage.saveChanges();
+        }
+        
+        return EMPTY_MAP;
+    }
+
+}
Index: main/plugin-web/src/org/ametys/web/repository/page/jcr/DefaultPage.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/page/jcr/DefaultPage.java	(revision 39808)
+++ main/plugin-web/src/org/ametys/web/repository/page/jcr/DefaultPage.java	(working copy)
@@ -82,6 +82,9 @@
     /** Constant for referers metadata. */
     public static final String METADATA_REFERERS = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":referers";
 
+    /** Constant for the visible attribute. */
+    public static final String METADATA_VISIBLE = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":visible";
+
     /** Constant for robots metadata. */
     public static final String METADATA_ROBOTS_DISALLOW = "robots-disallow";
     
@@ -550,6 +553,29 @@
         }
         return new CollectionIterable<Page>(childrenPages);
     }
+    
+    @Override
+    public AmetysObjectIterable< ? extends Page> getChildrenPages(boolean includeInvisiblePage) throws AmetysRepositoryException
+    {
+        List<Page> childrenPages = new ArrayList<Page>();
+        for (AmetysObject childObject : getChildren())
+        {
+            if (childObject instanceof Page)
+            {
+                Page page = (Page) childObject;
+                if (includeInvisiblePage)
+                {
+                    childrenPages.add(page);
+                }
+                else if (page.isVisible())
+                {
+                    childrenPages.add(page);
+                }
+                    
+            }
+        }
+        return new CollectionIterable<Page>(childrenPages);
+    }
 
     @Override
     public DefaultPage copyTo(ModifiableTraversableAmetysObject parent, String name, List<String> restrictTo) throws AmetysRepositoryException
@@ -709,4 +735,37 @@
             throw new AmetysRepositoryException(String.format("Unable to order page '%s' before sibling '%s'", this, siblingNode != null ? siblingNode.getName() : ""), e);
         }
     }
+
+    @Override
+    public boolean isVisible() throws AmetysRepositoryException
+    {
+        try
+        {
+            if (getNode().hasProperty(METADATA_VISIBLE))
+            {
+                return getNode().getProperty(METADATA_VISIBLE).getBoolean();
+            }
+            else
+            {
+                return true;
+            }
+        }
+        catch (RepositoryException e)
+        {
+            throw new AmetysRepositoryException("Unable to get visible property", e);
+        }
+    }
+    
+    @Override
+    public void setVisible(boolean isVisible) throws AmetysRepositoryException
+    {
+        try
+        {
+            getNode().setProperty(METADATA_VISIBLE, isVisible);
+        }
+        catch (RepositoryException e)
+        {
+            throw new AmetysRepositoryException("Unable to set visible property", e);
+        }
+    }
 }
Index: main/plugin-web/src/org/ametys/web/repository/sitemap/Sitemap.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/sitemap/Sitemap.java	(revision 39808)
+++ main/plugin-web/src/org/ametys/web/repository/sitemap/Sitemap.java	(working copy)
@@ -15,11 +15,15 @@
  */
 package org.ametys.web.repository.sitemap;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import javax.jcr.Node;
 
 import org.ametys.plugins.repository.AmetysObject;
 import org.ametys.plugins.repository.AmetysObjectIterable;
 import org.ametys.plugins.repository.AmetysRepositoryException;
+import org.ametys.plugins.repository.CollectionIterable;
 import org.ametys.plugins.repository.RepositoryConstants;
 import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject;
 import org.ametys.web.repository.page.MetadataAwarePagesContainer;
@@ -58,6 +62,28 @@
     }
     
     @Override
+    public AmetysObjectIterable< ? extends Page> getChildrenPages(boolean includeInvisiblePage) throws AmetysRepositoryException
+    {
+        if (includeInvisiblePage)
+        {
+            return getChildrenPages();
+        }
+        else
+        {
+            List<Page> pages = new ArrayList<Page>();
+            for (Page page : getChildrenPages())
+            {
+                if (page.isVisible())
+                {
+                    pages.add(page);
+                }
+            }
+            
+            return new CollectionIterable<Page>(pages);
+        }
+    }
+
+    @Override
     public Site getSite() throws AmetysRepositoryException
     {
         return getParent().getParent();
@@ -80,4 +106,5 @@
     {
         return getName();
     }
+
 }
Index: main/plugin-web/src/org/ametys/web/repository/sitemap/generators/SitemapGenerator.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/sitemap/generators/SitemapGenerator.java	(revision 39808)
+++ main/plugin-web/src/org/ametys/web/repository/sitemap/generators/SitemapGenerator.java	(working copy)
@@ -73,27 +73,28 @@
         
         int depth = parameters.getParameterAsInteger("depth", -1);
         boolean all = parameters.getParameterAsBoolean("all", true);
+        boolean includeInvisblePage = parameters.getParameterAsBoolean("includeInvisiblePage", false);
         
         contentHandler.startDocument();
         
         XMLUtils.startElement(contentHandler, "sitemap");
         
         String login = (String) request.getAttribute(WebConstants.FO_LOGIN);
-        _saxPagesContainer(all ? sitemap : page, login, sitemap.getSite().getRestrictedPagePolicy(), depth);
+        _saxPagesContainer(all ? sitemap : page, login, sitemap.getSite().getRestrictedPagePolicy(), depth, includeInvisblePage);
         
         XMLUtils.endElement(contentHandler, "sitemap");
         
         contentHandler.endDocument();
     }
     
-    private void _saxPagesContainer(PagesContainer pagesContainer, String login, RestrictedPagePolicy policy, int depth) throws SAXException
+    private void _saxPagesContainer(PagesContainer pagesContainer, String login, RestrictedPagePolicy policy, int depth, boolean includeInvisblePage) throws SAXException
     {
         if (depth != 0)
         {
             RenderingContext renderingContext = _renderingContextHandler.getRenderingContext();
             boolean inBackOffice = renderingContext == RenderingContext.BACK || renderingContext == RenderingContext.PREVIEW;
             
-            for (Page page : pagesContainer.getChildrenPages())
+            for (Page page : pagesContainer.getChildrenPages(includeInvisblePage))
             {
                 PageAccessInfo info = _accessManager.getAccessInfo(page);
                 boolean accessGranted = _accessManager.hasRight(page, login);
@@ -119,7 +120,7 @@
                     
                     XMLUtils.startElement(contentHandler, "page", attrs);
                     
-                    _saxPagesContainer(page, login, policy, depth - 1);
+                    _saxPagesContainer(page, login, policy, depth - 1, includeInvisblePage);
                     
                     XMLUtils.endElement(contentHandler, "page");
                 }
Index: main/plugin-web/stylesheets/utils.xsl
===================================================================
--- main/plugin-web/stylesheets/utils.xsl	(revision 39808)
+++ main/plugin-web/stylesheets/utils.xsl	(working copy)
@@ -27,6 +27,7 @@
     <xsl:template name="common-utils-pagination">
         <xsl:param name="nbPages"/>
         <xsl:param name="current-page"/>
+        <xsl:param name="hasNbPages" select="true()" />
         
         <span class="label"><i18n:text i18n:key="FRONT_MODULE_SEARCH_NAV_PAGES" i18n:catalogue="plugin.web"/></span>
         <ul class="nav">
@@ -52,6 +53,7 @@
                 </li>
             </xsl:if>
             
+            <xsl:if test="$hasNbPages">
             <xsl:for-each select="$current-page/preceding-sibling::page[position() &lt; 4]">
                  <li>
                     <xsl:call-template name="common-utils-input-submit">
@@ -60,39 +62,57 @@
                     </xsl:call-template>                            
                  </li>
             </xsl:for-each>
+            </xsl:if>
             
              <li class="current"><span class="current"><xsl:value-of select="$current-page/@index"/></span></li>
             
-            <xsl:for-each select="$current-page/following-sibling::page[position() &lt; 4]">
-                 <li>
-                    <xsl:call-template name="common-utils-input-submit">
-                        <xsl:with-param name="text"><xsl:value-of select="@index"/></xsl:with-param>
-                        <xsl:with-param name="name">page-<xsl:value-of select="@index"/></xsl:with-param>                                
-                    </xsl:call-template>                            
-                 </li>
-            </xsl:for-each>
-                        
-            <xsl:if test="$current-page/@index != $nbPages">
-            <!--  Next page -->
-                <li class="next">
-                    <xsl:call-template name="common-utils-input-submit">
-                        <xsl:with-param name="i18nkey" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_NEXT'" />
-                        <xsl:with-param name="i18ntitle" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_NEXT_TITLE'" />
-                        <xsl:with-param name="name">page-<xsl:value-of select="$current-page/following-sibling::page[1]/@index"/></xsl:with-param>                                
-                    </xsl:call-template>                                            
-                </li>
-            </xsl:if>
-            
-            <xsl:if test="$current-page/@index &lt; ($nbPages - 2)">
-            <!-- Last page -->
-                <li class="last">   
-                    <xsl:call-template name="common-utils-input-submit">
-                        <xsl:with-param name="i18nkey" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_LAST'" />
-                        <xsl:with-param name="i18ntitle" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_LAST_TITLE'" />
-                        <xsl:with-param name="name">page-<xsl:value-of select="$current-page/../page[position() = last()]/@index"/></xsl:with-param>                                
-                    </xsl:call-template>
-                </li>
-            </xsl:if>            
+            <xsl:if test="$hasNbPages">
+                <xsl:for-each select="$current-page/following-sibling::page[position() &lt; 4]">
+                     <li>
+                        <xsl:call-template name="common-utils-input-submit">
+                            <xsl:with-param name="text"><xsl:value-of select="@index"/></xsl:with-param>
+                            <xsl:with-param name="name">page-<xsl:value-of select="@index"/></xsl:with-param>                                
+                        </xsl:call-template>                            
+                     </li>
+                </xsl:for-each>
+            </xsl:if>           
+            <xsl:choose>
+                <xsl:when test="$hasNbPages">
+                    <xsl:if test="$current-page/@index != $nbPages">
+                        <!--  Next page -->
+                        <li class="next">
+                            <xsl:call-template name="common-utils-input-submit">
+                                <xsl:with-param name="i18nkey" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_NEXT'" />
+                                <xsl:with-param name="i18ntitle" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_NEXT_TITLE'" />
+                                <xsl:with-param name="name">page-<xsl:value-of select="$current-page/following-sibling::page[1]/@index"/></xsl:with-param>                                
+                            </xsl:call-template>                                            
+                        </li>
+                    </xsl:if>
+                    
+                    <xsl:if test="$current-page/@index &lt; ($nbPages - 2)">
+                    <!-- Last page -->
+                        <li class="last">   
+                            <xsl:call-template name="common-utils-input-submit">
+                                <xsl:with-param name="i18nkey" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_LAST'" />
+                                <xsl:with-param name="i18ntitle" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_LAST_TITLE'" />
+                                <xsl:with-param name="name">page-<xsl:value-of select="$current-page/../page[position() = last()]/@index"/></xsl:with-param>                                
+                            </xsl:call-template>
+                        </li>
+                    </xsl:if>            
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:if test="$current-page/@index != $nbPages">
+                        <!--  Next page -->
+                        <li class="next">
+                            <xsl:call-template name="common-utils-input-submit">
+                                <xsl:with-param name="i18nkey" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_NEXT'" />
+                                <xsl:with-param name="i18ntitle" select="'plugin.web:FRONT_MODULE_SEARCH_NAV_NEXT_TITLE'" />
+                                <xsl:with-param name="name">page-<xsl:value-of select="$current-page/following-sibling::page[1]/@index"/></xsl:with-param>                                
+                            </xsl:call-template>                                            
+                        </li>
+                    </xsl:if>
+                </xsl:otherwise>
+            </xsl:choose>
         </ul>
     </xsl:template>
     
