diff src/pages/common/blog/page_meta.py @ 1016:fc1c913cc9d1

pages (blog_new, common/blog): various blog improvments: - item_id can now be specified in URL parsing, and a filter_keyword is used so future variants can be implemented (e.g. tags) - if item_id is specified, rsm is discarded and only the requested item is retrieved - new template data "items_http_uri" is filled, with links to HTTP versions of items - blog_new is now a simple redirection to common/blog as the later should be generic enough to handle all use cases.
author Goffi <goffi@goffi.org>
date Fri, 19 Jan 2018 18:09:39 +0100
parents fe08a5c95b27
children 2ae3b6291456
line wrap: on
line diff
--- a/src/pages/common/blog/page_meta.py	Fri Jan 19 18:01:58 2018 +0100
+++ b/src/pages/common/blog/page_meta.py	Fri Jan 19 18:09:39 2018 +0100
@@ -23,10 +23,13 @@
 
 
 def parse_url(self, request):
-    """URL is /[service]/[node]
+    """URL is /[service]/[node]/[filter_keyword]/[item]|[other]
 
-    if [node] is not found, default namespace is used
-    if both [service] and [node] are not found, default service is used too
+    if [node] is '@', default namespace is used
+    if a value is unset, default one will be used
+    keyword can be one of:
+        id: next value is a item id
+        tag: next value is a blog tag
     """
     data = self.getRData(request)
 
@@ -45,6 +48,24 @@
         data['node'] = self.nextPath(request)
     except IndexError:
         data['node'] = u''
+    else:
+        if data['node'] == u'@':
+            data['node'] = u''
+
+    try:
+        filter_kw = data['filter_keyword'] = self.nextPath(request)
+    except IndexError:
+        pass
+    else:
+        if filter_kw == u'id':
+            try:
+                data['item'] = self.nextPath(request)
+            except IndexError:
+                self.pageError(request, C.HTTP_BAD_REQUEST)
+        else:
+            # invalid filter keyword
+            log.warning(_(u"invalid filter keyword: {filter_kw}").format(filter_kw=filter_kw))
+            self.pageError(request, C.HTTP_BAD_REQUEST)
 
 
 @defer.inlineCallbacks
@@ -77,13 +98,17 @@
             yield appendComments(self, comments, identities, profile)
 
 @defer.inlineCallbacks
-def getBlogData(self, request, service, node, extra, profile):
+def getBlogData(self, request, service, node, item_id, extra, profile):
     try:
+        if item_id:
+            items_id = [item_id]
+        else:
+            items_id = []
         blog_data = yield self.host.bridge.mbGet(
                               service.userhost(),
                               node,
                               C.NO_LIMIT,
-                              [],
+                              items_id,
                               extra,
                               profile)
     except Exception as e:
@@ -100,30 +125,39 @@
 def prepare_render(self, request):
     data = self.getRData(request)
     # if the comments are not explicitly hidden, we show them
-    service, node, show_comments = data.get(u'service', u''), data.get(u'node', u''), data.get(u'show_comments', True)
+    service, node, item_id, show_comments = data.get(u'service', u''), data.get(u'node', u''), data.get(u'item'), data.get(u'show_comments', True)
     profile = self.getProfile(request)
     if profile is None:
         profile = C.SERVICE_PROFILE
 
     params = self.getAllPostedData(request, multiple=False)
-    extra = {u'rsm_max': u'10'}
-    if u'after' in params:
-        extra[u'rsm_after'] = params[u'after']
-    elif u'before' in params:
-        extra[u'rsm_before'] = params[u'before']
+    if item_id:
+        extra = {}
+    else:
+        extra = {u'rsm_max': u'10'}
+        if u'after' in params:
+            extra[u'rsm_after'] = params[u'after']
+        elif u'before' in params:
+            extra[u'rsm_before'] = params[u'before']
 
-    blog_data, items = yield getBlogData(self, request, service, node, extra, profile)
+    blog_data, items = yield getBlogData(self, request, service, node, item_id, extra, profile)
     template_data = request.template_data
     if items:
-        last_id = items[-1].id
-        template_data['older_url'] = self.getParamURL(request, after=last_id)
-        if u'before' in params or u'after' in params:
-            first_id = items[0].id
-            template_data['newer_url']  = self.getParamURL(request, before=first_id)
+        if not item_id:
+            last_id = items[-1].id
+            template_data['older_url'] = self.getParamURL(request, after=last_id)
+            if u'before' in params or u'after' in params:
+                first_id = items[0].id
+                template_data['newer_url']  = self.getParamURL(request, before=first_id)
     else:
+        if item_id:
+            # if item id has been specified in URL and it's not found,
+            # we must return an error
+            self.pageError(request, C.HTTP_NOT_FOUND)
+
         # no items, we have requested items before last post, or blog is empty
         extra = {u'rsm_max': u'10'}
-        blog_data, items = yield getBlogData(self, request, service, node, extra, profile)
+        blog_data, items = yield getBlogData(self, request, service, node, None, extra, profile)
         if items:
             last_id = items[-1].id
             template_data['older_url'] = self.getParamURL(request, after=last_id)
@@ -133,7 +167,9 @@
     if show_comments:
         yield appendComments(self, items, identities, profile)
 
-    template_data[u'items'] = items
+    blog_view = self.getPageByName(u'blog_view')
+    template_data[u'items'] = data[u'items'] = items
+    template_data[u'items_http_uri'] = {item.id: self.host.getExtBaseURL(request, blog_view.getURL(service.full(), node or '@', u'id', item.id)) for item in items}
     template_data[u'allow_commenting'] = data.get(u'allow_commenting', False)