=================
Browser Protocols
=================

The browser protocols mimic the browser ZCML namespace directives as closely as
possible. If you want to define a page, for instance, you can simply do this in
your Python view code as follows:

    >>> import zope.interface
    >>> from bebop.protocol import browser
    
    
    >>> class ISampleContent(zope.interface.Interface):
    ...     pass
    
We can use the pages and pagetemplate class declarations and the page
method decorator as a substitute for the corresponding ZCML statements:

    >>> from zope.publisher.browser import BrowserView
    >>> class SampleView(BrowserView):
    ...     browser.pages(ISampleContent, permission='zope.View')
    ...     browser.page(name='template.html', 
    ...                             template='demo/test.pt')
    ...
    ...     # use decor
    ...     @browser.page()
    ...     def read(self):
    ...         pass
    ...     @browser.page(name=u'test.html', permission='zope.ManageContent')
    ...     def write(self):
    ...         pass
    
        
The underlying page protocol records the following ZCML directives:

    >>> print browser.pageProtocol.record()
    <configure
           xmlns:browser="http://namespaces.zope.org/browser"
          >
       <!-- GENERATED PROTOCOL. DO NOT MODIFY OR INCLUDE -->
       <browser:page
          class="bebop.protocol.browser_txt.SampleView"
          layer="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
          for="bebop.protocol.browser_txt.ISampleContent"
          permission="zope.View"
          name="template.html"
          attribute="__call__"
          template=".../demo/test.pt"
       />
       <browser:page
          class="bebop.protocol.browser_txt.SampleView"
          layer="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
          for="bebop.protocol.browser_txt.ISampleContent"
          permission="zope.View"
          name="read"
          attribute="read"
       />
       <browser:page
          class="bebop.protocol.browser_txt.SampleView"
          layer="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
          for="bebop.protocol.browser_txt.ISampleContent"
          permission="zope.ManageContent"
          name="test.html"
          attribute="write"
       />
       <browser:page
          class="bebop.protocol.demo.hello.allinone.Greeting"
          layer="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
          for="bebop.protocol.demo.hello.allinone.World"
          permission="zope.Public"
          name="greet"
          attribute="__call__"
       />
       <browser:page
          class="bop.permalink.Permalink"
          layer="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
          for="zope.interface.Interface"
          permission="zope.Public"
          name="permalink"
          attribute="__call__"
       />
    </configure>
    
Note that the browser.pages statement has no direct counterpart in the ZCML.
Its parameters are the default values for the following browser.page 
decorators which are directly mapped onto the corresponding ZCML directives.

Menus
=====

We can build a ZCML menu in Python as follows:

    >>> menu = browser.menu(id='test_menu', title=u'Test')
    >>> print browser.menuProtocol.record()
    <configure
           xmlns:browser="http://namespaces.zope.org/browser"
          >
       <!-- GENERATED PROTOCOL. DO NOT MODIFY OR INCLUDE -->
       <browser:menu
          id="test_menu"
          class="zope.app.publisher.browser.menu.BrowserMenu"
       />
    </configure>

After that we can add items to the menu:

    >>> browser.menuItem('test_menu', ISampleContent, '@@action', u'TestItem')
    >>> print browser.menuItemProtocol.record()
    <configure
           xmlns:browser="http://namespaces.zope.org/browser"
          >
       <!-- GENERATED PROTOCOL. DO NOT MODIFY OR INCLUDE -->
       <browser:menuitem
          menu="test_menu"
          for="bebop.protocol.browser_txt.ISampleContent"
          layer="zope.publisher.interfaces.browser.IDefaultBrowserLayer"
          title="TestItem"
          action="@@action"
       />
    </configure>


To Dos
======

view directives?, ressource directive?

    <meta:directive
        name="menu"
        schema=".metadirectives.IMenuDirective"
        handler=".menumeta.menuDirective"
        />

    <meta:complexDirective
        name="menuItems"
        schema=".metadirectives.IMenuItemsDirective"
        handler=".menumeta.menuItemsDirective"
        >

      <meta:subdirective
          name="menuItem"
          schema=".metadirectives.IMenuItemSubdirective"
          />

      <meta:subdirective
          name="subMenuItem"
          schema=".metadirectives.ISubMenuItemSubdirective"
          />

    </meta:complexDirective>

    <meta:directive
        name="menuItem"
        schema=".metadirectives.IMenuItemDirective"
        handler=".menumeta.menuItemDirective"
        />

    <meta:directive
        name="subMenuItem"
        schema=".metadirectives.ISubMenuItemDirective"
        handler=".menumeta.subMenuItemDirective"
        />

    <meta:directive
        name="addMenuItem"
        schema=".metadirectives.IAddMenuItemDirective"
        handler=".menumeta.addMenuItem"
        />


    <!-- browser views -->

    <meta:complexDirective
        name="view"
        schema=".metadirectives.IViewDirective"
        handler=".viewmeta.view"
        >

      <meta:subdirective
          name="page"
          schema=".metadirectives.IViewPageSubdirective"
          />

      <meta:subdirective
          name="defaultPage"
          schema=".metadirectives.IViewDefaultPageSubdirective"
          />

    </meta:complexDirective>

    <meta:directive
        name="defaultView"
        schema=".metadirectives.IDefaultViewDirective"
        handler=".metaconfigure.defaultView"
        />

