Products.CMFPlone/plip-1486-redirection: Implement batching for managing existing redirects

Stephan Klinger <jenkins-z4DKO/[email protected]>
Newsgroups gmane.comp.web.zope.plone.cvs
Message-ID <[email protected]>
Repository: Products.CMFPlone
Branch: refs/heads/plip-1486-redirection
Date: 2017-07-10T09:31:40+03:00
Author: Asko Soukka (datakurre) <[email protected]>
Commit: https://github.com/plone/Products.CMFPlone/commit/9ec681659db331e0148908812c57c056d4bdcaf7

Implement batching for managing existing redirects

Files changed:
M Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt
M Products/CMFPlone/controlpanel/browser/redirects.py

diff --git a/Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt b/Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt
index 93f030bce..fbcd1eccd 100644
--- a/Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt
+++ b/Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt
@@ -118,13 +118,15 @@
 
       <form
           action="${view/view_url}"
-          method="post">
-        <fieldset>
+          method="post"
+          id="manage-existing-aliases">
+        <fieldset
+          tal:define="batch view/redirects">
           <legend i18n:translate="legend_all_existing_aliases">
             All existing aliases for this site
           </legend>
 
-          <tal:redirects repeat="redirect view/redirects">
+          <tal:redirects repeat="redirect batch">
             <div>
               <label>
               <input
@@ -137,6 +139,10 @@
             </div>
           </tal:redirects>
 
+          <div tal:condition="python:batch.numpages > 1"
+               tal:replace="structure view/batching">
+          </div>
+
           <div class="formControls">
             <input class="context"
                    type="submit"
diff --git a/Products/CMFPlone/controlpanel/browser/redirects.py b/Products/CMFPlone/controlpanel/browser/redirects.py
index 33294eb52..db4a6efbe 100644
--- a/Products/CMFPlone/controlpanel/browser/redirects.py
+++ b/Products/CMFPlone/controlpanel/browser/redirects.py
@@ -3,9 +3,11 @@
 from cStringIO import StringIO
 from plone import api
 from plone.app.redirector.interfaces import IRedirectionStorage
-from plone.memoize.instance import memoize
+from plone.batching.browser import PloneBatchView
+from plone.memoize.view import memoize
 from Products.CMFCore.interfaces import ISiteRoot
 from Products.CMFCore.permissions import ManagePortal
+from Products.CMFPlone.PloneBatch import Batch
 from Products.Five.browser import BrowserView
 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
 from Products.statusmessages.interfaces import IStatusMessage
@@ -103,6 +105,48 @@ def view_url(self):
         return self.context.absolute_url() + '/@@manage-aliases'
 
 
+class RedirectionSet(object):
+    def __init__(self):
+        self.storage = getUtility(IRedirectionStorage)
+
+        portal = getUtility(ISiteRoot)
+        self.portal_path = "/".join(portal.getPhysicalPath())
+        self.portal_path_len = len(self.portal_path)
+
+        # noinspection PyProtectedMember
+        self.data = list(self.storage._paths.keys())  # maybe be costly
+
+    def __len__(self):
+        return len(self.data)
+
+    def __iter__(self):
+        return iter(self.storage)
+
+    def __getitem__(self, item):
+        redirect = self.data[item]
+        if redirect.startswith(self.portal_path):
+            path = redirect[self.portal_path_len:]
+        else:
+            path = redirect
+        redirect_to = self.storage.get(redirect)
+        if redirect_to.startswith(self.portal_path):
+            redirect_to = redirect_to[self.portal_path_len:]
+        return {
+            'redirect': redirect,
+            'path': path,
+            'redirect-to': redirect_to,
+        }
+
+
+class RedirectsBatchView(PloneBatchView):
+    def make_link(self, pagenumber=None, omit_params=None):
+        if omit_params is None:
+            omit_params = ['ajax_load']
+        url = super(RedirectsBatchView, self).make_link(pagenumber,
+                                                        omit_params)
+        return url + u'#manage-existing-aliases'
+
+
 class RedirectsControlPanel(BrowserView):
 
     template = ViewPageTemplateFile('redirects-controlpanel.pt')
@@ -112,6 +156,10 @@ def __init__(self, context, request):
         self.errors = []
         # list of tuples: (line_number, absolute_redirection_path, err_msg, target)
 
+    def batching(self):
+        return RedirectsBatchView(self.context, self.request)(self.redirects())
+
+    @memoize
     def redirects(self):
         """ Get existing redirects from the redirection storage.
             Return dict with the strings redirect, path and redirect-to.
@@ -120,23 +168,12 @@ def redirects(self):
             If id of instance is not present in path the var 'path' and
             'redirect' are equal.
         """
-        storage = getUtility(IRedirectionStorage)
-        portal = getUtility(ISiteRoot)
-        portal_path = "/".join(portal.getPhysicalPath())
-        portal_path_len = len(portal_path)
-        for redirect in storage:
-            if redirect.startswith(portal_path):
-                path = redirect[portal_path_len:]
-            else:
-                path = redirect
-            redirectto = storage.get(redirect)
-            if redirectto.startswith(portal_path):
-                redirectto = redirectto[portal_path_len:]
-            yield {
-                'redirect': redirect,
-                'path': path,
-                'redirect-to': redirectto,
-            }
+        return Batch(
+            RedirectionSet(),
+            15,
+            int(self.request.form.get('b_start', '0')),
+            orphan=1
+        )
 
     def __call__(self):
         storage = getUtility(IRedirectionStorage)



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.