=============
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.


Getting started
---------------

First we grok this package's grokkers::

  >>> from megrok.layout import testing
  >>> import grokcore.component as grok
  >>> from grokcore.component.testing import grok_component
  >>> testing.grok('megrok.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

  >>> 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.render()
  u'Looks like an elephant'
  >>> page()
  u'a simple layout'

As we can see, the page us 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.

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

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