Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #2024 (closed task: fixed)

Opened 11 years ago

Last modified 10 years ago

Using CherryPy Filters to handle the same parameter on each controller method

Reported by: exhuma Owned by: Chris Arndt
Priority: normal Milestone: 1.1.x bugfix
Component: Documentation Version: 1.0
Severity: normal Keywords: doc request
Cc:

Description

I was not able to find a proper section in the documentation pages, so I decided to open a ticket :/ You could consider this a recipe/howto. I hope it will make it into the official/rough docs. It took me quite some time to find the appropriate pointers/hints on how to work with filters....

Problem

You want to add the same GET/POST parameter to each controller method, but using **kwargs is cumbersome. Imagine you want to be able to change the "skin" variable on any controller.

Solution

Using CherryPy? filters you can intercept the request before it reaches the controller method and add/remove parameters from the request object. You could then, for example, put this request into the session.

So:

  1. Write a CherryPy? filter
  2. Append the filter to a controller. Note that the filter is also active for all controllers inside that controller!

The Filter class

from cherrypy.filters.basefilter import BaseFilter
from cherrypy import request, session

class SkinFilter(BaseFilter):
   """
   If the request parameters contain a "skin" variable, pull it out the request
   and put it into the session
   """

   __detected_skin = None

   def before_request_body(self):
      try:
         if "skin" in request.params:
            skin = request.params.pop("skin")
            if skin is not None:
               self.__detected_skin = skin
      except Exception, e:
         log.warning( "Error in %s:\n%s" % (self.__class__.__name__, str(e)) )

   def before_main(self):
      if self.__detected_skin is not None:
         session['skin'] = self.__detected_skin

Adding it to the controller

...

class Root(controllers.RootController):

   # attach cherrypy filters
   _cp_filters = [SkinFilter()]

   ...

The filter could also be attached to non-root controllers so only parts of you application handles those requests.

Change History

comment:1 Changed 11 years ago by exhuma

Oh. I forgot: The reason why I pop the parameter from the request is to prevent CherryPy? from complaining if it's set to strictly check for parameters.

comment:2 Changed 10 years ago by Chris Arndt

  • Milestone set to 1.1.x bugfix

comment:3 Changed 10 years ago by Chris Arndt

  • Status changed from new to closed
  • Resolution set to fixed
Note: See TracTickets for help on using tickets.