Hello World Example

This quick tutorial will show the steps for creating a simple, somewhat interactive "Hello World" example.

Creating the project

Assuming you have already downloaded and installed Flannel, create the helloworld project like so:

paster create -t flannel helloworld

This will create the following files and directories:

  helloworld/
    development.ini
    helloworld/
      __init__.py
      assets/
      components/
      pages/
        Home.html
      wsgimain.py
    setup.py

Running the project

From the top-level directory, you may run the project by executing:

paster serve development.ini

This will run the application using Paste's built-in web server. You may access the project by visiting http://localhost:5000/.

If you visit it now, you'll see that it already says "Hello World!" But this isn't very interesting since it's simply serving a static page. :)

Creating the Python class

Create the file helloworld/pages/Home.py and insert the following code:

from flannel import *

class Home(BaseComponent):
    count = Persistent(0)

    @on_event('mylink')
    def inc(self):
        self.count += 1

Briefly, this defines a Python class for the Home page (the default page, similar to index.html). All pages and components must derive (either directly or indirectly) from BaseComponent.

This line

    count = Persistent(0)

defines a member variable called count. It is being declared as being persistent with a default value of 0. What this means is that the value of count will be persisted through different page requests. Under the hood, it is saved into the underlying session.

This method

    @on_event('mylink')
    def inc(self):
        self.count += 1

defines an event listener for the mylink component. In the template, we're going to define a hyperlink named mylink. Event listeners are where you do application-specific things. You can see that this event listener increments count by 1.

Editing the template

Next, edit the helloworld/pages/Home.html file so it looks like the following:

<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <h1>Hello World!</h1>
    <p>You have been here ${count} times.</p>
    <p><t:comp id="mylink" type="Link">Refresh</t:comp></p>
</body>
</html>

This line

    <p>You have been here ${count} times.</p>

shows an example of variable expansion. It simply outputs the value of the count attribute in the owning page/component - in this case, the Home class defined above.

The next line

    <p><t:comp id="mylink" type="Link">Refresh</t:comp></p>

defines an embedded component. The <t:comp ...> element requires either id or type (or both) to be specified. In this case, we are saying we want to embed a Link component and name it mylink.

(If you left out the type attribute, then the Home class would be expected to have an attribute named mylink which already has an instance of the Link component. Alternatively, if you left out the id attribute, the Link instance would be assigned a name by the framework. But since the Home.inc method is expecting events from a component named mylink, this example wouldn't work.)

Running the project again

Once this is done, run the project again and visit http://localhost:5000/. Clicking on the "Refresh" link increments the counter.

And that's it!