=============
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
  >>> 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 and CodePage
=================

The Page is the specific code that you want to control. It is based on
the grokcore.view.View browser page implementation and therefore
provides a 'update' method, and a 'content' method that will return
the specific HTML code generated by the template. If you don't whish
to use a template, you can use a CodePage, in that case the 'content'
method will return the result of the 'render' that you have to
define. That last one works like grokcore.view.CodeView.

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 CodePage
  >>> class AnimalDisplay(CodePage):
  ...    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'

