From 7f7026a0390bd527765639f3f6bd5bbcda169bf7 Mon Sep 17 00:00:00 2001
From: Romain Courteaud <romain@nexedi.com>
Date: Tue, 2 Nov 2021 10:58:13 +0000
Subject: [PATCH] erp5_web_js_style: generate feed from the web section's
 document list

Generate a hfeed in the HTML rendering.
https://indieweb.org/feed

Provide a RSS feed automatically.

Only generate the feed when rendering the web section in view mode.

Extract all feed informations in Javascript to allow styling it as a blog.

Add bt5 dependency to erp5_dms to retrieve the author title.
---
 .../WebSection_generateNavigationHTML.py      |  22 +++-
 .../WebSection_generateNavigationHTML.xml     |   2 +-
 .../erp5_web_js_style_ui/feed.rss.xml         |  62 +++++++++
 .../erp5_web_js_style_ui/feed.rss.zpt         |  27 ++++
 .../erp5_web_js_style_ui/jsstyle.js.js        | 115 +++++++++++++++--
 .../erp5_web_js_style_ui/view_main.zpt        |   6 +-
 bt5/erp5_web_js_style/bt/dependency_list      |   3 +-
 .../js_style_zuite/testJsStyleDemoStyle.zpt   |  23 +++-
 .../js_style_zuite/testJsStyleNoStyle.zpt     |  22 +++-
 .../testJsStyleNoStyleReference.xml           |  58 +++++++++
 .../testJsStyleNoStyleReference.zpt           |  83 ++++++++++++
 .../testJsStyleRelativeLinkHandling.zpt       |   5 +
 .../testJsStyleWebSectionForm.zpt             |  15 +++
 .../testJsStyleWebSectionNavigateBaseLink.zpt |  20 +++
 ...stJsStyleWebSectionNavigateByReference.zpt |  30 +++++
 ...stJsStyleWebSectionWithLanguageBaseUrl.zpt |  10 ++
 ...estJsStyleWebSectionWithWebSiteBaseUrl.zpt |  10 ++
 .../testJsStyleWebSiteBrowseSitemap.zpt       |  75 +++++++++++
 ...ebSiteBrowseSitemapWithLanguageBaseUrl.zpt |  74 +++++++++++
 .../testJsStyleWebSiteChangeLanguage.zpt      | 108 ++++++++++++++++
 ...bSiteChangeLanguageWithLanguageBaseUrl.zpt | 108 ++++++++++++++++
 ...ebSiteChangeLanguageWithWebSiteBaseUrl.zpt | 108 ++++++++++++++++
 .../testJsStyleWebSiteEmptySitemap.zpt        |   5 +
 .../js_style_zuite/testJsStyleWebSiteForm.zpt |  15 +++
 .../testJsStyleWebSiteNavigateBaseLink.zpt    | 108 ++++++++++++++++
 .../testJsStyleWebSiteNavigateByReference.zpt | 118 ++++++++++++++++++
 .../testJsStyleWebSiteNoStyleForm.zpt         |  14 +++
 .../ERP5Site_createWebJSStyleZuiteTestData.py |  30 ++++-
 .../jsstyle_demo.html.html                    |   1 +
 .../erp5_web_js_style_test/jsstyle_demo.js.js |  20 ++-
 30 files changed, 1270 insertions(+), 27 deletions(-)
 create mode 100644 bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/feed.rss.xml
 create mode 100644 bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/feed.rss.zpt
 create mode 100644 bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyleReference.xml
 create mode 100644 bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyleReference.zpt

diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSection_generateNavigationHTML.py b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSection_generateNavigationHTML.py
index c98c7c9b94..c407da28b2 100644
--- a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSection_generateNavigationHTML.py
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSection_generateNavigationHTML.py
@@ -26,9 +26,24 @@ def generateSectionListHTML(result_list, section_list):
 
 def generateDocumentListHTML(result_list, document_list):
   if (document_list):
-    result_list.append('<aside id="document_list"><ul>')
+    result_list.append('<aside id="document_list"><ul class="h-feed">')
     for section in document_list:
-      result_list.append('<li><a href="%s">%s</a></li>' % (__(section['url']), _(section['translated_title'])))
+      result_list.append("""
+<li class="h-entry">
+  <div class="e-content">
+    <h2 class="p-name">%s</h2>
+    %s
+  </div>
+  %s
+  <p><a class="u-url" rel="permalink" href="%s"><time class="dt-published" datetime="%s">%s</time></a></p>
+</li>""" % (
+  _(section['translated_title']),
+  ('<p class="p-summary">%s</p>' % _(section['description'])) if section.get('description') else '',
+  ('<p class="p-author h-card">%s</p>' % _(section['document'].Document_getContributorTitleList()[0])),
+  __(section['url']),
+  __(section['modification_date'].HTML4()),
+  _(section['modification_date'].rfc822())
+))
     result_list.append('</ul></aside>')
 
 
@@ -59,6 +74,7 @@ generateSectionListHTML(result_list, web_site.WebSection_getSiteMapTree(include_
 result_list.append('</nav>')
 
 # Documents
-generateDocumentListHTML(result_list, web_section.WebSection_getSiteMapTree(include_subsection=False, exclude_default_document=True, depth=1))
+if include_document:
+  generateDocumentListHTML(result_list, web_section.WebSection_getSiteMapTree(include_subsection=False, exclude_default_document=True, depth=1, property_mapping=('translated_title', 'description', 'modification_date')))
 
 return ''.join(result_list)
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSection_generateNavigationHTML.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSection_generateNavigationHTML.xml
index a1506d32c9..9821e77e1b 100644
--- a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSection_generateNavigationHTML.xml
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSection_generateNavigationHTML.xml
@@ -50,7 +50,7 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string></string> </value>
+            <value> <string>include_document=False</string> </value>
         </item>
         <item>
             <key> <string>id</string> </key>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/feed.rss.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/feed.rss.xml
new file mode 100644
index 0000000000..5cc809d633
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/feed.rss.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Cacheable__manager_id</string> </key>
+            <value> <string>caching_policy_manager</string> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>application/rss+xml</string> </value>
+        </item>
+        <item>
+            <key> <string>expand</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>feed.rss</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <unicode></unicode> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/feed.rss.zpt b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/feed.rss.zpt
new file mode 100644
index 0000000000..abd1bf34d0
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/feed.rss.zpt
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<tal:block xmlns:tal="http://xml.zope.org/namespaces/tal"
+           xmlns:metal="http://xml.zope.org/namespaces/metal"
+           xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+           tal:define="
+  web_section python: here.getWebSectionValue();
+  include_document python: web_section.isSiteMapDocumentParent() and (here.getRelativeUrl() == web_section.getRelativeUrl());">
+<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
+  <channel>
+    <title tal:content="python: web_section.getTranslatedTitle()"></title>
+    <link tal:content="python: web_section.absolute_url()"></link>
+    <lastBuildDate tal:content="python: DateTime().rfc822()"></lastBuildDate>
+    <description tal:condition="python: web_section.getDescription()" tal:content="python: web_section.getDescription()"></description>
+  </channel>
+  <tal:block tal:condition="include_document">
+    <tal:block tal:repeat="item python: web_section.WebSection_getSiteMapTree(include_subsection=False, exclude_default_document=True, depth=1, property_mapping=('translated_title', 'description', 'modification_date'))">
+      <item>
+        <author tal:content="python: item['document'].Document_getContributorTitleList()[0]"></author>
+        <guid tal:content="python: item['url']"></guid>
+        <pubDate tal:content="python: item['modification_date'].rfc822()"></pubDate>
+        <title tal:content="python: item['translated_title']"></title>
+        <description tal:condition="python: item.get('description', '')" tal:content="python: item['description']"></description>
+      </item>
+    </tal:block>
+  </tal:block>
+</rss>
+</tal:block>
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.js b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.js
index 4150a14ff3..1c3b7652d7 100644
--- a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.js
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.js
@@ -109,6 +109,84 @@
     return sitemap;
   }
 
+  function parseDate(date_string) {
+    var date = Date.parse(date_string);
+    if (isNaN(date)) {
+      // Hack to fix a specific non-ISO date format.
+      // "Mon, 07 Oct 2013 16:49:10 Z" = "D, d M Y H:i:s Z"
+      date_string = date_string.substring(0, date_string.length - 1);
+      date = Date.parse(date_string);
+    }
+    if (!isNaN(date)) {
+      return new Date(date).toUTCString();
+    }
+    return;
+  }
+
+  function parseMicroFormat(item) {
+    // http://indiewebcamp.com/page-name-discovery
+    // http://indiewebcamp.com/h-entry#How_to_consume_h-entry
+    // http://indiewebcamp.com/comment-presentation#How_to_display
+
+    var result = {},
+      element_name = item.querySelector(".p-name"),
+      element_content = item.querySelector(".e-content"),
+      element_summary = item.querySelector(".p-summary"),
+      element_permalink = item.querySelector("a[rel='permalink']"),
+      element_publication_date = item.querySelector("time.dt-published"),
+      element_author = item.querySelector(".p-author"),
+      element_link;
+
+    // publication date
+    if (element_publication_date !== null) {
+      result.date = element_publication_date.getAttribute('datetime');
+      if (result.date === null) {
+        // Get text content?
+        delete result.date;
+
+      } else {
+        result.date = parseDate(result.date);
+      }
+    }
+
+    // title
+    if (element_name !== null) {
+      result.text = element_name.textContent;
+      // Drop title from content
+      element_name.parentElement.removeChild(element_name);
+    }
+
+    // title
+    if (element_author !== null) {
+      result.author = element_author.textContent;
+      // Drop author from content
+      element_author.parentElement.removeChild(element_author);
+    }
+
+    // content
+    if (element_summary !== null) {
+      element_content = element_summary;
+    } else if (element_content === null) {
+      element_content = item;
+    }
+
+    if (element_content !== null) {
+      result.description = element_content.textContent;
+    }
+
+    // Search for the URL
+    if (element_permalink === null) {
+      element_link = item.querySelector(".u-url");
+    } else {
+      element_link = element_permalink;
+    }
+    if (element_link !== null) {
+      result.href = element_link.getAttribute('href');
+    }
+
+    return result;
+  }
+
   function parseDocumentListElement(document_list_element) {
     var document_list = [],
       li_list,
@@ -117,12 +195,9 @@
       return document_list;
     }
 
-    li_list = document_list_element.querySelectorAll('a');
+    li_list = document_list_element.querySelectorAll('.h-entry');
     for (i = 0; i < li_list.length; i += 1) {
-      document_list.push({
-        href: li_list[i].href,
-        text: li_list[i].textContent
-      });
+      document_list.push(parseMicroFormat(li_list[i]));
     }
     return document_list;
   }
@@ -145,13 +220,15 @@
     return result;
   }
 
-  function parsePageContent(body_element, language, base_uri) {
+  function parsePageContent(body_element, language, alternate_element,
+                            base_uri) {
     var i,
       element,
       element_list,
       j,
       url_attribute_list = ['src', 'href', 'srcset', 'action'],
-      url_attribute;
+      url_attribute,
+      feed_url = null;
 
     if (base_uri !== undefined) {
       // Rewrite relative url (copied from renderjs)
@@ -171,7 +248,15 @@
 
     }
 
+    if (alternate_element !== null) {
+      feed_url = alternate_element.getAttribute('href');
+      if (base_uri !== undefined) {
+        feed_url = new URL(feed_url, base_uri).href;
+      }
+    }
+
     return {
+      feed_url: feed_url,
       original_content: body_element.innerHTML,
       html_content: body_element.querySelector('main').innerHTML,
       language: language,
@@ -216,9 +301,12 @@
           // consider this must be reloaded
           throw new Error('Trigger an error to force reload');
         }
-        parsed_content = parsePageContent(dom_parser.body,
-                                          dom_parser.documentElement.lang,
-                                          dom_parser.baseURI);
+        parsed_content = parsePageContent(
+          dom_parser.body,
+          dom_parser.documentElement.lang,
+          dom_parser.querySelector('link[rel=alternate]'),
+          dom_parser.baseURI
+        );
         gadget.parsed_content = parsed_content;
         parsed_content.page_title = dom_parser.title;
         return result_dict.style_gadget.render(parsed_content.html_content,
@@ -315,8 +403,11 @@
         return rJS.declareCSS(style_css_url, document.head);
       }
 
-      parsed_content = parsePageContent(gadget.element,
-                                        document.documentElement.lang);
+      parsed_content = parsePageContent(
+        gadget.element,
+        document.documentElement.lang,
+        document.querySelector('link[rel=alternate]')
+      );
       gadget.parsed_content = parsed_content;
       parsed_content.page_title = document.title;
       gadget.style_gadget_url =
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.zpt b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.zpt
index f63bceda97..9a6f08ace9 100644
--- a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.zpt
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.zpt
@@ -22,7 +22,8 @@
       keyword_list python: web_section.getSubjectList();
       og_locale_dict python: web_site.WebSite_getOgLocaleDict();
       current_language python: web_site.getPortalObject().Localizer.get_selected_language();
-      global_definitions_macros here/global_definitions/macros;">
+      global_definitions_macros here/global_definitions/macros;
+      include_document python: web_section.isSiteMapDocumentParent() and ((here.getRelativeUrl() == web_section.getRelativeUrl()) or request.get('is_web_section_default_document', False));">
       <tal:block metal:use-macro="global_definitions_macros/header_definitions" />
 <html tal:attributes="lang current_language">
   <head>
@@ -32,6 +33,7 @@
   <tal:block tal:condition="favicon_url">
     <link rel="icon" tal:attributes="href favicon_url" />
   </tal:block>
+  <link tal:condition="include_document" rel="alternate" type="application/rss+xml" href="feed.rss" />
   <tal:block tal:condition="keyword_list">
     <meta name="keywords" tal:attributes="content python: ','.join(keyword_list)">
   </tal:block>
@@ -75,7 +77,7 @@
   </head>
   <body tal:attributes="data-nostyle-gadget-url no_style_gadget_url;
                         data-nostyle-css-url no_style_css_url">
-    <tal:block tal:content="structure python: web_section.WebSection_generateNavigationHTML()"></tal:block>
+    <tal:block tal:content="structure python: web_section.WebSection_generateNavigationHTML(include_document=include_document)"></tal:block>
     <p tal:content="request/portal_status_message | nothing" id="portal_status_message"/>
 
     <main><tal:block metal:define-slot="main"/></main>
diff --git a/bt5/erp5_web_js_style/bt/dependency_list b/bt5/erp5_web_js_style/bt/dependency_list
index 8853475efb..bceb433815 100644
--- a/bt5/erp5_web_js_style/bt/dependency_list
+++ b/bt5/erp5_web_js_style/bt/dependency_list
@@ -1 +1,2 @@
-erp5_web
\ No newline at end of file
+erp5_web
+erp5_dms
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.zpt
index 283f412e40..202a1f5cfc 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.zpt
@@ -69,7 +69,28 @@
 
 <tr>
   <td>assertElementPresent</td>
-  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage']</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
   <td></td>
 </tr>
 
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.zpt
index a1c63d6c09..27ddc405a9 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.zpt
@@ -37,6 +37,11 @@
   <td>//head/link[@rel='prerender']</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//head/link[@rel='alternate' and @type='application/rss+xml' and @href='feed.rss']</td>
+  <td></td>
+</tr>
 
 <tr>
   <td>waitForElementPresent</td>
@@ -63,7 +68,22 @@
 
 <tr>
   <td>assertElementPresent</td>
-  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage']</td>
+  <td>//aside[@id='document_list']//ul[@class="h-feed"]//li[@class="h-entry"]//div[@class="e-content"]//h2[@class="p-name" and text()='erp5_web_js_style_test_contentpage title']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//ul[@class="h-feed"]//li[@class="h-entry"]//div[@class="e-content"]//p[@class="p-summary" and text()='erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//ul[@class="h-feed"]//li[@class="h-entry"]//p[@class="p-author h-card" and text()='erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//ul[@class="h-feed"]//li[@class="h-entry"]//a[@class="u-url" and @rel='permalink' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]//time[@class="dt-published" and contains(@datetime, 'T')]</td>
   <td></td>
 </tr>
 
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyleReference.xml b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyleReference.xml
new file mode 100644
index 0000000000..fbfcd8ee47
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyleReference.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>expand</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>testJsStyleNoStyleReference</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <unicode></unicode> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyleReference.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyleReference.zpt
new file mode 100644
index 0000000000..e5d26d5556
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyleReference.zpt
@@ -0,0 +1,83 @@
+<html xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Test JS Style No Style</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Test JS Style No Style</td></tr>
+</thead><tbody>
+<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
+
+<tr>
+  <td>open</td>
+  <td>${base_url}/ERP5Site_createWebJSStyleZuiteTestData?configuration=nostyle</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertTextPresent</td>
+  <td>Web Site created.</td>
+  <td></td>
+</tr>
+
+<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
+
+
+<!-- Initialize -->
+<tr>
+  <td>open</td>
+  <td>${base_url}/web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementNotPresent</td>
+  <td>//head/link[@rel='prerender']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementNotPresent</td>
+  <td>//head/link[@rel='alternate' and @type='application/rss+xml' and @href='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>waitForElementPresent</td>
+  <td>//head/link[@rel='stylesheet' and @href='jsstyle.css']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//head/link[@rel='stylesheet' and @href='jsstyle.css']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//nav[@id='sitemap']/a[text()='No Style']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//nav[@id='language']//a[@hreflang='en']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementNotPresent</td>
+  <td>//aside[@id='document_list']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//div[@class='input']//p[text()='Subpage content']</td>
+  <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleRelativeLinkHandling.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleRelativeLinkHandling.zpt
index febd701283..3582179f13 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleRelativeLinkHandling.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleRelativeLinkHandling.zpt
@@ -55,6 +55,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionForm.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionForm.zpt
index f2b8f35bcb..4c63fbfef9 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionForm.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionForm.zpt
@@ -60,6 +60,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_form/jsstyle_demo.html')]</td>
@@ -131,6 +136,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_form/jsstyle_demo.html')]</td>
@@ -203,6 +213,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_form/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionNavigateBaseLink.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionNavigateBaseLink.zpt
index 8ad987d618..ee3ef146ad 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionNavigateBaseLink.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionNavigateBaseLink.zpt
@@ -55,6 +55,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -89,6 +94,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -132,6 +142,11 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -166,6 +181,11 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionNavigateByReference.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionNavigateByReference.zpt
index 13c681232d..2ed151b96d 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionNavigateByReference.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionNavigateByReference.zpt
@@ -55,6 +55,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -89,6 +94,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -123,6 +133,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -166,6 +181,11 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -200,6 +220,11 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -234,6 +259,11 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionWithLanguageBaseUrl.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionWithLanguageBaseUrl.zpt
index ea5549c7b4..e8c5f1d232 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionWithLanguageBaseUrl.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionWithLanguageBaseUrl.zpt
@@ -55,6 +55,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -100,6 +105,11 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionWithWebSiteBaseUrl.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionWithWebSiteBaseUrl.zpt
index b36db71c2b..c6ee752392 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionWithWebSiteBaseUrl.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSectionWithWebSiteBaseUrl.zpt
@@ -55,6 +55,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -100,6 +105,11 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteBrowseSitemap.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteBrowseSitemap.zpt
index c1aed0c5d9..fd8045b362 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteBrowseSitemap.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteBrowseSitemap.zpt
@@ -55,6 +55,34 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -98,6 +126,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -141,6 +174,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_1/erp5_web_js_style_test_section_11/jsstyle_demo.html')]</td>
@@ -184,6 +222,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_1/jsstyle_demo.html')]</td>
@@ -227,6 +270,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/erp5_web_js_style_test_section_2/jsstyle_demo.html')]</td>
@@ -270,6 +318,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteBrowseSitemapWithLanguageBaseUrl.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteBrowseSitemapWithLanguageBaseUrl.zpt
index aaf676c7b3..98aa31f137 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteBrowseSitemapWithLanguageBaseUrl.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteBrowseSitemapWithLanguageBaseUrl.zpt
@@ -55,6 +55,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -93,6 +120,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -131,6 +163,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -169,6 +206,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -207,6 +249,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -245,6 +292,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and contains(text(), 'web_site_module/erp5_web_js_style_test_site/feed.rss')]</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguage.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguage.zpt
index ae417f185c..5f5fc1fd36 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguage.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguage.zpt
@@ -50,6 +50,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()='Frontpage content']</td>
@@ -93,6 +120,33 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/fr/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()="Contenu de la page d'accueil"]</td>
@@ -136,6 +190,33 @@
   <td>//p[@id='current_language'][contains(text(), 'zh')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/zh/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()="涓婚〉鍐呭"]</td>
@@ -179,6 +260,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()='Frontpage content']</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguageWithLanguageBaseUrl.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguageWithLanguageBaseUrl.zpt
index 854ff1cf75..e9052c7593 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguageWithLanguageBaseUrl.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguageWithLanguageBaseUrl.zpt
@@ -50,6 +50,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()='Frontpage content']</td>
@@ -93,6 +120,33 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/fr/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()="Contenu de la page d'accueil"]</td>
@@ -136,6 +190,33 @@
   <td>//p[@id='current_language'][contains(text(), 'zh')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/zh/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()="涓婚〉鍐呭"]</td>
@@ -179,6 +260,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()='Frontpage content']</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguageWithWebSiteBaseUrl.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguageWithWebSiteBaseUrl.zpt
index 0fe9a46323..f89de987d9 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguageWithWebSiteBaseUrl.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteChangeLanguageWithWebSiteBaseUrl.zpt
@@ -50,6 +50,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()='Frontpage content']</td>
@@ -88,6 +115,33 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and contains(text(), 'web_site_module/erp5_web_js_style_test_site/fr/feed.rss')]</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/fr/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()="Contenu de la page d'accueil"]</td>
@@ -126,6 +180,33 @@
   <td>//p[@id='current_language'][contains(text(), 'zh')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and contains(text(), 'web_site_module/erp5_web_js_style_test_site/zh/feed.rss')]</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/zh/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()="涓婚〉鍐呭"]</td>
@@ -164,6 +245,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and contains(text(), 'web_site_module/erp5_web_js_style_test_site/feed.rss')]</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//main//p[text()='Frontpage content']</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteEmptySitemap.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteEmptySitemap.zpt
index 4d1d12043b..19d74a0c1e 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteEmptySitemap.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteEmptySitemap.zpt
@@ -55,6 +55,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteForm.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteForm.zpt
index 0786975927..1ee4009dd8 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteForm.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteForm.zpt
@@ -60,6 +60,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -131,6 +136,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -203,6 +213,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNavigateBaseLink.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNavigateBaseLink.zpt
index c9f0451599..0eab0db098 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNavigateBaseLink.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNavigateBaseLink.zpt
@@ -55,6 +55,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -89,6 +116,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and contains(text(), 'web_site_module/erp5_web_js_style_test_site/feed.rss')]</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -132,6 +186,33 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/fr/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/jsstyle_demo.html')]</td>
@@ -166,6 +247,33 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and contains(text(), 'web_site_module/erp5_web_js_style_test_site/fr/feed.rss')]</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/fr/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNavigateByReference.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNavigateByReference.zpt
index b876f6af53..63af84b4fc 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNavigateByReference.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNavigateByReference.zpt
@@ -55,6 +55,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -89,6 +116,11 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -123,6 +155,33 @@
   <td>//p[@id='current_language'][contains(text(), 'en')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and contains(text(), 'web_site_module/erp5_web_js_style_test_site/feed.rss')]</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/jsstyle_demo.html')]</td>
@@ -166,6 +225,33 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and text()='feed.rss']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/fr/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/jsstyle_demo.html')]</td>
@@ -200,6 +286,11 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and not(text())]</td>
+  <td></td>
+</tr>
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/jsstyle_demo.html')]</td>
@@ -234,6 +325,33 @@
   <td>//p[@id='current_language'][contains(text(), 'fr')]</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//p[@id='feed_url' and contains(text(), 'web_site_module/erp5_web_js_style_test_site/fr/feed.rss')]</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//a[text()='erp5_web_js_style_test_contentpage title' and contains(@href, 'web_site_module/erp5_web_js_style_test_site/fr/erp5_web_js_style_test_contentpage')]</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Author: erp5_web_js_style_test_contributor']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[text()='Description: erp5_web_js_style_test_contentpage description']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//aside[@id='document_list']//p[contains(text(), 'Date: ') and contains(text(), 'GMT')]</td>
+  <td></td>
+</tr>
+
 <tr>
   <td>assertElementPresent</td>
   <td>//p[@id='gadget_style_url'][contains(text(), 'erp5_web_js_style_test_site/fr/jsstyle_demo.html')]</td>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNoStyleForm.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNoStyleForm.zpt
index e212e7ac3a..d8ac10e7e9 100644
--- a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNoStyleForm.zpt
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleWebSiteNoStyleForm.zpt
@@ -36,12 +36,26 @@
   <td>//head/link[@rel='prerender']</td>
   <td></td>
 </tr>
+<tr>
+  <td>assertElementNotPresent</td>
+  <td>//head/link[@rel='alternate' and @type='application/rss+xml' and @href='feed.rss']</td>
+  <td></td>
+</tr>
 <tr>
   <td>waitForTextPresent</td>
   <td>No Style Form</td>
   <td></td>
 </tr>
 
+<tr>
+  <td colspan="3"><b>Check no document list is rendered</b></td>
+</tr>
+<tr>
+  <td>assertElementNotPresent</td>
+  <td>//aside[@id='document_list']</td>
+  <td></td>
+</tr>
+
 <tr>
   <td colspan="3"><b>Check the form content</b></td>
 </tr>
diff --git a/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/ERP5Site_createWebJSStyleZuiteTestData.py b/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/ERP5Site_createWebJSStyleZuiteTestData.py
index dd58fcf7d1..60967413fb 100644
--- a/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/ERP5Site_createWebJSStyleZuiteTestData.py
+++ b/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/ERP5Site_createWebJSStyleZuiteTestData.py
@@ -6,10 +6,24 @@ portal = context.getPortalObject()
 web_page_portal_type = "Web Page"
 web_site_portal_type = "Web Site"
 web_section_portal_type = "Web Section"
+person_portal_type = "Person"
 
 web_site_id = "erp5_web_js_style_test_site"
 web_section_id_prefix = "erp5_web_js_style_test_section_"
 
+contributor_title = "erp5_web_js_style_test_contributor"
+contributor_id = "erp5_web_js_style_test_contributor"
+
+### English web page
+module = portal.getDefaultModule(person_portal_type)
+if getattr(module, contributor_id, None) is not None:
+  module.manage_delObjects([contributor_id])
+contributor = module.newContent(
+  portal_type=person_portal_type,
+  id=contributor_id,
+  title=contributor_title
+)
+
 web_page_frontend_reference = "erp5_web_js_style_test_frontpage"
 web_page_frontend_en_id = "erp5_web_js_style_test_frontpage_en"
 web_page_frontend_fr_id = "erp5_web_js_style_test_frontpage_fr"
@@ -28,6 +42,7 @@ web_page = module.newContent(
   portal_type=web_page_portal_type,
   id=web_page_frontend_en_id,
   reference=web_page_frontend_reference,
+  contributor_value=contributor,
   language="en",
   version="001",
   text_content="""
@@ -45,6 +60,9 @@ web_page = module.newContent(
   portal_type=web_page_portal_type,
   id=web_page_content_en_id,
   reference=web_page_content_reference,
+  contributor_value=contributor,
+  title="%s title" % web_page_content_reference,
+  description="%s description" % web_page_content_reference,
   language="en",
   version="001",
   text_content="""
@@ -60,6 +78,7 @@ web_page = module.newContent(
   portal_type=web_page_portal_type,
   id=web_page_frontend_fr_id,
   reference=web_page_frontend_reference,
+  contributor_value=contributor,
   language="fr",
   version="001",
   text_content="""
@@ -77,6 +96,9 @@ web_page = module.newContent(
   portal_type=web_page_portal_type,
   id=web_page_content_fr_id,
   reference=web_page_content_reference,
+  contributor_value=contributor,
+  title="%s title" % web_page_content_reference,
+  description="%s description" % web_page_content_reference,
   language="fr",
   version="001",
   text_content="""
@@ -92,6 +114,7 @@ web_page = module.newContent(
   portal_type=web_page_portal_type,
   id=web_page_frontend_zh_id,
   reference=web_page_frontend_reference,
+  contributor_value=contributor,
   language="zh",
   version="001",
   text_content="""
@@ -109,6 +132,9 @@ web_page = module.newContent(
   portal_type=web_page_portal_type,
   id=web_page_content_zh_id,
   reference=web_page_content_reference,
+  contributor_value=contributor,
+  title="%s title" % web_page_content_reference,
+  description="%s description" % web_page_content_reference,
   language="zh",
   version="001",
   text_content="""
@@ -214,10 +240,10 @@ web_site = module.newContent(
   skin_selection_name="Jsstyle",
   layout_configuration_form_id="WebSection_viewJsstylePreference",
   site_map_document_parent=True,
-  criterion_property_list=('title',),
+  criterion_property_list=('reference',),
   **configuration_dict[configuration]
 )
-web_site.setCriterion('title', identity='erp5_web_js_style_test_contentpage')
+web_site.setCriterion('reference', identity='erp5_web_js_style_test_contentpage')
 
 web_section = web_site.newContent(
   portal_type=web_section_portal_type,
diff --git a/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/jsstyle_demo.html.html b/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/jsstyle_demo.html.html
index 1d66aa5bf1..a9b33b80c4 100644
--- a/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/jsstyle_demo.html.html
+++ b/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/jsstyle_demo.html.html
@@ -12,6 +12,7 @@
     <p id="render_count"></p>
     <p id="portal_status_message"></p>
     <p id="current_language"></p>
+    <p id="feed_url"></p>
     <nav id="language"></nav>
     <nav id="sitemap"></nav>
     <aside id="document_list"></aside>
diff --git a/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/jsstyle_demo.js.js b/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/jsstyle_demo.js.js
index 2a26305f0b..0b5fc279b7 100644
--- a/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/jsstyle_demo.js.js
+++ b/bt5/erp5_web_js_style_test/SkinTemplateItem/portal_skins/erp5_web_js_style_test/jsstyle_demo.js.js
@@ -35,6 +35,7 @@
     })
     .declareMethod("render", function (html_content, parsed_content) {
       var state = {
+        feed_url: parsed_content.feed_url || "",
         document_list: JSON.stringify(parsed_content.document_list || []),
         current_language: parsed_content.language || "",
         language_list: JSON.stringify(parsed_content.language_list || []),
@@ -93,6 +94,11 @@
           text: gadget.state.current_language
         });
       }
+      if (modification_dict.hasOwnProperty('feed_url')) {
+        domsugar(gadget.element.querySelector('p#feed_url'), {
+          text: gadget.state.feed_url
+        });
+      }
       if (modification_dict.hasOwnProperty('language_list')) {
         language_list = JSON.parse(gadget.state.language_list);
         child_list = [];
@@ -109,10 +115,16 @@
         document_list = JSON.parse(gadget.state.document_list);
         child_list = [];
         for (i = 0; i < document_list.length; i += 1) {
-          child_list.push(domsugar('li', [domsugar('a', {
-            text: document_list[i].text,
-            href: document_list[i].href
-          })]));
+          child_list.push(domsugar('li', [
+            domsugar('a', {
+              text: document_list[i].text,
+              href: document_list[i].href
+            }),
+            domsugar('p', {text: 'Author: ' + document_list[i].author}),
+            domsugar('p', {text: 'Description: ' +
+                                 document_list[i].description}),
+            domsugar('p', {text: 'Date: ' + document_list[i].date})
+          ]));
         }
         domsugar(gadget.element.querySelector('aside#document_list'),
                  [domsugar('ul', child_list)]);
-- 
GitLab