### Eclipse Workspace Patch 1.0 #P Ametys - Template CMSWEB Index: webapp/cms/skins/demo/resources/css/services/filtered-pages.css =================================================================== --- webapp/cms/skins/demo/resources/css/services/filtered-pages.css (revision 0) +++ webapp/cms/skins/demo/resources/css/services/filtered-pages.css (revision 0) @@ -0,0 +1,31 @@ +/* + * Copyright 2012 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. + */ + +/* +CSS FOR FILTERED-PAGES +*/ + +.filtered-pages > ul > li +{ + list-style-type: none; +} + +.filtered-pages > ul > li > ul > li +{ + background-repeat: no-repeat; + padding-left: 9px; + background-image: url('../../img/postbullets.png'); +} Index: webapp/cms/skins/demo/services/web/pages/services/filtered-pages/list_3.5.xsl =================================================================== --- webapp/cms/skins/demo/services/web/pages/services/filtered-pages/list_3.5.xsl (revision 0) +++ webapp/cms/skins/demo/services/web/pages/services/filtered-pages/list_3.5.xsl (revision 0) @@ -0,0 +1,87 @@ + + + + + + + + + fc_ + + + + + + + + + + + + + + + + + +
  • + page-list-item + + + + +
  • +
    + + + + + + + +
  • + + +
      + +
    +
    empty
    +
  • + + + + + + + + +
    +
    #P Ametys - 08 WEB Index: main/plugin-web/i18n/messages_en.xml =================================================================== --- main/plugin-web/i18n/messages_en.xml (revision 15614) +++ main/plugin-web/i18n/messages_en.xml (working copy) @@ -102,6 +102,8 @@ Right to create external page integration services (iframe and embedded) Filtered contents Right to create a filtered contents service + Filtered pages + Right to create a filtered pages service Insert content Right to create an insert content service Page attachments @@ -1133,6 +1135,35 @@ Preceding Next + + Pages digest + The service displays a selection of pages. + Title + This text will display before pages list.<br/>Leave emtpy if you don't want any title. + Search context + Select search context<br/><ul><li>- <b>current website</b> : only pages created in current website</li><li>- <b>other websites</b> : pages created in all website except current website</li><li>- <b>all websites</b> : all pages of every website</li><li>- <b>children pages</b> : only sub-pages of current page</li></ul> + In current website + In other websites + In all websites + In children pages + Research sites + Choose the research sites + Language + Select language of pages<br/><ul><li>- <b>current language</b> : only pages of page language</li><li>- <b>other languages</b> : pages in other languages than page language</li><li>- <b>all</b> : all pages, whatever language</li></ul> + Current language + All languages + Other languages + Tags + Service will only display pages tagged with specific tags.<br/>You can leave that field empty. + Max results + Maximum results to display.<br/>Leave empty to display all pages. + Results per page + When a number is set, results are paginated. E.G., 25 results with 10 results per page will lead to 3 result pages (1 to 10, 11 to 20 and 21 to 25).<br/>You can leave that field empty if you do not want pagination. + The number of results per page should be a positive number (or empty)/message> + Display + Select the display to use when displaying this service + Default + External page (iframe) The service is used to integrate an external HTML page inside an i-frame.\n HTML content will be integrated with no change on appearance. Index: main/plugin-web/i18n/messages_fr.xml =================================================================== --- main/plugin-web/i18n/messages_fr.xml (revision 15614) +++ main/plugin-web/i18n/messages_fr.xml (working copy) @@ -102,6 +102,8 @@ Droit de créer un service d'insertion d'une URL externe (iframe). Remontée de contenus Droit de créer un service de remontée de contenus + Remontée de pages + Droit de créer un service de remontée de pages Afficher un contenu Droit de créer un service d'affichage de contenu Pièces jointes @@ -1095,7 +1097,7 @@ Dans le site courant Dans les autres sites Dans tous les sites - Dans un site ou une liste de site + Dans un site ou une liste de sites Dans les pages filles Dans les pages filles directes Sites de recherche @@ -1130,6 +1132,35 @@ Précédent Suivant + + Remontée de pages + Ce service permet de remonter des pages suivant un filtre choisi. + Titre + Texte utilisé en titre pour l'affichage de la liste des pages.<br/>Laissez le champ vide si vous ne souhaitez pas de titre. + Contexte de recherche + Sélectionnez le contexte de la recherche<br/><ul><li>- <b>site courant</b> : uniquement les pages créées dans le site courant</li><li>- <b>autres sites</b> : pages créées dans les autres sites</li><li>- <b>tous les sites</b> : toutes les pages quelque soit leur site</li><li>- <b>pages filles</b> : uniquement les pages filles de la page contenant le service</li></ul> + Dans le site courant + Dans les autres sites + Dans tous les sites + Dans les pages filles + Sites de recherche + Choisissez les sites de recherche + Langues + Sélectionnez la langue des pages<br/><ul><li>- <b>langue courante</b> : uniquement les pages dans la langue du plan du site courant</li><li>- <b>autres langues</b> : pages dans une langue autre que celle du plan du site courant</li><li>- <b>toutes</b> : toutes les pages quelque soit leur langue</li></ul> + Dans langue courante + N'importe quelle langue + Dans les autres langues + Etiquettes + Le service remontera uniquement les pages étant étiquetées avec les étiquettes sélectionnées.<br/>Ce champ peut être vide. + Nombre maximum de résultats + Nombre maximum de résultats à afficher.<br/>Laissez vide pour renvoyer toutes les pages. + Nombre de résultats par page + Lorsqu'un chiffre est précisé, les résultats seront paginés. Par exemple, 25 résultats avec 10 résultats par page impliquera la création de 3 pages de résultats (1 à 10, 11 à 20 et 21 à 25).<br/>Laissez vide pour ne pas activer la pagination des résultats. + Le nombre de résultats par page doit être un nombre strictement positif (ou vide) + Affichage + Rendu à utiliser pour l'affichage du service + Par défaut + Page externe (iframe) Ce service permet d'insérer dans votre page une page HTML externe à l'intérieur d'une i-frame.\n Le contenu HTML de la page sera inséré sans application de style. Index: main/plugin-web/plugin.xml =================================================================== --- main/plugin-web/plugin.xml (revision 15614) +++ main/plugin-web/plugin.xml (working copy) @@ -796,6 +796,8 @@ + @@ -4038,6 +4040,131 @@ + + + + + + PLUGINS_WEB_RIGHTS_SERVICE_FILTEREDPAGES_DESCRIPTION + plugin.web:PLUGINS_WEB_RIGHTS_SERVICE_CREATE_CATEGORY + + + + + + service/filtered-pages.html + + true + Web_Right_Service_FilteredPages + + + PLUGINS_WEB_SERVICE_FILTERED_PAGES_DESCRIPTION + PLUGINS_WEB_SERVICE_CATEGORY_90_OTHERS + + img/service/tagged_content_16.png + img/service/tagged_content_32.png + img/service/tagged_content_48.png + + + + + + js/org/ametys/web/tag/TagServiceParametersAction.i18n.js + + + + PLUGINS_WEB_SERVICE_FILTERED_PAGES_TITLE_DESC + + + + PLUGINS_WEB_SERVICE_FILTERED_PAGES_SEARCH_CONTEXT_DESC + CURRENT_SITE + web-search-context + + + + CURRENT_SITE + + + + SITES + + + + OTHER_SITES + + + + CHILD_PAGES + + + + + + + + + PLUGINS_WEB_SERVICE_FILTERED_PAGES_CONTEXT_LANGUAGE_DESC + CURRENT + + + + CURRENT + + + + ALL + + + + OTHERS + + + + + + + + + PLUGINS_WEB_SERVICE_FILTERED_PAGES_TAGS_DESC + page-tags + + + + PLUGINS_WEB_SERVICE_FILTERED_PAGES_NB_MAX_DESC + 5 + + + + PLUGINS_WEB_SERVICE_FILTERED_PAGES_PAGINATION_DESC + + ^[1-9][0-9]*$ + PLUGINS_WEB_SERVICE_FILTERED_PAGES_PAGINATION_INVALID_REGEXP + + + + + PLUGINS_WEB_SERVICE_FILTERED_PAGES_XSLT_DESC + pages/services/filtered-pages/list_3.5.xsl + + + + + + pages/services/filtered-pages + + + + + + + + + + + @@ -57,8 +58,9 @@ - - + + + @@ -140,7 +142,7 @@ | FILTERED CONTENT Service + --> - + @@ -164,6 +166,29 @@ + + + + + + + + + + + + + + + + + + + + + @@ -338,7 +363,7 @@ - + @@ -357,7 +382,7 @@ - + @@ -377,7 +402,7 @@ - + Index: main/plugin-web/src/org/ametys/web/filter/FilteredPagesGenerator.java =================================================================== --- main/plugin-web/src/org/ametys/web/filter/FilteredPagesGenerator.java (revision 0) +++ main/plugin-web/src/org/ametys/web/filter/FilteredPagesGenerator.java (revision 0) @@ -0,0 +1,106 @@ +/* + * Copyright 2012 Anyware Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ametys.web.filter; + +import java.io.IOException; + +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.environment.ObjectModelHelper; +import org.apache.cocoon.environment.Request; +import org.apache.cocoon.generation.ServiceableGenerator; +import org.apache.cocoon.xml.XMLUtils; +import org.xml.sax.SAXException; + +import org.ametys.web.content.GetSiteAction; +import org.ametys.web.repository.page.Page; +import org.ametys.web.repository.page.ZoneItem; + +/** + * Generates SAX events for contents matching a {@ContentFilter} set in request attributes + * + */ +public class FilteredPagesGenerator extends ServiceableGenerator +{ + private PageFilterHelper _filterHelper; + + @Override + public void service(ServiceManager smanager) throws ServiceException + { + super.service(smanager); + _filterHelper = (PageFilterHelper) smanager.lookup(PageFilterHelper.ROLE); + } + + @Override + public void generate() throws IOException, SAXException, ProcessingException + { + Request request = ObjectModelHelper.getRequest(objectModel); + String currentSiteName = (String) request.getAttribute("site"); + String currentSkinName = (String) request.getAttribute("skin"); + String currentTemplateName = (String) request.getAttribute("template"); + + // Issue CMS-3391 + request.setAttribute(GetSiteAction.OVERRIDE_SITE_REQUEST_ATTR, currentSiteName); + request.setAttribute(GetSiteAction.OVERRIDE_SKIN_REQUEST_ATTR, currentSkinName); + + // Get filter in request attributes + PageFilter filter = (PageFilter) request.getAttribute("filter"); + + // Get site, language and page in request attributes. Can be null if the filter does not need them. + String siteName = (String) request.getAttribute("site"); + Page page = (Page) request.getAttribute(Page.class.getName()); + String lang = page != null ? page.getSitemap().getName() : null; + ZoneItem zoneItem = (ZoneItem) request.getAttribute(ZoneItem.class.getName()); + + try + { + contentHandler.startDocument(); + XMLUtils.startElement(contentHandler, "pages"); + + _saxRSSFeedURL(zoneItem); + + if (filter != null) + { + _filterHelper.saxMatchingPages(contentHandler, filter, siteName, lang, page); + } + + XMLUtils.endElement(contentHandler, "pages"); + contentHandler.endDocument(); + } + finally + { + request.removeAttribute(GetSiteAction.OVERRIDE_SITE_REQUEST_ATTR); + request.removeAttribute(GetSiteAction.OVERRIDE_SKIN_REQUEST_ATTR); + request.setAttribute("site", currentSiteName); + request.setAttribute("skin", currentSkinName); + request.setAttribute("template", currentTemplateName); + } + + } + + private void _saxRSSFeedURL (ZoneItem zoneItem) throws SAXException + { + if (zoneItem != null && zoneItem.getServiceParameters().getBoolean("rss", false)) + { + // Split protocol and id + String[] zoneItemId = zoneItem.getId().split("://"); + String url = "_plugins/web/" + zoneItemId[0] + "/" + zoneItemId[1] + "/rss.xml"; + + XMLUtils.createElement(contentHandler, "RSSFeedURL", url); + } + } +} Index: main/plugin-web/src/org/ametys/web/filter/DefaultPageFilter.java =================================================================== --- main/plugin-web/src/org/ametys/web/filter/DefaultPageFilter.java (revision 15614) +++ main/plugin-web/src/org/ametys/web/filter/DefaultPageFilter.java (working copy) @@ -35,6 +35,7 @@ import org.ametys.plugins.repository.query.expression.MetadataExpression; import org.ametys.plugins.repository.query.expression.StringExpression; import org.ametys.plugins.repository.query.expression.Expression.Operator; +import org.ametys.runtime.util.I18nizableText; import org.ametys.runtime.util.LoggerFactory; import org.ametys.web.repository.page.Page; import org.ametys.web.repository.page.jcr.DefaultPage; @@ -72,6 +73,9 @@ /** The number max of results */ protected int _length; + /** The title */ + protected I18nizableText _title; + /** The sort criteria */ protected SortCriteria _sortCriteria; @@ -97,7 +101,7 @@ _id = id; _resolver = resolver; } - + @Override public String getId() { @@ -440,4 +444,16 @@ } } + @Override + public I18nizableText getTitle() + { + return _title; + } + + @Override + public void setTitle(I18nizableText title) + { + _title = title; + } + } Index: main/plugin-web/src/org/ametys/web/filter/PageFilter.java =================================================================== --- main/plugin-web/src/org/ametys/web/filter/PageFilter.java (revision 15614) +++ main/plugin-web/src/org/ametys/web/filter/PageFilter.java (working copy) @@ -21,6 +21,7 @@ import org.ametys.plugins.repository.AmetysObjectIterable; import org.ametys.plugins.repository.AmetysObjectResolver; import org.ametys.plugins.repository.query.SortCriteria; +import org.ametys.runtime.util.I18nizableText; import org.ametys.web.repository.page.Page; /** @@ -218,4 +219,16 @@ * @return The matching pages. */ public AmetysObjectIterable getMatchingPages (String siteName, String lang, Page page); + + /** + * Get the title + * @return The title + */ + public I18nizableText getTitle (); + + /** + * Set the title + * @param title The title + */ + public void setTitle (I18nizableText title); } Index: main/plugin-web/src/org/ametys/web/filter/PageFilterHelper.java =================================================================== --- main/plugin-web/src/org/ametys/web/filter/PageFilterHelper.java (revision 0) +++ main/plugin-web/src/org/ametys/web/filter/PageFilterHelper.java (revision 0) @@ -0,0 +1,79 @@ +/* + * Copyright 2012 Anyware Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ametys.web.filter; + +import java.io.IOException; + +import org.apache.avalon.framework.component.Component; +import org.apache.cocoon.xml.AttributesImpl; +import org.apache.cocoon.xml.XMLUtils; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +import org.ametys.cms.filter.ContentFilter; +import org.ametys.plugins.repository.AmetysObjectIterable; +import org.ametys.web.repository.page.Page; + +/** + * Component helper for manipulating {@link ContentFilter} + */ +public class PageFilterHelper implements Component +{ + /** The Avalon Role */ + public static final String ROLE = PageFilterHelper.class.getName(); + + /** + * SAX all pages matching the given filter + * @param handler The content handler to SAX into + * @param filter The filter + * @param siteName The current site name. Can be null. + * @param lang The current language. Can be null. + * @param currentPage The current page. Can be null. + * @throws SAXException If an error occurs while SAXing + * @throws IOException If an error occurs while retrieving content. + */ + public void saxMatchingPages (ContentHandler handler, PageFilter filter, String siteName, String lang, Page currentPage) throws SAXException, IOException + { + AmetysObjectIterable pages = filter.getMatchingPages(siteName, lang, currentPage); + + int index = 0; + while (pages.hasNext() && index < filter.getLength()) + { + Page page = pages.next(); + saxPage(handler, page); + index++; + } + } + + /** + * SAX a page in its specific view + * @param handler The content handler to SAX into + * @param page The page to SAX + * @param metadataSetName The metadata set to use + * @throws SAXException If an error occurs while SAXing + * @throws IOException If an error occurs while retrieving content. + */ + public void saxPage (ContentHandler handler, Page page) throws SAXException, IOException + { + AttributesImpl attrs = new AttributesImpl(); + attrs.addCDATAAttribute("id", page.getId()); + attrs.addCDATAAttribute("name", page.getName()); + attrs.addCDATAAttribute("title", page.getTitle()); + + XMLUtils.createElement(handler, "page", attrs); + } + +} Index: main/plugin-web/src/org/ametys/web/repository/page/actions/SetPageFilterInRequestAttributesAction.java =================================================================== --- main/plugin-web/src/org/ametys/web/repository/page/actions/SetPageFilterInRequestAttributesAction.java (revision 0) +++ main/plugin-web/src/org/ametys/web/repository/page/actions/SetPageFilterInRequestAttributesAction.java (revision 0) @@ -0,0 +1,122 @@ +/* + * Copyright 2012 Anyware Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ametys.web.repository.page.actions; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.avalon.framework.parameters.ParameterException; +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.cocoon.acting.ServiceableAction; +import org.apache.cocoon.environment.ObjectModelHelper; +import org.apache.cocoon.environment.Redirector; +import org.apache.cocoon.environment.Request; +import org.apache.cocoon.environment.SourceResolver; + +import org.ametys.plugins.repository.AmetysObjectResolver; +import org.ametys.runtime.util.I18nizableText; +import org.ametys.web.filter.DefaultPageFilter; +import org.ametys.web.filter.PageFilter; +import org.ametys.web.filter.PageFilter.Context; +import org.ametys.web.repository.page.ZoneItem; + +/** + * This action creates a filter from the sitemap parameters or request parameter 'filterId' and set the filter in request attributes. + * + */ +public class SetPageFilterInRequestAttributesAction extends ServiceableAction +{ + private AmetysObjectResolver _resolver; + + @Override + public void service(ServiceManager smanager) throws ServiceException + { + super.service(smanager); + _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); + } + + @Override + public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception + { + Map result = new HashMap(); + + Request request = ObjectModelHelper.getRequest(objectModel); + + PageFilter filter = _getFilterFromParams(parameters, (ZoneItem) request.getAttribute(ZoneItem.class.getName())); + + // Set the filter in request attributes + if (filter != null) + { + request.setAttribute("filter", filter); + } + + return result; + } + + /** + * Get the filter from the action parameters. + * @param parameters + * @param zoneItem the zone item + * @return the page filter. + */ + protected PageFilter _getFilterFromParams(Parameters parameters, ZoneItem zoneItem) + { + // Creates filter from sitemap parameters + PageFilter filter = new DefaultPageFilter(null, _resolver); + + try + { + // The filter inputs + filter.setLength(parameters.getParameterAsInteger("length", Integer.MAX_VALUE)); + String searchContext = parameters.getParameter("searchContext"); + if ("DIRECT_CHILD_PAGES".equals(searchContext)) + { + // Direct child pages are child pages context with depth 1. + filter.setContext(Context.CHILD_PAGES); + filter.setDepth(1); + } + else + { + // Else, parse the context. + filter.setContext(Context.valueOf(searchContext)); + } + + if (!"".equals(parameters.getParameter("contextLang"))) + { + filter.setContextLanguage(PageFilter.ContextLanguage.valueOf(parameters.getParameter("contextLang"))); + } + filter.setTitle(new I18nizableText(parameters.getParameter("service-title"))); + + String tagAsStr = parameters.getParameter("tags", ""); + if (tagAsStr.length() > 0) + { + String[] tags = tagAsStr != null ? tagAsStr.split(",") : new String[]{}; + for (int i = 0; i < tags.length; i++) + { + filter.addTag(tags[i]); + } + } + } + catch (ParameterException e) + { + getLogger().error("Missing at least one parameter", e); + } + + return filter; + } +} Index: main/plugin-web/pages/services/filtered-pages/list_3.5.xml =================================================================== --- main/plugin-web/pages/services/filtered-pages/list_3.5.xml (revision 0) +++ main/plugin-web/pages/services/filtered-pages/list_3.5.xml (revision 0) @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file Index: main/plugin-web/pages/services/filtered-pages/list_3.5.xsl =================================================================== --- main/plugin-web/pages/services/filtered-pages/list_3.5.xsl (revision 0) +++ main/plugin-web/pages/services/filtered-pages/list_3.5.xsl (revision 0) @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + filtered-pages filtered-pages- + + service-filtered-pages + + fc_ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
    + + +
    + + + +
  • + page-list-item + + + + +
  • +
    + + + + + + + +
  • + + +
      + +
    +
    empty
    +
  • + + + + + + + + +
    + + + + + + + + + empty + + + + + + + + + + + +