Header image rotation with KSSΒΆ

Tags: plone

Use case: the customer has an image at the top of the webpage that has to be rotated every 10 seconds. I didn't want to do that with some downloaded javascript file, but with KSS. With some pointers from Huub Bouma in irc I managed to get it done in no time. Necessary prerequisite: enable kss all the time in portal_javascripts, also for anonymous users (by default it is off for anonymous).

The great thing about KSS' way of doing ajax is their core design decision to keep the business logic on the server side instead of burying it inside unreadable javascript. The server-side functionality is done in browser/imagerotator.py (in my case). Simple, readable, python:

  from random import choice
  from kss.core import kssaction
  from plone.app.kss.plonekssview import PloneKSSView
  ... # Some parts omitted for brevity.

  IMGTEMPLATE = '<img alt="" src="%s" />'

  class ImageRotatorView(PloneKSSView):
      """KSS server action to rotate the header image."""

      def availabel_image_urls(self):
          catalog = getToolByName(self.context, 'portal_catalog')
          # Nothing fancy, just grab all image urls inside a
          # specific folder.
          ...
          urls = [brain.getURL() for brain in brains]
          return urls

      @kssaction
      def rotate(self):
          # The actual KSS work.
          ksscore = self.getCommandSet('core')
          urls = self.availabel_image_urls()
          if not urls:
              return
          url = choice(urls)
          content = IMGTEMPLATE % url
          ksscore.replaceInnerHTML('#portal-top-picture', content)

The method rotate() does the actual server-side work by telling KSS to replace the contents of <div id="portal-top-picture"> with a new image tag. A snippet of zcml makes the method available as rotateImage (browser/configure.zcml):

    <!-- Image rotator kss action -->
    <browser:page
        for="*"
        class=".imagerotator.ImageRotatorView"
        attribute="rotate"
        name="rotateImage"
        permission="zope2.View"
        />
    <browser:resource
      name="rotate.kss"
      file="resources/rotate.kss"
      />

A tiny kss stylesheet takes care of calling this method every 10 seconds (=10000 ms). browser/resources/rotate.kss :

  /* Rotate image every 10 seconds*/

  document:timeout {
      evt-timeout-delay: 10000;
      action-server: rotateImage;
      }

Last step: enable the stylesheet (handy with genericsetup's profiles/default/kssregistry.xml):

  <?xml version="1.0"?>
  <object name="portal_kss" meta_type="KSS Registry">
    <kineticstylesheet
        cacheable="True" compression="safe" cookable="True"
        enabled="1" expression="" id="++resource++rotate.kss"/>
  </object>

Works like a charm!

(Old imported comments)
"Doesn't work unless you're logged in?" by http://duffyd.myopenid.com/ on 2009-04-04 22:44:00
Thanks a lot!
"Doesn't work unless you're logged in?" by reinout on 2009-04-04 10:53:47
By default, the kss-handling javascript is disabled for anonymous users. By plone. See section 1.2 on http://plone.org/[...]/how-to-setup-and-use-kss-on-plone-3.0 .
"Doesn't work unless you're logged in?" by http://duffyd.myopenid.com/ on 2009-04-04 08:33:17
Hi Reinout,
I've just implemented this on a site[1] but it doesn't work unless the user is logged on. There's no errors in the logs. Any ideas why? I tried changing the permission on the KSSView to be zope2.Public but still doesn't work :(
Thanks,
Tim
[1] http://miusa3.netcorps-dev.org/
 
vanrees.org logo

About me

My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):