Personal tools

Adding a layer

The layer we add will allow us to override and extend views in the default view.
As an example application we're going to develop a very simple site that uses macros and then later add a layer dedicated for mobile phone browsing without having to put in "if" statements in your templates to accommodate for the differences you'll want to apply.
Page 2 of 4.

NOTE: This has changed somewhat since grok 0.14. Defining a separate skin class with grok.Skin is no longer necessary. Take a look at:

A very common pattern when adding a mobile front end to your web application is to write a different layout more suitable for small mobile phone screens with slow connections and secondly go in and explicitly customize some important pages such that the functionality is more suitable for mobile phones. So that's what we'll do.

The first thing to do is to create a layer we'll call mobile so reopen the file and add the following code:

from zope.publisher.interfaces.browser import IDefaultBrowserLayer

class MobileLayer(IDefaultBrowserLayer):

class MobileSkin(grok.Skin):'mobile')

That's all you need! Now, to actually use this layer we'll need another view that "overrides" the view called HeaderFooter so we'll add that to the end of the file

class MobileHeaderFooter(grok.View):'headerfooter') # overriding name

Now we need to actually write the macro that we'll use specifically for mobile phones. (Remember, there are many more ways this can be fine tuned and improved):

<metal:block define-macro="standard"
><?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC
  "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
<html xmlns="">
  <title>Web page (Mobile)</title>
  <meta http-equiv="Content-Type"
      content="text/html; charset=utf-8" />
  <link rel="stylesheet" type="text/css"
        tal:attributes="href static/style.css" />
  <link rel="stylesheet" type="text/css"
        tal:attributes="href static/mobile.css" />
<metal:block define-slot="body">
<div id="header">
  <metal:block define-slot="header">
    <h2>Web page</h2>
    <hr />

<div id="content">
  <metal:block define-slot="content">
    walk all over me

<div id="footer">
  <metal:block define-slot="footer">
    <p>&copy; Grok.<br />
    You are currently using the mobile version of this page.
    <a tal:attributes="href python:view.url().replace('++skin++mobile/','')"
      >Switch to normal web version</a>


As you can see it's not very different but it's a good start when you start perfecting it. Let's also, for the sake of the exercise, override the index view as well as an example. First define it inside

class MobileIndex(grok.View):'index')

And following this we of course need the page template to go with it so add

<html metal:use-macro="context/@@headerfooter/macros/standard">
<div metal:fill-slot="content">
  <h2>Mobile Web page</h2>

  <p>Now with mobile specific front end.</p>


Restart Zope and try reaching the new mobile layer on <http://localhost:8080/++skins++mobile/app> and <http://localhost:8080/++skins++mobile/app/about>.


Skins restructuring

Posted by Sylvain Boureliou at Oct 03, 2009 11:11 AM
Since Grok 0.14, grok.Skin baseclass is removed in favour of a directive that can be used on layer interfaces.

So in this how-to, the MobileSkin class must be removed and the new layer must be:

    class MobileLayer(IDefaultBrowserLayer):'mobile')

The URL to the new skin is http://localhost:8080/++skin++mobile/app