Index: main/plugin-web/i18n/messages_en.xml
===================================================================
--- main/plugin-web/i18n/messages_en.xml	(revision 32530)
+++ main/plugin-web/i18n/messages_en.xml	(working copy)
@@ -2003,7 +2004,9 @@
 	<message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION_STARTDATE">Start :</message>
 	<message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION_ENDDATE">End :</message>
 	<message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_TYPE">Type</message>
-		
+    <message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_EMPTY">No page is currently selected.&lt;br/&gt;Select a page in order to see its properties.</message>
+    <message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_MULTI_SELECT_FORBIDDEN">Several pages are currently selected.&lt;br/&gt;Select a page to show its properties.</message>
+    		
 	<!--  +
 		  | WIDGET
 		  + -->
Index: main/plugin-web/i18n/messages_fr.xml
===================================================================
--- main/plugin-web/i18n/messages_fr.xml	(revision 32530)
+++ main/plugin-web/i18n/messages_fr.xml	(working copy)
@@ -2005,6 +2006,8 @@
 	<message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION_STARTDATE">Début :</message>
 	<message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION_ENDDATE">Fin :</message>
 	<message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_TYPE">Type</message>
+    <message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_EMPTY">Aucune page n'est actuellement sélectionnée.&lt;br/&gt;Sélectionnez une page pour voir ses propriétés.</message>
+    <message key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_MULTI_SELECT_FORBIDDEN">Plusieurs pages sont actuellement sélectionnées.&lt;br/&gt;Sélectionnez une page pour ses propriétés.</message>
 	
 	<!--  +
 		  | WIDGET
Index: main/plugin-web/plugin.xml
===================================================================
--- main/plugin-web/plugin.xml	(revision 32530)
+++ main/plugin-web/plugin.xml	(working copy)
@@ -2113,45 +2113,53 @@
 	
 	<feature name="userinterface.page.properties">
     	<extensions>
-    		<!-- <extension id="org.ametys.web.page.Properties"
-    				   point="org.ametys.core.ui.RibbonControlsManager"
-    				   class="org.ametys.core.ui.StaticClientSideElement">
-				<action class="org.ametys.ribbon.control.button.UniqueInstanceToolAndSelectionButton">
-					<param name="role">uitool-page-properties</param>
-					<param name="target-type">^page$</param>
-					
-					<param name="label" i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LABEL</param>
-					<param name="default-description" i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_DESC</param>
-					<param name="footer" i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_FOOTER</param>
-					<param name="icon-small" file="true">img/page/page_properties_16.png</param>
-					<param name="icon-medium" file="true">img/page/page_properties_32.png</param>
-					<param name="icon-large" file="true">img/page/page_properties_48.png</param>
-				</action>    				   
-    		</extension>
-    		
-    		<extension id="org.ametys.web.page.PropertiesFactory"
-    				   point="org.ametys.core.ui.UIToolsFactoriesManager"
-    				   class="org.ametys.core.ui.StaticClientSideElement">
-				<action class="org.ametys.web.page.PagePropertiesToolFactory">
-					<param name="role">uitool-page-properties</param>
-					<param name="title" i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LABEL</param>
-					<param name="description" i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_DESC</param>
-					<param name="footer" i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_FOOTER</param>
-					<param name="icon-small" file="true">img/page/page_properties_16.png</param>
-					<param name="icon-medium" file="true">img/page/page_properties_32.png</param>
-					<param name="icon-large" file="true">img/page/page_properties_48.png</param>
-					<param name="default-location">l</param>
-				</action>    				   
-				<scripts>
-					<file plugin="cms">js/org/ametys/cms/tool/details/DetailsTool.js</file>
-					<file plugin="cms">js/org/ametys/cms/tool/details/DetailsToolFactory.js</file>
-					<file>js/org/ametys/web/page/PagePropertiesTool.js</file>
-					<file>js/org/ametys/web/page/PagePropertiesToolFactory.js</file>
-				</scripts>
-				<css>
-					<file plugin="cms">css/detail.css</file>
-				</css>
-    		</extension> -->
+    	
+	       <extension id="org.ametys.web.page.Properties"  
+                       point="org.ametys.core.ui.RibbonControlsManager" 
+                       class="org.ametys.core.ui.StaticClientSideElement">
+                <!-- 
+                    This interaction allows the administrator to see the properties of a page
+                 -->
+                 <class name="Ametys.ribbon.element.ui.button.OpenToolButtonController">
+                    <opentool-role>uitool-page-properties</opentool-role>
+                    <selection-target-type>^page$</selection-target-type>
+
+                    <label i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LABEL</label>
+                    <description i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_DESC</description>
+                    <default-description i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_DESC</default-description>
+                    
+                    <icon-small file="true">img/page/page_properties_16.png</icon-small>
+                    <icon-medium file="true">img/page/page_properties_32.png</icon-medium>
+                    <icon-large file="true">img/page/page_properties_48.png</icon-large>
+                </class>
+            </extension> 
+            
+            <extension id="org.ametys.web.page.PropertiesFactory"  
+                       point="org.ametys.core.ui.UIToolsFactoriesManager" 
+                       class="org.ametys.core.ui.StaticClientSideElement">
+                <class name="Ametys.tool.factory.UniqueToolFactory">
+                    <role>uitool-page-properties</role>
+                    <toolClass>Ametys.plugins.web.page.PagePropertiesTool</toolClass>
+                    <selection-target-type>^page$</selection-target-type>
+
+                    <title i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LABEL</title>
+                    <description i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_DESC</description>
+                    
+                    <selection-description-empty i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_EMPTY</selection-description-empty>
+                    <selection-description-nomatch i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_EMPTY</selection-description-nomatch>
+                    <selection-description-multiselectionforbidden i18n="true">PLUGINS_WEB_TOOL_PAGE_PROPERTIES_MULTI_SELECT_FORBIDDEN</selection-description-multiselectionforbidden>
+                    
+                    <icon-small file="true">img/page/page_properties_16.png</icon-small>
+                    <icon-medium file="true">img/page/page_properties_32.png</icon-medium>
+                    <icon-large file="true">img/page/page_properties_48.png</icon-large>
+                    
+                    <default-location>l</default-location>
+                </class>
+                <scripts>
+                    <file>js/Ametys/plugins/web/page/PagePropertiesTool.js</file>
+                </scripts>
+                <default-location>c</default-location>
+            </extension>
 		</extensions>
 	</feature>
     
Index: main/plugin-web/resources/js/Ametys/plugins/web/page/PagePropertiesTool.js
===================================================================
--- main/plugin-web/resources/js/Ametys/plugins/web/page/PagePropertiesTool.js	(revision 0)
+++ main/plugin-web/resources/js/Ametys/plugins/web/page/PagePropertiesTool.js	(revision 0)
@@ -0,0 +1,348 @@
+/*
+ *  Copyright 2015 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.
+ */
+
+/**
+ * This tool displays the properties of a page
+ */
+Ext.define('Ametys.plugins.web.page.PagePropertiesTool', {
+	extend: 'Ametys.tool.SelectionTool',
+		
+	/**
+	 * @private
+	 * @property {Ext.Container} _pagePropertiesPanel The page properties panel
+	 */
+	
+	constructor: function() 
+	{
+		this.callParent(arguments);
+		
+		Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onDeleted, this);
+		Ametys.message.MessageBus.on(Ametys.message.Message.METADATA_CHANGED, this._onMetadataChanged, this);
+	},
+	
+	getMBSelectionInteraction: function() 
+	{
+		return Ametys.tool.Tool.MB_TYPE_LISTENING;
+	},
+	
+	createPanel: function ()
+	{
+		this._pagePropertiesPanel = new Ext.Panel ({
+			autoScroll: true, 
+			border: false,
+			html : '',
+			id : 'details-view',
+			cls : 'details-view'
+		});
+		return this._pagePropertiesPanel;
+	},
+	
+	setParams: function (params)
+	{
+		this.callParent(arguments);
+		this.refresh();
+	},
+	
+	setNoSelectionMatchState: function (message)
+	{
+		this.callParent(arguments);
+		this._pagePropertiesPanel.body.dom.innerHTML = "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_SELECT_PAGE'/>";
+	},
+	
+	refresh: function (manual)
+	{
+		var currentSelectionTargets = this.getCurrentSelectionTargets();
+
+		if (currentSelectionTargets.length > 0)
+		{
+			var target = currentSelectionTargets[0];
+
+			this.showRefreshing();
+			
+			// Server call
+			Ametys.data.ServerComm.callMethod({
+				role: "org.ametys.web.repository.page.SitemapDAO",
+				methodName: "getPageInformation",
+				parameters: [target.getParameters().id],
+				callback: {
+					scope: this,
+					handler: this._refreshCb,
+				},
+				errorMessage: {
+					category: this.self.getName(),
+					msg: "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_ERROR'/>"
+				}
+			});
+		}
+	},
+	
+	/**
+	 * @private
+	 * Callback for the refreshing process
+	 * @param {Object} data the page information
+	 * @param {String} data.id the page's id
+	 * @param {String} data.name the page's name
+	 * @param {String} data.lang the page's lang
+	 * @param {String} data.site the page's site
+	 * @param {String} data.path the page's path
+	 * @param {Object} data.page 
+	 * @param {String} data.page.title the title of the page
+	 * @param {String} data.page.longTitle the long title of the page
+	 * @param {String} data.page.type the type of the page
+	 * @param {String[]} data.page.tags the titles of the tags of the page
+	 * @param {String} [data.page.template] the page's template
+	 * @param {String} [data.page.url] the page's url
+	 * @param {String} [data.page.urlType] the page's url type
+	 * @param {Object[]} data.page.publication the publication dates of the page
+	 * @param {String} [data.page.publication['start-date']] the starting date of the publication
+	 * @param {String} [data.page.publication['start-date']] the ending date of the publication
+	 * @param {Object} data.page.links the links of the page
+	 * @param {Object[]} [data.page.links.contents] the contents linking the page
+	 * @param {String} [data.page.links.contents.id] the id of the page
+	 * @param {String} [data.page.links.contents.name] the name of the page
+	 * @param {String} [data.page.links.contents.title] the title of the page
+	 * @param {Object} [data.page.links.contents.pages] the pages referencing the content
+	 * @param {String} [data.page.links.contents.pages.id] the page's id
+	 * @param {String} [data.page.links.contents.pages.name] the page's name
+	 * @param {String} [data.page.links.contents.pages.site] the page's site
+	 * @param {String} [data.page.links.contents.pages.title] the page's title
+	 * @param {String} [data.page.links.contents.pages.path] the page's path
+	 * @param {Object} [data.page.links.pages] the pages linking the page
+	 * @param {String} [data.page.links.pages.id] the page's id
+	 * @param {String} [data.page.links.pages.name] the page's name
+	 * @param {String} [data.page.links.pages.site] the page's site
+	 * @param {String} [data.page.links.pages.title] the page's title
+	 * @param {String} [data.page.links.pages.path] the page's path
+	 */
+	_refreshCb: function (data)
+	{
+		var values = {};
+		
+		values.lang = data.lang;
+		values.siteName = data.site;
+		values.title = data.page.title;
+		values.longTitle = data.page.longTitle;
+		values.type = data.page.type;
+		values.path = data.lang + "/" + data.path + ".html";
+		
+		var tags = data.page.tags;
+		values['tags-size'] = tags.length;
+		for (var i=0; i < tags.length; i++)
+		{
+			values['tag-' + i] = tags[i];
+		}
+		
+		var contents = data.page.links.contents;
+		values['link-content-size'] = contents.length;
+		for (var i=0; i < contents.length; i++)
+		{
+			var content = {};
+			values['link-content-' + i + '-id'] = contents[i].id;
+			values['link-content-' + i + '-name'] = contents[i].name;
+			values['link-content-' + i + '-title'] = contents[i].title;
+			
+			var pages = contents[i].page;
+			for (var j=0; j < pages.length; j++)
+			{
+				values['link-content-' + i + '-page-' + j + '-id'] = pages[j].id;
+				values['link-content-' + i + '-page-' + j + '-name'] = pages[j].name;
+				values['link-content-' + i + '-page-' + j + '-title'] = pages[j].title;
+				values['link-content-' + i + '-page-' + j + '-site'] = pages[j].site;
+				values['link-content-' + i + '-page-' + j + '-path'] = pages[j].path;
+			}
+		}
+		
+		var pages = data.page.links.pages;
+		values['link-page-size'] = pages.length;
+		for (var i=0; i < pages.length; i++)
+		{
+			values['link-page-' + i + '-id'] = pages[i].id;
+			values['link-page-' + i + '-name'] = pages[i].name;
+			values['link-page-' + i + '-title'] = pages[i].title;
+			values['link-page-' + i + '-site'] = pages[i].site;
+			values['link-page-' + i + '-path'] = pages[i].path;
+		}
+		
+		var pub = data.page.publication;
+		if (pub['start-date'] != null)
+		{
+			values['pub-start-date'] = pub['start-date'];
+		}
+		if (pub['end-date'] != null)
+		{
+			values['pub-end-date'] = pub['end-date'];
+		}
+		
+		var html = this._getHTML (values);
+		
+		this._pagePropertiesPanel.body.update(html);
+		this.showRefreshed();
+	},
+	
+	/**
+	 * Get the html corresponding to the given values
+	 * @param {Object} values the object to convert in html
+	 */
+	_getHTML: function (values)
+	{
+		var html = "";
+		
+		// Page title
+		html += '<p><b>' + "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_TITLE' i18n:catalogue='plugin.web'/>" + '</b><br/>';
+		html += values.title;
+		html += '</p>';
+		
+		// Page long title
+		html += '<p><b>' + "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LONGTITLE' i18n:catalogue='plugin.web'/>" + '</b><br/>';
+		html += values.longTitle;
+		html += '</p>';
+		
+		// Language
+		html += '<p><b>' + "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LANG' i18n:catalogue='plugin.web'/>" + '</b> ';
+		html += values.lang;
+		html += '</p>';
+		
+		// Site
+		html += '<p><b>' + "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_SITE' i18n:catalogue='plugin.web'/>" + '</b> ';
+		html += values.siteName;
+		html += '</p>';
+		
+		// Tags
+		var size = values['tags-size'];
+		if (values['tags-size'] != 0)
+		{
+			html += '<p><b>' + "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_TAGS' i18n:catalogue='plugin.web'/>" + '</b><br/>';
+			html += '<ul>';
+			for (var i=0; i < size; i++)
+			{
+				html += '<li>' + values['tag-' + i] + '</li>';
+			}
+			html += '</ul>';
+			html += '</p>';
+		}
+		
+		// Links
+		var linkContentsSize = values['link-content-size'];
+		if (linkContentsSize != 0)
+		{
+			html += '<p><b>' + "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LINK_CONTENTS' i18n:catalogue='plugin.web'/>" + '</b><br/>';
+			html += '<ul>';
+			for (var i=0; i < linkContentsSize; i++)
+			{
+				html += '<li>';
+				html += '<a href="" onclick="org.ametys.web.page.PagePropertiesTool._openPage(\'';
+				html += values['link-content-' + i + '-page-0-id'];
+				html += '\',\'';
+				html += values['link-content-' + i + '-page-0-site'];
+				html += '\',\'';
+				html += values['link-content-' + i + '-page-0-lang'];
+				html += '\',\'';
+				html += values['link-content-' + i + '-page-0-path'];
+				html += '\'); return false;">';
+				html += values['link-content-' + i + '-title'];
+				html += '</a>';
+				html += '</li>';
+			}
+			html += '</ul>';
+			html += '</p>';
+		}
+		
+		var linkPagesSize = values['link-page-size'];
+		if (linkPagesSize != 0)
+		{
+			html += '<p><b>' + "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LINK_PAGES' i18n:catalogue='plugin.web'/>" + '</b><br/>';
+			html += '<ul>';
+			for (var i=0; i < linkPagesSize; i++)
+			{
+				html += '<li>';
+				html += '<a href="" onclick="org.ametys.web.page.PagePropertiesTool._openPage(\'';
+				html += values['link-page-' + i + '-id'];
+				html += '\',\'';
+				html += values['link-page-' + i + '-site'];
+				html += '\',\'';
+				html += values['link-page-' + i + '-lang'];
+				html += '\',\'';
+				html += values['link-page-' + i + '-path'];
+				html += '\'); return false;">';
+				html += values['link-page-' + i + '-title'];
+				html += '</a>';
+				html += '</li>';
+			}
+			html += '</ul>';
+			html += '</p>';
+		}
+		
+		// Publication
+		if (values['pub-start-date'] != null || values['pub-end-date'])
+		{
+			html += '<p><b>' + "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION' i18n:catalogue='plugin.web'/>" + '</b><br/>';
+			if (values['pub-start-date'])
+			{
+				html += "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION_STARTDATE' i18n:catalogue='plugin.web'/>" + " ";
+				html += Ext.Date.parse(values['pub-start-date'], Ext.Date.patterns.ISO8601DateTime).format('d M Y'); 
+			}
+			if (values['pub-end-date'])
+			{
+				if (values['pub-start-date'])
+				{
+					html += '<br/>';
+				}
+				html += "<i18n:text i18n:key='PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION_ENDDATE' i18n:catalogue='plugin.web'/>" + " ";
+				html += Ext.Date.parse(values['pub-end-date'], Ext.Date.patterns.ISO8601DateTime).format('d M Y'); 
+			}
+		}
+		return html;
+	},
+	
+	/**
+	 * @private
+	 * Open the page tool
+	 * @param {String} id the page's id
+	 * @param {String} site the page's site
+	 * @param {String} lang the page's lang
+	 * @param {String} path the page's path
+	 */
+	_openPage: function (id, site, lang, path)
+	{
+		Ametys.tool.ToolsManager.openTool('uitool-page', {'id' : id, 'lang': lang, 'sitename': site, 'path': path});
+	},
+	
+	/**
+	 * @private
+	 * Listener on {@link Ametys.message.Message#DELETED} message. If the current page is concerned, the tool will be set in no selection mode.
+	 * @param {Ametys.message.Message}  message The deleted message.
+	 */
+	_onDeleted: function (message)
+	{
+		if (this.getTargetsInCurrentSelectionTargets(message).length > 0)
+		{
+			this.setNoSelectionMatchState();
+		}
+	},
+	
+	/**
+	 * @private
+	 * Listener on {@link Ametys.message.Message#METADATE_CHANGED} message. If the current page is concerned, the tool will be set out of date.
+	 * @param {Ametys.message.Message}  message The metadata changed message.
+	 */
+	_onMetadataChanged: function(message)
+	{
+		if (this.getTargetsInCurrentSelectionTargets(message).length > 0)
+		{
+			this.showOutOfDate();
+		}
+	}
+});
Index: main/plugin-web/resources/js/org/ametys/web/page/PagePropertiesTool.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/page/PagePropertiesTool.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/page/PagePropertiesTool.js	(nonexistent)
@@ -1,371 +0,0 @@
-/*
- *  Copyright 2010 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.PagePropertiesTool = function(id, pluginName) 
-{
-	org.ametys.web.page.PagePropertiesTool.superclass.constructor.call(this, id, pluginName);
-};
-
-Ext.extend(org.ametys.web.page.PagePropertiesTool, org.ametys.uitool.tool.Tool, {});
-
-org.ametys.web.page.PagePropertiesTool.prototype._refreshing = false;
-
-org.ametys.web.page.PagePropertiesTool.prototype.createPanel = function ()
-{
-	this._mainPanel = new Ext.Panel ({
-		tool : this,
-		autoScroll: true, 
-		listeners: {
-			'focus' : function() {},
-			'blur' : function() {},
-			'render' : function() { this.tool.refresh(); },
-			'deactivate' : function() {}
-		},
-		border: false,
-		html : '',
-		id : 'details-view',
-		cls : 'details-view'
-	});
-	return this._mainPanel;
-}
-
-
-org.ametys.web.page.PagePropertiesTool.prototype.setParams = function (params)
-{
-	this._params = params;
-}
-
-org.ametys.web.page.PagePropertiesTool.prototype.onMessage = function (messages)
-{
-	for (var i=messages.length - 1; i >= 0; i--)
-	{
-		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)
-			{
-				// Ignore
-				return;
-			}
-			
-			if (target.getParameters().id == this._currentPage)
-			{
-				this.outOfDate();
-				break;
-			}
-		}
-		else if (messages[i].getType().getName() == org.ametys.ribbon.RibbonManager.EVENTTYPE_SELECTIONCHANGED)
-		{
-			var targets = messages[i].getTargets();
-			var target = org.ametys.messagebus.message.MessageTargetHelper.findFirst(targets, function(target) { return target.getType() == "page";});
-			
-			if (target != null && this._currentPage == target.getParameters().id)
-			{
-				// target is the same as before
-				if (!this.metAnError)
-				{
-					this.upToDate();
-				}
-			}
-			else if (target != null && this._currentPage != target.getParameters().id)
-			{
-				// target has changed
-				this.outOfDate(true);
-			}
-			else if (target == null)
-			{
-				// No more target
-				this.upToDate();
-				this._setInNoSelectionState();
-			}
-			
-			return;
-		}
-	}
-}
-
-org.ametys.web.page.PagePropertiesTool.prototype._setInNoSelectionState = function ()
-{
-	this._currentPage = null;
-	this._mainPanel.body.dom.innerHTML = "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_SELECT_PAGE"/>";
-	this.metAnError = false;
-}
-
-/**
- * Refresh the tool when it is out of date.
- * @param {boolean} manual The refresh is manual. Defaults to false.
- */
-org.ametys.web.page.PagePropertiesTool.prototype.refresh = function (manual)
-{
-	if (manual)
-	{
-		this.metAnError = false;
-	}
-	
-	if (this._refreshing)
-	{
-		// The view is refreshing, but let it
-	}
-
-	this.refreshing();
-	
-	var targets = org.ametys.ribbon.RibbonManager.getInstance().getCurrentSelectionTargets();
-	var target = org.ametys.messagebus.message.MessageTargetHelper.findFirst(targets, function(target) { return target.getType() == "page";});
-
-	if (target != null)
-	{
-		if (this._currentPage == target.getParameters().id && this.metAnError)
-		{
-			// Do not refresh the same parameters with an error
-			this.upToDate();
-			return;
-		}
-		
-		// Change the current content
-		this._currentPage = target.getParameters().id;
-		this._refreshing = true;
-		
-		this._sendMessage (target.getParameters().id);
-	}
-	else
-	{
-		this._setInNoSelectionState();
-		this.upToDate();
-	}
-}
-
-org.ametys.web.page.PagePropertiesTool.prototype._sendMessage = function (pageId)
-{
-	var serverMessage = new org.ametys.servercomm.ServerMessage('web', 'page/properties', {'pageId': pageId}, org.ametys.servercomm.ServerComm.PRIORITY_MAJOR, this._refreshCallback, this, [this._currentPage]);
-	org.ametys.servercomm.ServerComm.getInstance().send(serverMessage);
-}
-	
-org.ametys.web.page.PagePropertiesTool.prototype._refreshCallback = function(response, args)
-{
-	var pageId = args[0];
-	
-	if (pageId != this._currentPage)
-	{
-		// too late => discard (another content has been selected)
-		return;
-	}
-	
-	this._refreshing = false;
-
-	if (org.ametys.servercomm.ServerComm.handleBadResponse("<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_ERROR"/> '" + pageId + "'", response, "org.ametys.web.page.PagePropertiesTool"))
-	{
-		this.metAnError = true;
-		this.outOfDate();
-		return;
-	}
-	
-	this.metAnError = false;
-	
-	// Update the view
-	var pageNode = response.selectSingleNode("page");
-	this._updateView (pageNode);
-	
-	this.upToDate();
-}
-
-
-org.ametys.web.page.PagePropertiesTool.prototype._updateView = function (pageNode)
-{
-	var values = {};
-	
-	values.lang = pageNode.getAttribute("lang");
-	values.siteName = pageNode.getAttribute("site");
-	values.title = pageNode.selectSingleNode("title")[org.ametys.servercomm.ServerComm.xmlTextContent];
-	values.longTitle = pageNode.selectSingleNode("longTitle")[org.ametys.servercomm.ServerComm.xmlTextContent];
-	values.type = pageNode.selectSingleNode("type")[org.ametys.servercomm.ServerComm.xmlTextContent];
-	values.path = pageNode.getAttribute("lang") + "/" + pageNode.getAttribute("path") + ".html";
-	
-	var tags = pageNode.selectNodes("tags/tag");
-	values['tags-size'] = tags.length;
-	for (var i=0; i < tags.length; i++)
-	{
-		values['tag-' + i] = tags[i][org.ametys.servercomm.ServerComm.xmlTextContent];
-	}
-	
-	var contents = pageNode.selectNodes("links/content");
-	values['link-content-size'] = contents.length;
-	for (var i=0; i < contents.length; i++)
-	{
-		var content = {};
-		values['link-content-' + i + '-id'] = contents[i].getAttribute("id");
-		values['link-content-' + i + '-name'] = contents[i].getAttribute("name");
-		values['link-content-' + i + '-title'] = contents[i].getAttribute("title");
-		
-		var pages = contents[i].selectNodes ("page");
-		for (var j=0; j < pages.length; j++)
-		{
-			values['link-content-' + i + '-page-' + j + '-id'] = pages[j].getAttribute("id");
-			values['link-content-' + i + '-page-' + j + '-name'] = pages[j].getAttribute("name");
-			values['link-content-' + i + '-page-' + j + '-title'] = pages[j].getAttribute("title");
-			values['link-content-' + i + '-page-' + j + '-site'] = pages[j].getAttribute("site");
-			values['link-content-' + i + '-page-' + j + '-path'] = pages[j].getAttribute("path");
-		}
-	}
-	
-	var pages = pageNode.selectNodes("links/page");
-	values['link-page-size'] = pages.length;
-	for (var i=0; i < pages.length; i++)
-	{
-		values['link-page-' + i + '-id'] = pages[i].getAttribute("id");
-		values['link-page-' + i + '-name'] = pages[i].getAttribute("name");
-		values['link-page-' + i + '-title'] = pages[i].getAttribute("title");
-		values['link-page-' + i + '-site'] = pages[i].getAttribute("site");
-		values['link-page-' + i + '-path'] = pages[i].getAttribute("path");
-	}
-	
-	var pub = pageNode.selectSingleNode("publication");
-	if (pub.selectSingleNode("start-date") != null)
-	{
-		values['pub-start-date'] = pub.selectSingleNode("start-date")[org.ametys.servercomm.ServerComm.xmlTextContent];
-	}
-	if (pub.selectSingleNode("end-date") != null)
-	{
-		values['pub-end-date'] = pub.selectSingleNode("end-date")[org.ametys.servercomm.ServerComm.xmlTextContent];
-	}
-	
-	var html = this._getHTML (values);
-	this._mainPanel.body.update(html);
-}
-
-org.ametys.web.page.PagePropertiesTool.prototype._getHTML = function (values)
-{
-	var html = "";
-	
-	// Page title
-	html += '<p><b>' + "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_TITLE" i18n:catalogue="plugin.web"/>" + '</b><br/>';
-	html += values.title;
-	html += '</p>';
-	
-	// Page long title
-	html += '<p><b>' + "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LONGTITLE" i18n:catalogue="plugin.web"/>" + '</b><br/>';
-	html += values.longTitle;
-	html += '</p>';
-	
-	// Language
-	html += '<p><b>' + "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LANG" i18n:catalogue="plugin.web"/>" + '</b> ';
-	html += values.lang;
-	html += '</p>';
-	
-	// Site
-	html += '<p><b>' + "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_SITE" i18n:catalogue="plugin.web"/>" + '</b> ';
-	html += values.siteName;
-	html += '</p>';
-	
-	// Tags
-	var size = values['tags-size'];
-	if (values['tags-size'] != 0)
-	{
-		html += '<p><b>' + "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_TAGS" i18n:catalogue="plugin.web"/>" + '</b><br/>';
-		html += '<ul>';
-		for (var i=0; i < size; i++)
-		{
-			html += '<li>' + values['tag-' + i] + '</li>';
-		}
-		html += '</ul>';
-		html += '</p>';
-	}
-	
-	// Links
-	var linkContentsSize = values['link-content-size'];
-	if (linkContentsSize != 0)
-	{
-		html += '<p><b>' + "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LINK_CONTENTS" i18n:catalogue="plugin.web"/>" + '</b><br/>';
-		html += '<ul>';
-		for (var i=0; i < linkContentsSize; i++)
-		{
-			html += '<li>';
-			html += '<a href="" onclick="org.ametys.web.page.PagePropertiesTool._openPage(\'';
-			html += values['link-content-' + i + '-page-0-id'];
-			html += '\',\'';
-			html += values['link-content-' + i + '-page-0-site'];
-			html += '\',\'';
-			html += values['link-content-' + i + '-page-0-lang'];
-			html += '\',\'';
-			html += values['link-content-' + i + '-page-0-path'];
-			html += '\'); return false;">';
-			html += values['link-content-' + i + '-title'];
-			html += '</a>';
-			html += '</li>';
-		}
-		html += '</ul>';
-		html += '</p>';
-	}
-	
-	var linkPagesSize = values['link-page-size'];
-	if (linkPagesSize != 0)
-	{
-		html += '<p><b>' + "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_LINK_PAGES" i18n:catalogue="plugin.web"/>" + '</b><br/>';
-		html += '<ul>';
-		for (var i=0; i < linkPagesSize; i++)
-		{
-			html += '<li>';
-			html += '<a href="" onclick="org.ametys.web.page.PagePropertiesTool._openPage(\'';
-			html += values['link-page-' + i + '-id'];
-			html += '\',\'';
-			html += values['link-page-' + i + '-site'];
-			html += '\',\'';
-			html += values['link-page-' + i + '-lang'];
-			html += '\',\'';
-			html += values['link-page-' + i + '-path'];
-			html += '\'); return false;">';
-			html += values['link-page-' + i + '-title'];
-			html += '</a>';
-			html += '</li>';
-		}
-		html += '</ul>';
-		html += '</p>';
-	}
-	
-	// Publication
-	if (values['pub-start-date'] != null || values['pub-end-date'])
-	{
-		html += '<p><b>' + "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION" i18n:catalogue="plugin.web"/>" + '</b><br/>';
-		if (values['pub-start-date'])
-		{
-			html += "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION_STARTDATE" i18n:catalogue="plugin.web"/>" + " ";
-			html += Date.parseDate(values['pub-start-date'], Date.patterns.ISO8601Long).format('d M Y');
-		}
-		if (values['pub-end-date'])
-		{
-			if (values['pub-start-date'])
-			{
-				html += '<br/>';
-			}
-			html += "<i18n:text i18n:key="PLUGINS_WEB_TOOL_PAGE_PROPERTIES_PUBLICATION_ENDDATE" i18n:catalogue="plugin.web"/>" + " ";
-			html += Date.parseDate(values['pub-end-date'], Date.patterns.ISO8601Long).format('d M Y');
-		}
-	}
-	return html;
-}
-
-org.ametys.web.page.PagePropertiesTool._openPage = function (id, site, lang, path)
-{
-	org.ametys.uitool.ToolsManager.getInstance().openTool ("uitool-page", {
-		'id' : id,
-		'lang': lang,
-		'sitename': site,
-		'path': path
-	});
-}
Index: main/plugin-web/resources/js/org/ametys/web/page/PagePropertiesToolFactory.js
===================================================================
--- main/plugin-web/resources/js/org/ametys/web/page/PagePropertiesToolFactory.js	(revision 32509)
+++ main/plugin-web/resources/js/org/ametys/web/page/PagePropertiesToolFactory.js	(nonexistent)
@@ -1,30 +0,0 @@
-/*
- *  Copyright 2010 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.PagePropertiesToolFactory = function(id, config, pluginName) 
-{
-	org.ametys.web.page.PagePropertiesToolFactory.superclass.constructor.call(this, id, config, pluginName);
-};
-
-Ext.extend(org.ametys.web.page.PagePropertiesToolFactory, org.ametys.uitool.tool.impl.UniqueInstanceToolFactory,
-{
-	createTool : function (id)
-	{
-		return new org.ametys.web.page.PagePropertiesTool (id, this.getPluginName());
-	}
-});
\ No newline at end of file
Index: main/plugin-web/sitemap-back.xmap
===================================================================
--- main/plugin-web/sitemap-back.xmap	(revision 32530)
+++ main/plugin-web/sitemap-back.xmap	(working copy)
@@ -34,7 +34,6 @@
             <map:generator name="cache-stats-servers" src="org.ametys.web.cache.monitoring.ui.ServersCacheStatsGenerator" logger="org.ametys.web.cachemonitoring.generators.ServersCacheStatsGenerator" label="xml"/>
             <map:generator name="site-parameters" src="org.ametys.web.site.SiteParametersGenerator" logger="org.ametys.web.site.SiteParametersGenerator" label="xml"/>
 			<map:generator name="page-info" src="org.ametys.web.repository.page.generators.PageInformationGenerator" label="xml" pool-grow="2" pool-max="16" pool-min="0"/>
-			<map:generator name="page-properties" src="org.ametys.web.repository.page.PagePropertiesGenerator"/>
 			<map:generator name="site-info" src="org.ametys.web.repository.site.SiteInformationGenerator" label="xml" pool-grow="2" pool-max="16" pool-min="0"/>
 			<map:generator name="sitemap-info" src="org.ametys.web.repository.sitemap.generators.SitemapInformationGenerator" label="xml" pool-grow="2" pool-max="16" pool-min="0"/>
 			<map:generator name="page-contents" src="org.ametys.web.repository.page.generators.PageContentsGenerator" label="xml" pool-grow="2" pool-max="16" pool-min="0"/>
@@ -117,7 +116,6 @@
             
             <map:action name="administrator-is-system-user" src="org.ametys.runtime.plugins.admin.IsAdminAction" logger="org.ametys.runtime.plugins.web.administrator.sitemap.action.isAdmin"/>
 
-		  	<map:action name="disallow-robots" src="org.ametys.web.repository.page.actions.DisallowRobotsAction"/>
 		  	<map:action name="tag" src="org.ametys.web.repository.tag.actions.TagAction"/>
 		  	<map:action name="edit-metadata" src="org.ametys.web.repository.page.actions.EditMetadataAction"/>
 
@@ -435,13 +433,6 @@
 				<map:serialize type="xml"/>
 			</map:match>
 			
-			<map:match pattern="repository/disallow-robots">
-				<map:act type="disallow-robots">
-					<map:generate type="action-result"/>
-					<map:serialize type="xml"/>
-				</map:act>
-			</map:match>
-			
 			<map:match pattern="repository/tag">
 				<map:act type="tag">
 					<map:generate type="action-result"/>
@@ -476,14 +467,6 @@
 				<map:serialize type="xml"/>
 			</map:match>
 			
-			<map:match pattern="page/properties">
-				<map:generate type="page-properties"/>
-				<map:transform type="i18n">
-					<map:parameter name="locale" value="{locale:locale}"/>
-				</map:transform>
-				<map:serialize type="xml"/>
-			</map:match>
-			
 			<map:match pattern="pages/filter-regexp">
 				<map:generate type="filter-pages-by-regexp"/>
 				<map:serialize type="xml"/>
Index: main/plugin-web/src/org/ametys/web/repository/page/SitemapDAO.java
===================================================================
--- main/plugin-web/src/org/ametys/web/repository/page/SitemapDAO.java	(revision 32509)
+++ main/plugin-web/src/org/ametys/web/repository/page/SitemapDAO.java	(working copy)
@@ -16,6 +16,7 @@
 package org.ametys.web.repository.page;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -40,7 +41,9 @@
 import org.ametys.core.right.RightsManager.RightResult;
 import org.ametys.core.ui.Callable;
 import org.ametys.core.user.CurrentUserProvider;
+import org.ametys.core.util.I18nUtils;
 import org.ametys.plugins.repository.AmetysObject;
+import org.ametys.plugins.repository.AmetysObjectIterable;
 import org.ametys.plugins.repository.AmetysObjectResolver;
 import org.ametys.plugins.repository.AmetysRepositoryException;
 import org.ametys.plugins.repository.CopiableAmetysObject;
@@ -50,18 +53,23 @@
 import org.ametys.plugins.repository.jcr.JCRAmetysObject;
 import org.ametys.plugins.repository.jcr.SimpleAmetysObject;
 import org.ametys.plugins.repository.version.VersionableAmetysObject;
+import org.ametys.runtime.parameter.ParameterHelper;
 import org.ametys.web.ObservationConstants;
 import org.ametys.web.alias.Alias.TargetType;
 import org.ametys.web.alias.AliasHelper;
 import org.ametys.web.alias.DefaultAlias;
+import org.ametys.web.repository.content.WebContent;
 import org.ametys.web.repository.page.Page.LinkType;
 import org.ametys.web.repository.page.Page.PageType;
 import org.ametys.web.repository.page.ZoneItem.ZoneType;
+import org.ametys.web.repository.page.jcr.DefaultPage;
 import org.ametys.web.repository.site.Site;
 import org.ametys.web.repository.site.SiteManager;
 import org.ametys.web.repository.sitemap.Sitemap;
 import org.ametys.web.sitemap.SitemapDecorator;
 import org.ametys.web.sitemap.SitemapDecoratorsHandler;
+import org.ametys.web.tags.Tag;
+import org.ametys.web.tags.TagProviderExtensionPoint;
 
 /**
  * DAO for manipulating pages
@@ -76,6 +84,8 @@
     private CopySiteComponent _copySiteComponent;
     private SiteManager _siteManager;
     private SitemapDecoratorsHandler _sitemapHandler;
+    private TagProviderExtensionPoint _tagProvider;
+    private I18nUtils _i18nUtils;
     
     @Override
     public void service(ServiceManager smanager) throws ServiceException
@@ -87,6 +97,8 @@
         _copySiteComponent = (CopySiteComponent) smanager.lookup(CopySiteComponent.ROLE);
         _siteManager = (SiteManager) smanager.lookup(SiteManager.ROLE);
         _sitemapHandler = (SitemapDecoratorsHandler) smanager.lookup(SitemapDecoratorsHandler.ROLE);
+        _tagProvider = (TagProviderExtensionPoint) smanager.lookup(TagProviderExtensionPoint.ROLE);
+        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
     }
     
     /**
@@ -727,6 +739,172 @@
         }
     }
     
+    /**
+     * Gather page information and return it as a map
+     * @param pageId the id of the page
+     * @return a map
+     */
+    @Callable
+    public Map<String, Object> getPageInformation(String pageId)
+    {
+        Map<String, Object> result = new HashMap<> ();
+        Map<String, Object> pageMap = new HashMap<> ();
+        List<String> tagsList = new ArrayList<> ();
+        List<Map<String, Object>> contentsList = new ArrayList<> ();
+        List<Map<String, String>> pageLinksList = new ArrayList<> ();
+        Map<String, Object> linksMap = new HashMap<> ();
+        
+        
+        Page page = _resolver.resolveById(pageId);
+        result.put("id", page.getId());
+        result.put("name", page.getName());
+        result.put("lang", page.getSitemapName());
+        result.put("site", page.getSiteName());
+        result.put("path", page.getPathInSitemap());
+        
+        
+        pageMap.put("title", page.getTitle());
+        pageMap.put("longTitle", page.getLongTitle());
+        
+        PageType type = page.getType();
+        pageMap.put("type", type.toString());
+
+        if (PageType.CONTAINER.equals(type))
+        {
+            pageMap.put("template", page.getTemplate());
+        }
+        else if (PageType.LINK.equals(type))
+        {
+            pageMap.put("urlType", page.getURLType().toString());
+            pageMap.put("url", page.getURL());
+        }
+        
+        // Tags
+        Set<String> tags = page.getTags();
+        for (String tagId : tags)
+        {
+            Tag tag = _tagProvider.getTag(page.getSiteName(), tagId);
+            tagsList.add(_i18nUtils.translate(tag.getTitle()));
+        }
+
+        pageMap.put("tags", tagsList);
+        
+        // Links (contents)
+        AmetysObjectIterable<Content> contents = _getContents (pageId);
+        for (Content content : contents)
+        {
+            contentsList.add(_content2Json (content));
+        }
+        
+        linksMap.put("contents", contentsList);
+        
+        // Links (pages)
+        AmetysObjectIterable<Page> pages = _getLinkPages (pageId);
+        for (Page linkPage : pages)
+        {
+            pageLinksList.add(_page2Json(linkPage));
+        }
+        
+        linksMap.put("pages", pageLinksList);
+        
+        pageMap.put("links", linksMap);
+        
+        // Publication dates
+        pageMap.put("publication", _publication2Json(page));
+        
+        result.put("page", pageMap);
+
+        return result;
+    }
+    
+    /**
+     * Get the JSON representation of a publication
+     * @param publication the publication
+     * @return the publication in JSON
+     */
+    private Map<String, String> _publication2Json (Page page)
+    {
+        Map<String, String> publicationMap = new HashMap<> ();
+        Date startDate = page.getMetadataHolder().getDate(DefaultPage.METADATA_PUBLICATION_START_DATE, null);
+        if (startDate != null)
+        {
+            publicationMap.put("start-date", ParameterHelper.valueToString(startDate));
+        }
+        
+        Date endDate = page.getMetadataHolder().getDate(DefaultPage.METADATA_PUBLICATION_END_DATE, null);
+        if (endDate != null)
+        {
+            publicationMap.put("end-date", ParameterHelper.valueToString(endDate));
+        }
+
+        return publicationMap;
+    }
+    
+    /**
+     * Get the JSON representation of a content
+     * @param content the content
+     * @return the content in JSON
+     */
+    private Map<String, Object> _content2Json (Content content)
+    {
+        Map<String, Object> contentMap = new HashMap<> ();
+        
+        contentMap.put("id", content.getId());
+        contentMap.put("name", content.getName());
+        contentMap.put("title", content.getTitle());
+        
+        if (content instanceof WebContent)
+        {
+            List<Map<String, String>> pageList = new ArrayList<> ();
+            Collection<Page> pages = ((WebContent) content).getReferencingPages();
+            for (Page refPage : pages)
+            {
+                pageList.add(_page2Json(refPage));
+            }
+            contentMap.put("pages", pageList);
+        }
+        
+        return contentMap;
+    }
+    
+    /**
+     * Get the JSON representation of a page
+     * @param page the page
+     * @return the page in JSON
+     */
+    private Map<String, String> _page2Json (Page page)
+    {
+        Map<String, String> pageMap = new HashMap<> ();
+        pageMap.put("id", page.getId());
+        pageMap.put("name", page.getName());
+        pageMap.put("site", page.getSiteName());
+        pageMap.put("title", page.getTitle());
+        pageMap.put("path", page.getPathInSitemap());
+        
+        return pageMap;
+    }
+    
+    /**
+     * Get the contents linking the page with the given id
+     * @param pageId the id of the page
+     * @return the contents 
+     */
+    private AmetysObjectIterable<Content> _getContents (String pageId)
+    {
+        String xpathQuery = "//element(*, ametys:content)[ametys-internal:consistency/@ametys-internal:link = 'page:" + pageId + "']";
+        return _resolver.query(xpathQuery);
+    }
+    
+    /**
+     * Get the pages linking the page with the given id
+     * @param pageId the id of the page
+     * @return the link pages 
+     */
+    private AmetysObjectIterable<Page> _getLinkPages (String pageId)
+    {
+        String xpathQuery = "//element(*, ametys:page)[@ametys-internal:type = 'LINK' and @ametys-internal:url= '" + pageId + "']";
+        return _resolver.query(xpathQuery);
+    }
     
     /**
      * Get the user rights on page
