Killer Web Development

by Marco Laspe

5.4 Getting slightly more dynamic

In this section we will add the address to the links web2py-style and we will divide the dynamic the static parts of our homepage to create a consistent layout for the whole tukker app.

In the footer section of the index.html view, add the following web2py helper to the links in the footer:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
...
<
footer class="container">
<
nav class="sixteen columns alpha omega">
<
a href="{{=URL(c="default",f="about")}}">About</a>
·
<a href="{{=URL(c="default",f="terms")}}">Terms</a>
·
<a href="{{=URL(c="default",f="contact")}}">Contact</a>
</
nav>
</
footer>
...

We can do the same procedure with the main menu:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
...
<
nav>
<
ul class="sf-menu">
<
li><a href="{{=URL(c="default",f="index")}}">Home</a></li>
<
li><a href="{{=URL(c="default",f="help")}}">Help</a></li>
<
li><a href="{{=URL(c="default",f="user", args="login")}}">Login</a></li>
<
li><a href="{{=URL(c="default",f="privacy")}}">Privacy</a></li>
</
ul>
</
nav>
...

lastly we add the right URL to the href attribute of the button:

1.
2.
3.
...
<
a id="register-button" href="{{=URL(c="default",f="user",args="register")}}" class="button">Register</a>
...

What does the {{=URL(c="default",f="user", args="register")}} statement do?

  • the double curly braces open Python code
  • the equal sign (=) makes sure that the result of the Python statement gets filled in the page - don't forget this!
  • the URL helper creates an URL based on the parameters provided. This way the same code can be used on different domains, without breaking the link. In this case:
    • c="default" - the controller (c) is default
    • f="contact" - the function (f) in this controller is user
    • args="register" - one argument ('args') is register, which is computed by the function user

Maybe you remember this graphic from chapter 3.

URL dipatching web2py

You find more in depth explanation of the URL() function in the web2py-book.

Dividing dynamic and static parts

If you look at the sketches from chapter 4, you will see that a lot of the stuff on the different pages stays the same.

If we look at the sketch of the Home Page, we can mark the parts that change and which stay the same:

dynamic vs static parts of the tukker app

  • the logo and the footer links stay always the same
  • the menu on the top right slightly changes based on different states (e.g. if the user is logged in or not)
  • the main content in the middle always changes - this is where the money is.

Now it doesn't make sense to repeat ourself on every page, even if the content doesn't change.

Therefore web2py follows the DRY (= Don't repeat yourself!') paradigm. In the views that means we can split up the parts that change and the parts that don't.

  1. Copy the file views/default/index.html to views/layout.html:

    1.
    $ cp views/default/index.html views/layout.html
  2. Open views/layout.html and replace the part inside <div class="main"> with {{include}}:

    1.
    2.
    3.
    4.
    5.
    ...
    <
    section id="main" class="container">
    {{
    include}}
    </section>
    ...
  3. Reduce views/default/index.html to only the dynamic part and put {{extend 'layout.html'}} at the top:

    1.
    2.
    3.
    4.
    5.
    6.
    7.
    8.
    9.
    {{extend 'layout.html'}}
    <div class="six columns alpha">
    <h1>Messages With 300 Chars</h1>
    <p>Welcome to <strong>Tukker.Me</strong>, the new way to
    tell your friends and the world what you are thinking.</p>
    </div>
    <div class="ten columns omega">
    <a id="register-button" href="{{=URL(c="default",f="user",args="register")}}" class="button">Register</a>
    </div>

    If you refresh your browser, the homepage should look the, the about and the privacy page should still look like before.

  4. Add the "semi" dynamic parts like:

    • the title
    • the status message
    • the main menu

    First we have to change code on 3 different spots in the views/layout.html file:

    1.
    2.
    3.
    4.
    5.
    6.
    7.
    8.
    9.
    10.
    11.
    12.
    13.
    <!DOCTYPE html>
    <
    html>
    <
    head>
    <
    title>{{=response.title or request.application}}</title>
    ...
    <nav>
    {{=MENU(response.menu, _class='sf-menu')}}
    </nav>
    </div>
    </header>
    <section id="main" class="container">
    <div class="flash">{{=response.flash or ''}}</div>
    ...

    then we have to change content of the file models/menu.py to:

    1.
    2.
    3.
    4.
    5.
    6.
    7.
    8.
    9.
    10.
    11.
    12.
    13.
    # -*- coding: utf-8 -*-
    response.title = 'Microposts On Steroids'

    #########################################################################
    ## this is the main application menu add/remove items as required
    #########################################################################

    response.menu = [
    (
    T('Home'), False, URL('default','index'), []),
    (
    T('Help'), False, URL('default','help'), []),
    (
    T('Login'), False, URL('default','user', 'login'), []),
    (
    T('Privacy'), False, URL('default','privacy'), []),
    ]

    Now we have nice defaults to work with and are can change the menu and the title if we want to. For example we can add the following line to our index function in controllers/default.py and you will some message saying *Welcome to Tukker.Me.:

    1.
    2.
    3.
    def index():
    response.flash = "Welcome to Tukker.Me."
    return dict()

If you reload the homepage, you should see the welcome message.

That's it. Our basic layout is finished. It won't win any awards in the web design community, but it will work for the tukker app.

Top-Down vs. Bottom-Up

We build the layout with a bottom-up approach. That is one way to build layouts with web2py. The alternative would be a top-down approach, where you take the layout of the scaffolding application (every new web2py application starts as the welcome application) and change it until you have the look you have in mind. In certain situations, the bottom up approach will be faster - especially if you only want to some slight modifications of the standard theme.

The advantages of the top-down method is, that you won't forget certain features that can be used with web2py and you will always have a solid foundation to build on.

Why did we choose a bottom-up approach?

We chose the bottom-up approach for two reasons:

  1. For the sake of learning: From a didactic standpoint it's a much better learning experience to build something bit by bit.
  2. Often you will get finished HTML templates, that you have to translate them to work with web2py. I think this is much easier, if you know how to build a web2py design from scratch.

Books often read by web2py and Python experts:

Comments

Leave a Reply

Required fields are marked *.