=============
megrok.layout
=============

The `megrok.layout` package provides a simple way to write view
components which can be included into a defined layout. It turns
around two main components : the Page and the Layout.

Layout
======

The layout is a component allowing you to design your site. Often,
it's the common structure shared between all the pages. Technically,
it is a class based on the view components interface, providing a
'render' and 'update' method.

Let's implement a simple Layout:

  >>> from megrok.layout import Layout
  >>> from zope.interface import Interface
  >>> import grokcore.component as grok

  >>> class MyLayout(Layout):
  ...     grok.name('mylayout')
  ...     grok.context(Interface)
  ...
  ...     def render(self):
  ...         return u"a simple layout"

We grok our component:

  >>> grok_component('MyLayout', MyLayout)
  True

We check it has been correctly registered:

  >>> from megrok.layout import ILayout
  >>> from zope.component import getMultiAdapter
  >>> from zope.publisher.browser import TestRequest

  >>> layout = getMultiAdapter((TestRequest(), Interface), ILayout)
  >>> isinstance(layout, MyLayout)
  True
  >>> layout.render()
  u'a simple layout'

Now let's see how to use this Layout in a specific context using a Page.


Page
====

The page is the specific code that you want to control. It is based on
the grokcore.View browser page implementation and therefore provides a
``render`` and ``update`` method. The ``render`` method will simply
return the specific HTML code generated by the template or the
``render`` method code while ``__call__`` will lookup for a Layout
component and renders itself inside it.

First, we'll create 2 models that will serve as exemples.

  >>> class Aurochs(grok.Context):
  ...    description = u'Looks like a bull'

  >>> class Mammoth(grok.Context):
  ...    description = u'Looks like an elephant'

Let's create now a page that will display their description.

  >>> from megrok.layout import Page
  >>> class AnimalDisplay(Page):
  ...    grok.name('display')
  ... 	 grok.context(Interface)
  ...
  ...    def render(self):
  ...        return self.context.description

Grokking our Page will let us use it.

  >>> grok_component('AnimalDisplay', AnimalDisplay)
  True
  >>> wooly = Mammoth()
  >>> page = getMultiAdapter((wooly, TestRequest()), name='display')
  >>> page.content()
  u'Looks like an elephant'
  >>> page()
  u'a simple layout'

As we can see, the page is using the layout, on the __call__ to
render. Of course, this example Layout doesn't provide any interesting
feature. Let's create something more interesting, by using our page
with the help of the 'content' method:

  >>> class MammothLayout(Layout):
  ...     grok.context(Mammoth)
  ...
  ...	  def render(self):
  ...	      return u'Header. Page: %s. Footer' % self.view.content()

  >>> grok_component('MammothLayout', MammothLayout)
  True
  >>> page()
  u'Header. Page: Looks like an elephant. Footer'


Forms
=====

You have as well a Form, AddForm, EditForm and DisplayForm availables,
which are all aware of Layout components like Page does.
