skip to navigation
skip to content

Not Logged In

horae.layout 1.0a1

Provides the global layout for the Horae resource planning system

Introduction

The horae.layout package provides the global layout for the Horae resource planning system by defining base classes for views, forms (add, edit, delete and display) and viewlets. Additionally the following features are provided:

  • Registration of several viewlet managers
  • Integration of megrok.navigation
  • Helper view to create tables
  • Generic views for listing, adding, editing and deleting objects in a container
  • Possibility to register fanstatic resources through named adapters
  • Registration of the horae.datetime widgets
  • Registration of rich text widgets using megrok.form

Usage

Views

The aforementioned base classes for views, forms and viewlets are defined in horae.layout.layout. All the views defined there provide the functionality to be called with two special parameters provided through GET or POST:

plain
If this parameter is set to any truth value only the views result is rendered without the whole layout put around.
selector
If this parameter is set to any CSS selector only the contents of the element matching the selector is returned.

Those base classes are also responsible for including the fanstatic resources provided by the named adapters implementing horae.layout.interfaces.IResourceProvider.

Add forms

Creating an add form using horae.layout is done by sub-classing from the provided base class horae.layout.layout.AddForm and implementing the required methods:

import grok

from horae.layout import layout
from some.module.interfaces import ISampleContent, ISampleContainer
from some.module.content import SampleContent

class AddSampleContent(layout.AddForm):
    grok.context(ISampleContainer)
    form_fields = grok.AutoFields(ISampleContent)

    def create(self, **data):
        return SampleContent()

    def add(self, obj):
        self.context[obj]

This will render a form having a Add and Cancel button.

Edit forms

Edit forms work pretty much the same as add forms. The only difference is the class to be sub-classed and that there are no methods required to be implemented:

class EditSampleContent(layout.EditForm):
    grok.context(ISampleContent)
    form_fields = grok.AutoFields(ISampleContent)

This will render a form having a Save changes and Cancel button.

Display forms

Like edit forms display forms require no implementation at all:

class DisplaySampleContent(layout.DisplayForm):
    grok.context(ISampleContent)
    form_fields = grok.AutoFields(ISampleContent)

Delete forms

Delete forms provide a confirmation view before actually deleting an object and are implemented by sub-classing from horae.layout.layout.DeleteForm:

class DeleteSampleContent(layout.DeleteForm):
    grok.context(ISampleContent)

    def item_title(self):
        return self.context.title

View extenders

Additionally the views sub-classing from those base classes may be extended by other packages using so called view extenders, which are named adapters implementing horae.layout.interfaces.IViewExtender and adapting the view itself. If for example one would like to add an additional field to the aforementioned add form without touching the form itself:

from zope import schema
from horae.layout import interfaces

class AddSampleContentExtender(grok.Adapter):
    grok.context(AddSampleContent)
    grok.implements(interfaces.IViewExtender)
    grok.name('addsamplecontentextender')

    def pre_update(self):
        """ Called before the views update is called
        """
        self.context.form_fields = self.context.form_fields + \
            grok.Fields(additional_field=schema.TextLine(
                title=u'Additional field'
            ))

    def pre_setUpWidgets(self, ignore_request=False):
        """ Called before the forms setUpWidgets is called
        """
        # set custom widgets for fields using this method

    def post_update(self):
        """ Called after the views update is called
        """
        # set default values for fields using this method

    def apply(self, obj, **data):
        """ Called when applying changes to an object
        """
        obj.additional_field = data.get('additional_field', None)

    def validate(self, action, data):
        """ Called when validating a form
        """
        # do custom validation using this method

Viewlet managers

The following viewlet managers are registered in horae.layout.viewlets:

TopManager
Viewlet manager rendered on top
HeaderLeftManager
Viewlet manager rendered on the left in the header
HeaderRightManager
Viewlet manager rendered on the right in the header
ContentBeforeManager
Viewlet manager rendered before the content
ContentAfterManager
Viewlet manager rendered after the content
SidebarManager
Viewlet manager rendered in the sidebar
FooterManager
Viewlet manager rendered in the footer

Table helper view

The table helper view is implemented in horae.layout.table and registered as a view named table. The view handles sorting, filtering and pagination of tabular data. An example usage of the view may be found in horae.layout.objects.ObjectOverview.

A simple usage may look like this:

from zope.component import getMultiAdapter
from zope.schema import vocabulary

class SampleTableView(grok.View):

    def render_table(self):
        table = getMultiAdapter((self.context, self.request), name=u'table')
        table.page_size = 10
        table.columns = (
            ('col1', u'Column 1'),
            ('col2', u'Column 2')
        )
        table.sortable = {
            'col1': 'col1',
            'col2': 'col2'
        }
        table.filterable = {
            'col1': vocabulary.SimpleVocabulary.fromValues([
                        'Group 1',
                        'Group 2',
                        'Group 3'
                    ])
        }
        rows = [
            {'col1': 'Group 1', 'col2': 'Row 1'},
            {'col1': 'Group 1', 'col2': 'Row 2'},
            {'col1': 'Group 1', 'col2': 'Row 3'},
            {'col1': 'Group 2', 'col2': 'Row 4'},
            {'col1': 'Group 2', 'col2': 'Row 5'},
            {'col1': 'Group 2', 'col2': 'Row 6'},
            {'col1': 'Group 3', 'col2': 'Row 7'},
            {'col1': 'Group 3', 'col2': 'Row 8'},
            {'col1': 'Group 4', 'col2': 'Row 9'},
        ]
        filtering = table.filtering()
        if 'col1' in filtering:
            rows = [row for row in rows if row['col1'] in filtering['col1']]
        sort, reverse = table.sorting()
        if sort:
            rows = sorted(rows, key=lambda row: row[sort])
        if reverse:
            rows = reversed(rows)
        table.rows = rows
        return table()

This would result in a table of two columns and nine rows which is sortable by both columns and the first column is filterable.

Changelog

1.0a1 (2012-01-16)

  • Initial release
 
File Type Py Version Uploaded on Size
horae.layout-1.0a1.tar.gz (md5) Source 2012-01-16 56KB
  • Downloads (All Versions):
  • 3 downloads in the last day
  • 36 downloads in the last week
  • 163 downloads in the last month