• BU Home | 
  • News | 
  • Events | 
  •  | 
  •  

Web Services Wiki

Welcome Guest: Login

BU Public Layout

The BU Public layout extends the base bethel layout (IBaseBethelSkin) to provide the public layout / template for Bethel University.  It is located in the Products.BethelTemplates.templates.bu.

An interesting feature of this template is it's use of viewlets (pluggable view components) to render the two elements in the top header: the top header (in black) and the Personal Bar.

Directory Structure

  • configure.zcml
  • bu.py
  • maintemplate.pt
  • resource directories

    • buassets
    • bugraphics
  • viewlets

    • butopdiv
    • butopbar

configure.zcml

This component registration file does the following:

  • Registers the resource directories

    • buassets contains stylesheets
    • bugraphics contains the graphics for the public template (logos, spacer gif, etc)
  • defines the IBethelBU skin as an interface
  • includes the "viewlets" package, where this skin's viewlets are defined
  • registers browser:pages for Silva IContent and IContainer interfaces, which use maintemplate.pt and the appropriate view class from bu.py.

bu.py

This module defines the IBethelBU skin, which extends IBaseBethelSkin.

resource directories

See configure.zcml for a description of these directories.

maintemplate.pt

This is the primary layout rendering template.  It uses the "page" basemacro, accessible via "context/@@bethel_macros/page".  A few things to note about the variables used in this template:

  1. "view" is either the IBethelBase Content or Container view class
  2. "context" is the content object (model), which is either an IContent or IContainer
  3. The site config (BethelSite) is named "config", and defined using view/get_site_config
  4. The page content is rendered at the top of the template, before the "page" macro is used.  This is done primarily so that the head_stuffer request variable can be populated.
  5. prefs is the site's preferences (either public or preview)
  6. papi_prefs is the preferences sent through the PortalAPI

Slots filled

headers
  • stylesheets are inserted here

body

The public template is rendered here.   The stdtop viewlets are looked up almost right away, using:

 <tal:providers replace="structure provider:bu.stdtop" tal:condition="not:hide_template" />

To force an order for the viewlets, they are both defined as python classes, whose __call__ methods return a rendered page template.  The order is based on python's default __cmp__ method, so the classes are placed in viewlets/impl.py in the order they are to appear on the page.  This is a hack...the web component dev w/ zope3 book defines a nicer "sortedviewletmanager" approach, but I was unable to get this to work.

There are two spots where a config preference value could either be a script id or a menu id.  Here's the logic to determine which, and render appropriately:

tal:define="m python:submenu.startswith('m@') and view.renderSubMenu(config,submenu[2:]) 
                     or view.call_site_config_script(config,submenu)"

Viewlets

These are pluggable components grouped by Viewlet Manager and attached to a skin.  Viewlets enable the template to provide "slots" where components will be placed, and the template doesn't necessarily need to know (or care) what those components are.  Viewlets enable new components to be added to the  template without the template needing modification.  This can be particularly useful when extending a base template from a new layout.  These are also useful for code abstraction, so the maintemplate need not be so monolithic.

The top area of the BU template was broken up into two viewlets partly to abstract this (lengthy) chunk of code out of the maintemplate, and also to learn how viewlets work.

There are currently two viewlets: butopdiv and butopbar.

butopdiv

This is a very basic pagetemplate viewlet.  It has a view class, but only to assist in the ordering of the viewlets.  The butopdiv is everything in the black top bar.  The only dynamic component here is the site title.

butopbar

This is the personalbar, which contains the site menu on the right and the welcome/login on the left.  It's view class has some business logic to determine whether the personalbar should be displayed (it can be and usually is disabled), and also to determine whether the welcome/login should be displayed (since some sites just use the site menu).

Viewlets have access to the parent view, which in this case has the BaseViewMixin as a base class, and so butopbar uses the renderTopMenu and call_site_config_script methods of this base class.  The parent view is access within the viewlet page template by accessing the viewlets "view class" __parent__ attribute, e.g.:

view.__parent__.call_site_config_script(config,somescriptid)

Keep in mind that the "view" variable in the above example is the viewlets view class.  In this case it is Products.BethelTemplates.templates.bu.viewlets.impl.BUTopBar