Index: main/plugin-blog/i18n/messages_en.xml
===================================================================
--- main/plugin-blog/i18n/messages_en.xml (revision 31348)
+++ main/plugin-blog/i18n/messages_en.xml (working copy)
@@ -56,7 +56,8 @@
The displayed title.
Display
Service display
- Default
+ Tree
+ Flat list
Posts
Posts
Title
Index: main/plugin-blog/i18n/messages_fr.xml
===================================================================
--- main/plugin-blog/i18n/messages_fr.xml (revision 31348)
+++ main/plugin-blog/i18n/messages_fr.xml (working copy)
@@ -56,7 +56,8 @@
Titre
Affichage
Affichage
- Defaut
+ Vue arborescence
+ Liste à plat
Liste de billets
Ce service affiche une liste de billets.
Titre
Index: main/plugin-blog/pages/services/tags/list_1.0.xml
===================================================================
--- main/plugin-blog/pages/services/tags/list_1.0.xml (revision 0)
+++ main/plugin-blog/pages/services/tags/list_1.0.xml (revision 0)
@@ -0,0 +1,19 @@
+
+
+
+
+
Index: main/plugin-blog/pages/services/tags/list_1.0.xsl
===================================================================
--- main/plugin-blog/pages/services/tags/list_1.0.xsl (revision 0)
+++ main/plugin-blog/pages/services/tags/list_1.0.xsl (revision 0)
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+ 1
+ true
+
+
+ blog blog-tags blog-list
+
+ service-blog-tags
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (
+
+
+
+
+
+
+
+
+ )
+
+
+
+
Index: main/plugin-blog/pages/services/tags/tree_1.0.xsl
===================================================================
--- main/plugin-blog/pages/services/tags/tree_1.0.xsl (revision 31348)
+++ main/plugin-blog/pages/services/tags/tree_1.0.xsl (working copy)
@@ -24,7 +24,7 @@
- 1
+ 4
true
@@ -59,7 +59,7 @@
@@ -76,7 +76,7 @@
Index: main/plugin-blog/plugin.xml
===================================================================
--- main/plugin-blog/plugin.xml (revision 31348)
+++ main/plugin-blog/plugin.xml (working copy)
@@ -1000,6 +1000,7 @@
pages/services/tags
pages/services/tags/tree_1.0.xsl
+ pages/services/tags/list_1.0.xsl
Index: main/plugin-blog/src/org/ametys/plugins/blog/BlogCacheManager.java
===================================================================
--- main/plugin-blog/src/org/ametys/plugins/blog/BlogCacheManager.java (revision 31348)
+++ main/plugin-blog/src/org/ametys/plugins/blog/BlogCacheManager.java (working copy)
@@ -57,6 +57,9 @@
import org.ametys.web.repository.content.jcr.DefaultWebContent;
import org.ametys.web.repository.site.SiteManager;
import org.ametys.web.site.SiteConfigurationExtensionPoint;
+import org.ametys.web.tags.Tag;
+import org.ametys.web.tags.TagHelper;
+import org.ametys.web.tags.TagProviderExtensionPoint;
/**
* Blog cache manager.
@@ -72,6 +75,9 @@
/** The ametys object resolver. */
protected AmetysObjectResolver _ametysResolver;
+ /** Th tag provider */
+ protected TagProviderExtensionPoint _tagProviderEP;
+
/** The Site manager. */
protected SiteManager _siteManager;
@@ -104,6 +110,7 @@
_siteConf = (SiteConfigurationExtensionPoint) serviceManager.lookup(SiteConfigurationExtensionPoint.ROLE);
_blogRootHandler = (BlogPageHandler) serviceManager.lookup(BlogPageHandler.ROLE);
_workspaceSelector = (WorkspaceSelector) serviceManager.lookup(WorkspaceSelector.ROLE);
+ _tagProviderEP = (TagProviderExtensionPoint) serviceManager.lookup(TagProviderExtensionPoint.ROLE);
}
@Override
@@ -451,10 +458,35 @@
*/
public Collection getSortedPostsByTag(String siteName, String language, String tagName)
{
+ return getSortedPostsByTag (siteName, language, tagName, false);
+ }
+
+ /**
+ * Get the posts for a given tag.
+ * @param siteName
+ * @param language
+ * @param tagName
+ * @return the tag posts, indexed by ID.
+ */
+ public Collection getSortedPostsByTag(String siteName, String language, String tagName, boolean deepSearch)
+ {
PostTagCache cache = getPostTagCache(siteName, language);
List sortedPosts = new ArrayList(cache.getPosts(tagName).values());
+ if (deepSearch)
+ {
+ Tag tag = _tagProviderEP.getTag(siteName, tagName);
+ if (tag != null)
+ {
+ Set descendantsNames = TagHelper.getDescendantNames(tag, false);
+ for (String descendantsName : descendantsNames)
+ {
+ sortedPosts.addAll(cache.getPosts(descendantsName).values());
+ }
+ }
+ }
+
Collections.sort(sortedPosts, new ReverseDatePostComparator());
return sortedPosts;
Index: main/plugin-blog/src/org/ametys/plugins/blog/posts/BlogPagesGenerator.java
===================================================================
--- main/plugin-blog/src/org/ametys/plugins/blog/posts/BlogPagesGenerator.java (revision 31348)
+++ main/plugin-blog/src/org/ametys/plugins/blog/posts/BlogPagesGenerator.java (working copy)
@@ -29,6 +29,10 @@
import org.xml.sax.SAXException;
import org.ametys.plugins.blog.BlogPageHandler;
+import org.ametys.plugins.blog.repository.VirtualMonthPage;
+import org.ametys.plugins.blog.repository.VirtualPostPage;
+import org.ametys.plugins.blog.repository.VirtualTagPage;
+import org.ametys.plugins.blog.repository.VirtualYearPage;
import org.ametys.plugins.repository.AmetysObjectResolver;
import org.ametys.web.repository.page.Page;
import org.ametys.web.repository.page.PagesContainer;
@@ -107,6 +111,23 @@
attrs.addCDATAAttribute("path", page.getPathInSitemap());
attrs.addCDATAAttribute("id", page.getId());
+ if (page instanceof VirtualPostPage)
+ {
+ attrs.addCDATAAttribute("type", "post");
+ }
+ else if (page instanceof VirtualTagPage)
+ {
+ attrs.addCDATAAttribute("type", "tag");
+ }
+ else if (page instanceof VirtualYearPage)
+ {
+ attrs.addCDATAAttribute("type", "year");
+ }
+ else if (page instanceof VirtualMonthPage)
+ {
+ attrs.addCDATAAttribute("type", "month");
+ }
+
for (String tag : page.getTags())
{
attrs.addCDATAAttribute("PLUGIN_TAGS_" + tag, "empty");
Index: main/plugin-blog/src/org/ametys/plugins/blog/posts/PostsGenerator.java
===================================================================
--- main/plugin-blog/src/org/ametys/plugins/blog/posts/PostsGenerator.java (revision 31348)
+++ main/plugin-blog/src/org/ametys/plugins/blog/posts/PostsGenerator.java (working copy)
@@ -194,7 +194,7 @@
}
else if ("tag".equals(type))
{
- postIt = _blogCache.getSortedPostsByTag(siteName, language, tagName).iterator();
+ postIt = _blogCache.getSortedPostsByTag(siteName, language, tagName, true).iterator();
}
if (postIt != null)
Index: main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagPage.java
===================================================================
--- main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagPage.java (revision 31349)
+++ main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagPage.java (working copy)
@@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Map;
import java.util.Set;
import org.ametys.cms.repository.Content;
@@ -32,6 +33,7 @@
import org.ametys.plugins.repository.CollectionIterable;
import org.ametys.plugins.repository.UnknownAmetysObjectException;
import org.ametys.plugins.repository.metadata.CompositeMetadata;
+import org.ametys.runtime.util.I18nUtils;
import org.ametys.web.repository.page.Page;
import org.ametys.web.repository.page.PagesContainer;
import org.ametys.web.repository.page.Zone;
@@ -40,9 +42,13 @@
import org.ametys.web.site.SiteConfigurationExtensionPoint;
import org.ametys.web.skin.Skin;
import org.ametys.web.skin.SkinsManager;
+import org.ametys.web.tags.Tag;
+import org.ametys.web.tags.TagHelper;
+import org.ametys.web.tags.TagProviderExtensionPoint;
/**
- * Virtual page representing a year page.
+ * Virtual page representing a tag page.
+ * A tag page can contains {@link VirtualTagPage}s or {@link VirtualPostPage}
*/
public class VirtualTagPage extends AbstractBlogPage
{
@@ -53,22 +59,28 @@
private PagesContainer _root;
private String _tagName;
private String _title;
+ private TagProviderExtensionPoint _tagProviderEP;
+ private I18nUtils _i18nUtils;
/**
* Constructor.
* @param resolver the {@link AmetysObjectResolver}.
* @param cacheManager the {@link AmetysObjectResolver}.
* @param skinsManager the {@link SkinsManager}
- * @param siteConf
- * @param tagName
+ * @param tagProviderEP the tag provider
+ * @param i18nUtils the i18n utils
+ * @param siteConf the site configuration
+ * @param tagName The tag name
* @param title the page's title.
* @param root the blog root page.
*/
- public VirtualTagPage(AmetysObjectResolver resolver, BlogCacheManager cacheManager, SkinsManager skinsManager, SiteConfigurationExtensionPoint siteConf, String tagName, String title, PagesContainer root)
+ public VirtualTagPage(AmetysObjectResolver resolver, BlogCacheManager cacheManager, SkinsManager skinsManager, TagProviderExtensionPoint tagProviderEP, I18nUtils i18nUtils, SiteConfigurationExtensionPoint siteConf, String tagName, String title, PagesContainer root)
{
_resolver = resolver;
_cacheManager = cacheManager;
_skinsManager = skinsManager;
+ _tagProviderEP = tagProviderEP;
+ _i18nUtils = i18nUtils;
_siteConf = siteConf;
_root = root;
_tagName = tagName;
@@ -146,6 +158,23 @@
{
ArrayList childrenPages = new ArrayList();
+ Tag tag = _tagProviderEP.getTag(getSiteName(), _tagName);
+
+ Set tagNames = _cacheManager.getTags(getSiteName(), getSitemapName());
+
+ Map childTags = tag.getTags();
+ for (Tag childTag : childTags.values())
+ {
+ Set descendantAndItSelfNames = TagHelper.getDescendantNames(childTag, true);
+
+ if (!Collections.disjoint(tagNames, descendantAndItSelfNames))
+ {
+ String title = _i18nUtils.translate(childTag.getTitle(), getSitemapName());
+ VirtualTagPage page = new VirtualTagPage(_resolver, _cacheManager, _skinsManager, _tagProviderEP, _i18nUtils, _siteConf, childTag.getName(), title, _root);
+ childrenPages.add(page);
+ }
+ }
+
// Map posts = _cacheManager.getPostsByTag(getSiteName(), getSitemapName(), _tagName);
Collection posts = _cacheManager.getSortedPostsByTag(getSiteName(), getSitemapName(), _tagName);
for (Post post : posts)
@@ -165,14 +194,24 @@
{
String rootPath = _root.getPathInSitemap();
- StringBuilder buff = new StringBuilder(rootPath);
+ String path = _tagName;
+
+ Tag tag = _tagProviderEP.getTag(getSiteName(), _tagName);
+ Tag parentTag = tag.getParent();
+ while (parentTag != null)
+ {
+ path = parentTag.getName() + "/" + path;
+ parentTag = parentTag.getParent();
+ }
+
+ path = VirtualTagsPage.NAME + "/" + path;
+
if (!rootPath.isEmpty())
{
- buff.append('/');
+ path = "/" + path;
}
- buff.append(VirtualTagsPage.NAME).append('/').append(_tagName);
- return buff.toString();
+ return path;
}
@Override
@@ -208,27 +247,35 @@
throw new AmetysRepositoryException("Path must be non empty");
}
-// int slashPos = path.indexOf('/');
-// int questionPos = path.indexOf('?', slashPos);
-// int ampPos = path.indexOf('&', questionPos);
-
-// String childName = slashPos == -1 ? path : path.substring(0, slashPos);
-// String rootId = path.substring(questionPos + "?rootId=".length(), ampPos);
-// String postId = path.substring(ampPos + "&postId=".length());
-
+ // TAG_1/TAG_2/TAG_3
int slashPos = path.indexOf('/');
String childName = slashPos == -1 ? path : path.substring(0, slashPos);
- Post post = _cacheManager.getPostByName(getSiteName(), getSitemapName(), _tagName, childName);
- if (post == null)
+ AbstractBlogPage page = null;
+ if (_cacheManager.hasTag(getSiteName(), getSitemapName(), childName))
{
- throw new UnknownAmetysObjectException(path + " is not a valid post page.");
+ Tag tag = _tagProviderEP.getTag(getSiteName(), childName);
+ if (tag == null)
+ {
+ throw new UnknownAmetysObjectException("No child named " + childName + " exists in parent " + getId());
+ }
+
+ String title = _i18nUtils.translate(tag.getTitle(), getSitemapName());
+
+ page = new VirtualTagPage(_resolver, _cacheManager, _skinsManager, _tagProviderEP, _i18nUtils, _siteConf, childName, title, _root);
}
-
- Content postContent = _resolver.resolveById(post.getId());
-
- VirtualPostPage page = new VirtualPostPage(_resolver, _skinsManager, _root, postContent, VirtualTagsPage.NAME + "/" + _tagName);
+ else
+ {
+ Post post = _cacheManager.getPostByName(getSiteName(), getSitemapName(), _tagName, childName);
+ if (post == null)
+ {
+ throw new UnknownAmetysObjectException(path + " is not a valid post page.");
+ }
+
+ Content postContent = _resolver.resolveById(post.getId());
+ page = new VirtualPostPage(_resolver, _skinsManager, _root, postContent, VirtualTagsPage.NAME + "/" + _tagName);
+ }
if (slashPos == -1)
{
Index: main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagPageFactory.java
===================================================================
--- main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagPageFactory.java (revision 31349)
+++ main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagPageFactory.java (working copy)
@@ -16,6 +16,9 @@
package org.ametys.plugins.blog.repository;
+import java.util.Collections;
+import java.util.Set;
+
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
@@ -33,6 +36,7 @@
import org.ametys.web.site.SiteConfigurationExtensionPoint;
import org.ametys.web.skin.SkinsManager;
import org.ametys.web.tags.Tag;
+import org.ametys.web.tags.TagHelper;
import org.ametys.web.tags.TagProviderExtensionPoint;
/**
@@ -89,20 +93,24 @@
PagesContainer root = _resolver.resolveById(rootId);
- if (!_cacheManager.hasTag(root.getSiteName(), root.getSitemapName(), tagName))
- {
- throw new UnknownAmetysObjectException("There's no virtual child page named " + tagName + " for parent " + rootId);
- }
-
Tag tag = _tagProviderEP.getTag(root.getSiteName(), tagName);
+
if (tag == null)
{
throw new UnknownAmetysObjectException("There's no virtual child page named " + tagName + " for parent " + rootId);
}
+ Set descendantOrItSelfNames = TagHelper.getDescendantNames(tag, true);
+ Set tagNames = _cacheManager.getTags(root.getSiteName(), root.getSitemapName());
+
+ if (Collections.disjoint(tagNames, descendantOrItSelfNames))
+ {
+ throw new UnknownAmetysObjectException("There's no virtual child page named " + tagName + " for parent " + rootId);
+ }
+
String title = _i18nUtils.translate(tag.getTitle(), root.getSitemapName());
- return new VirtualTagPage(_resolver, _cacheManager, _skinsManager, _siteConf, tagName, title, root);
+ return new VirtualTagPage(_resolver, _cacheManager, _skinsManager, _tagProviderEP, _i18nUtils, _siteConf, tagName, title, root);
}
@Override
@@ -113,17 +121,28 @@
String tagName = id.substring(getScheme().length() + 3, rootPos);
String rootId = id.substring(rootPos + "?rootId=".length());
- Page root = null;
+ PagesContainer root = _resolver.resolveById(rootId);
try
{
root = _resolver.resolveById(rootId);
- }
+
+ Tag tag = _tagProviderEP.getTag(root.getSiteName(), tagName);
+ if (tag == null)
+ {
+ return false;
+ }
+
+ Set descendantOrItSelfNames = TagHelper.getDescendantNames(tag, true);
+ Set tagNames = _cacheManager.getTags(root.getSiteName(), root.getSitemapName());
+
+ return !Collections.disjoint(tagNames, descendantOrItSelfNames);
+ }
catch (UnknownAmetysObjectException e)
{
// Ignore.
}
- return root != null && _cacheManager.hasTag(root.getSiteName(), root.getSitemapName(), tagName);
+ return false;
}
/**
Index: main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagsPage.java
===================================================================
--- main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagsPage.java (revision 31349)
+++ main/plugin-blog/src/org/ametys/plugins/blog/repository/VirtualTagsPage.java (working copy)
@@ -19,6 +19,8 @@
import java.util.Collections;
import java.util.Set;
+import javax.jcr.RepositoryException;
+
import org.ametys.plugins.blog.BlogCacheManager;
import org.ametys.plugins.explorer.resources.ResourceCollection;
import org.ametys.plugins.repository.AmetysObject;
@@ -27,6 +29,7 @@
import org.ametys.plugins.repository.AmetysRepositoryException;
import org.ametys.plugins.repository.CollectionIterable;
import org.ametys.plugins.repository.EmptyIterable;
+import org.ametys.plugins.repository.TraversableAmetysObject;
import org.ametys.plugins.repository.UnknownAmetysObjectException;
import org.ametys.plugins.repository.metadata.CompositeMetadata;
import org.ametys.runtime.util.I18nUtils;
@@ -39,7 +42,10 @@
import org.ametys.web.site.SiteConfigurationExtensionPoint;
import org.ametys.web.skin.SkinsManager;
import org.ametys.web.tags.Tag;
+import org.ametys.web.tags.TagHelper;
import org.ametys.web.tags.TagProviderExtensionPoint;
+import org.ametys.web.tags.jcr.JCRTag;
+import org.ametys.web.tags.jcr.JCRTagProvider;
/**
* Virtual page representing the Post list page.
@@ -146,13 +152,6 @@
public Zone getZone(String name) throws UnknownZoneException, AmetysRepositoryException
{
throw new UnknownZoneException("There is no zone on the blog tags page.");
-// return null;
-// if (!"default".equals(name))
-// {
-// throw new IllegalArgumentException("Only the zone named 'default' is actually supported on virtual program pages.");
-// }
-//
-// return new DomainZone(this);
}
@Override
@@ -174,6 +173,40 @@
Set tagNames = _cacheManager.getTags(getSiteName(), getSitemapName());
+ JCRTagProvider provider = (JCRTagProvider) _tagProviderEP.getExtension(JCRTagProvider.class.getName());
+ try
+ {
+ TraversableAmetysObject rootNode = provider.getRootNode(getSiteName());
+ AmetysObjectIterable it = rootNode.getChildren();
+ for (AmetysObject object : it)
+ {
+ if (object instanceof JCRTag)
+ {
+ String tagName = object.getName();
+ Tag tag = _tagProviderEP.getTag(getSiteName(), object.getName());
+
+ Set descendantAndItSelfNames = TagHelper.getDescendantNames(tag, true);
+
+ if (!Collections.disjoint(tagNames, descendantAndItSelfNames))
+ {
+ String title = _i18nUtils.translate(tag.getTitle(), getSitemapName());
+
+ VirtualTagPage page = new VirtualTagPage(_resolver, _cacheManager, _skinsManager, _tagProviderEP, _i18nUtils, _siteConf, tagName, title, _root);
+
+ children.add(page);
+ }
+ }
+ }
+ }
+ catch (RepositoryException e)
+ {
+ throw new AmetysRepositoryException("Unable to get tags pages", e);
+ }
+
+ /*ArrayList children = new ArrayList();
+
+ Set tagNames = _cacheManager.getTags(getSiteName(), getSitemapName());
+
for (String tagName : tagNames)
{
Tag tag = _tagProviderEP.getTag(getSiteName(), tagName);
@@ -185,7 +218,7 @@
children.add(page);
}
- }
+ }*/
return new CollectionIterable(children);
}
@@ -240,20 +273,23 @@
String childName = slashPos == -1 ? path : path.substring(0, slashPos);
- if (!_cacheManager.hasTag(getSiteName(), getSitemapName(), childName))
+ Set tagNames = _cacheManager.getTags(getSiteName(), getSitemapName());
+
+ Tag tag = _tagProviderEP.getTag(getSiteName(), childName);
+ if (tag == null)
{
throw new UnknownAmetysObjectException("No child named " + childName + " exists in parent " + getId());
}
- Tag tag = _tagProviderEP.getTag(getSiteName(), childName);
- if (tag == null)
+ Set descendantAndItSelfNames = TagHelper.getDescendantNames(tag, true);
+ if (Collections.disjoint(tagNames, descendantAndItSelfNames))
{
throw new UnknownAmetysObjectException("No child named " + childName + " exists in parent " + getId());
}
String title = _i18nUtils.translate(tag.getTitle(), getSitemapName());
- VirtualTagPage page = new VirtualTagPage(_resolver, _cacheManager, _skinsManager, _siteConf, childName, title, _root);
+ VirtualTagPage page = new VirtualTagPage(_resolver, _cacheManager, _skinsManager, _tagProviderEP, _i18nUtils, _siteConf, childName, title, _root);
if (slashPos == -1)
{
Index: main/plugin-blog/stylesheets/content/post/post.xsl
===================================================================
--- main/plugin-blog/stylesheets/content/post/post.xsl (revision 31348)
+++ main/plugin-blog/stylesheets/content/post/post.xsl (working copy)
@@ -80,8 +80,8 @@
-
-
+
+
,