A CWF Section

In Django, you define the urls in your site by creating urlpatterns.

This is usually done by hand, but this means that if you want to generate a menu system on your site from your urls, you have to essentially duplicate the structure of your website.

CWF instead provides classes that can be used to generate both the urlpatterns and a data structure that can be used to generate a menu from.

Usage looks like:

from cwf.sections import Section

section = Section().configure(module="webthing.views")

section.first(name="root").configure(target='base')
section.add('login', name='login').configure(target='login')
section.add('logout', name='logout').configure(target='logout')

numbers = section.add('numbers')
numbers.add("one").configure(target="one")
numbers.add("two").configure(target="two")

section.add('\d+').configure(''
    , target='digits'
    , match='digit'
    )

urlpatterns = section.patterns()

For this very simple case, it would be the same as:

from django.conf.urls import patterns

urlpatterns = patterns(''
    , (r'^$', 'webthing.views.base', name="root")
    , (r'^login/$', 'webthing.views.login', name="login")
    , (r'^logout/$', 'webthing.views.logout', name="logout")
    , (r'^numbers/one/$', 'webthing.views.one')
    , (r'^numbers/two/$', 'webthing.views.two')
    , (r'^(?P<digit>\d+)/$', 'webthing.views.digits')
    )

Configuring a section

Every section has an options object that knows what options are available , what values those options can be, and some helpful methods for determining information about the section from those options.

You can configure these options by using “section.configure”.

For example:

tests = section.add("tests").configure(''
    , kls = 'testViews'
    , redirect = 'register'
    , needs_auth = True
    )

Note

Positional arguments to configure are ignored.

There are options available for how the section appears in the urlpatterns ; what view is used; and how it appears in the menu that can be generated.

Adding child sections

Sections represent only one part of the url. To make urls with more than one part to it, we need to build up a heirarchy of sections. We can do this by adding child sections to each section.

When we then did “section.first” and “section.add” we created new sections with the url and name as passed into those functions and these new sections got the first section as it’s parent. The first section also records these new sections on itself.

Note

section.first() behaves exactly as section.add() except the section will consider this child section to be first before any other child sections and there can only be one “first” section.

You can also add sections via the merge, adopt and copy functions on the section.

Note

Creating a section this way will copy most options from the parent onto the child.

Adding a Child

The “section.first” and “section.add” methods are shortcuts to “section.add_child” where the only difference is “section.first” will call “add_child” with “first=True”

“section.first” will also default url to an empty string, whereas “section.add” will complain if no url is provided.

These functions will return the child that was added.

Merging children

If you do a “section.merge(another_section)”, then you will add the children from another_section onto section.

If you specify take_base=True, then it will also take the first child of another_section and put it onto section as the first child.

Note

merging always does a copy.

Adopting children

You may do a “section.adopt(other_section1, other_section2)” and it will change the parent of these children to section and add them as children of section.

If you also specify “clone=True”, then it will use section.copy to make a clone of the children before adding them as children.

You may also specify as keyword arguments consider_for_menu and include_as and these will be used when putting the child onto the section. See Section datastructure for what that means.

Copying children

Doing a “section.copy(other_section)” will make a clone of other_section and recursively merge the children of other_section onto the clone before adding the clone as a child of section.

It will also take in consider_for_menu and include_as (see Section datastructure)

Cloning children

You can use the “section.clone()” method to create a clone of the section.

It will create a new Section object with the url, name and parent of the section being cloned and then copy a clone of “section.options” onto the clone.

It will not pass on any reference or clone of the children from the original section onto the clone.

Section datastructure

The section has two attributes it uses to hold it’s children:

_base

This holds a single item. And is what the section considers as the “first” child.

_children

An array of items.

Section Item

There are three pieces of information that is required to make it easy for us to generate a menu from this information: The section itself, whether to include the section in the menu; and what to include the section as if it needs to be included as anything special.

To achieve this, each child of a section is held in an instance of cwf.sections.section.Item. This is an object that holds section, consider_for_menu and include_as.

This is so that sections can use the same sections as children but have them appear in the menu and url scheme differently depending on which parent owns them.