Roundup Tracker

Have you ever wanted to return to the most recently displayed issue index without having to remember which saved query you used to generate it? Or maybe you sometimes manipulate the URL directly to see some highly specific index to which you want to return later without having to save it as a query.

You can use your web browser's page history to go back but the index you'll see will likely be the locally cached copy requiring that you refresh the page manually to see any changes.

The idea here is to put a "back link" on the item page or the sidebar which returns you to the most recent index directly.

It uses roundup's built-in session storage mechanism to remember the index for each class.

  1. add an extension (eg, session.py):
       1   def session(utils, key, value=None):
       2       '''Return a session variable with optional value update.
       3 
       4       "key" name of the variable (a string)
       5       "value" optional value to assign (any marshallable type)
       6 
       7       '''
       8       db = utils.client.db
       9       store = db.getSessionManager()
      10       session = utils.client.session
      11 
      12       if value != None:
      13           store.set(session, **{key:value})
      14           db.commit()
      15 
      16       return store.get(session,key)
      17 
      18   def init(tracker):
      19       tracker.registerUtil('session', session)
    
  2. add a "refresh link" somewhere in the issue index template:
      <a tal:define="key string:index_${request/classname}; 
                     value string:${request/classname}?${request/env/QUERY_STRING}" 
         tal:attributes="href python:utils.session(utils,key,value)" 
         i18n:translate="">Refresh Index</a>
  3. add a "backlink" to the issue item template (or the sidebar):
      <a tal:attributes="href python:utils.session(utils,index_issue)" 
         i18n:translate="">Return to Index</a>

Notes

  1. I've defined "Refresh Index" link generically (drop it in the class index template for any class to save the most recent index for that class).
  2. I've defined the "Return to Index" link specifically for the issue class so it can be put in page.html along with similar links to any other class index pages your tracker may use. Simply add a link for each class replacing index_issue with index_yourclassnamehere.
  3. If an index for a given class has not yet been generated (ie, because you have not visited it yet), the "Return to Index" link will be deactivated but still visible (ie, an <a> tag with no href attribute).

  4. any session based mechanism in roundup, including this one, will only work for users who are logged in (anonymous users don't get a session).

-- Bruce Tulloch

From wiki Thu Apr 26 18:35:11 +1000 2007
From: wiki
Date: Thu, 26 Apr 2007 18:35:11 +1000
Subject: Pythonicity
Message-ID: <20070426183511+1000@www.mechanicalcat.net>

This looks very interesting and useful!

However, a more "pythonic" way of doing::

         store.set(session, **{key:value})

(creating a one-key dictionary on the fly and handing it over by reference)
would be::

         store.set(session, key=value)

which should do exactly the same.

- Tobias Herp

From wiki Thu Apr 26 18:45:29 +1000 2007
From: wiki
Date: Thu, 26 Apr 2007 18:45:29 +1000
Subject: Only for logged-in users
Message-ID: <20070426184529+1000@www.mechanicalcat.net>

Since Roundup's session mechanism works for logged-in users only, it 
would be clever to have the links only created for those (avoiding errors when anonymous users try to use them), e.g. using (untested)::

    tal:condition="request/user/id"

If performance is an issue, and since tal:define is always evaluated first (but the condition in this case doesn't depend on it), the links an be put in a surrounding (tal) element, e.g.::

 <tal:if1 condition="request/user/id">
   <a ...>...</a>
 </tal:if1>


- Tobias Herp

From wiki Thu Apr 26 20:28:57 +1000 2007
From: wiki
Date: Thu, 26 Apr 2007 20:28:57 +1000
Subject: Re: Pythonicity
Message-ID: <20070426202857+1000@www.mechanicalcat.net>

I am certainly no python expert (yet :) but I think key=value won't work because what's needed here is not the literal 'key' but the value of 'key' (ie, the argument as passed in to utils.session function).
-Bruce

From wiki Thu Apr 26 20:56:08 +1000 2007
From: wiki
Date: Thu, 26 Apr 2007 20:56:08 +1000
Subject: Re: Only for logged-in users
Message-ID: <20070426205608+1000@www.mechanicalcat.net>

You are quite right about this one. 

In fact it's vital because when not logged in, if the session function is ever called it will bomb the template. I had considered making utils.session more robust by having it test for the existence of the session and only if it exists would it attempt to access it. If it did not exist utils.session would return None or the value passed in (which is safe in most situations). I'm not well enough versed in Python to work out how to do this test inside utils.session though :-)

From richard Fri Apr 27 07:30:35 +1000 2007
From: richard
Date: Fri, 27 Apr 2007 07:30:35 +1000
Subject: Re: Pythonicity
Message-ID: <20070427073035+1000@www.mechanicalcat.net>
In-Reply-To: <20070426202857+1000@www.mechanicalcat.net>

Indeed key=value is not the same as {key:value} (it would be {'key':value})

From wiki Fri Apr 27 19:31:04 +1000 2007
From: wiki
Date: Fri, 27 Apr 2007 19:31:04 +1000
Subject: Re: Pythonicity
Message-ID: <20070427193104+1000@www.mechanicalcat.net>
In-Reply-To: <20070427073035+1000@www.mechanicalcat.net>

Ooops, right :)