Latest Version: 0.9.6.2

Warning

This documentation does not refer to the most recent version of Pylons. Current Documentation

Getting Started

Creating a Pylons Project

Pylons uses Paste to create and deploy projects as well as create new controllers and their tests.

Create a new project named helloworld with this command:

paster create --template=pylons helloworld

Windows users might have to use a slightly longer version using the appropriate path to their Scripts directory:

python "C:\Python24\Scripts\paster" create --template=pylons helloworld

This creates a template pylons project which you can use as a basis for your own project. The directory structure is as follows:

-helloworld

    - helloworld
    - helloworld.egg-info
    - development.ini
    - setup.cfg
    - setup.py

The setup.py file is used to create a re-distributable Python package of your project called an egg. Eggs can be thought of as similar to .jar files in Java. setup.cfg and the helloworld.egg-info directory contain extra information to configure how the egg is produced. Distributing and deploying your egg file is covered in the Deployment docs.

The helloworld directory within the helloworld directory is where all your application specific code and files are placed. This directory looks like:

-helloworld
  • helloworld
    • components
    • config
    • controllers
    • docs
    • i18n
    • lib
    • public
    • tests
    • templates
    • __init__.py
    • model.py
    • websetup.py

The components directory is for Myghty components that you want available in your Myghty templates.

The config directory contains the configuration options for your web application.

The controllers directory is where your application controllers are written. Controllers are the core of your application where most of your code will be written.

The docs directory is where you can write documentation for your project. You can then turn it into HTML using the command setup.py pudge. # XXX currently a problem in lib.base.py when this command is run but project documentation is generated fine.

The i18n directory is where your message catalogues are stored to support multiple languages.

The lib directory is where you can put code that is used between different controllers, third party code, or any other code that doesn't fit in well elsewhere.

The public directory is where you put all your HTML, image, javascript, css and other static files. It is similar to your htdocs directory in Apache.

The tests directroy is where you can put controller and other tests. The controller testing functionality uses TestGears.

The templates directory is where templates are stored. Templates contain a mixture of plain text and Python code and are used for creating HTML and other documents in a way that is easy for designers to tweak without them needing to see all the code that goes on behind the scenes. Pylons uses Myghty templates by default but also supports Cheetah, Kid and others through a system called Buffet.

The __init__.py file is present so that the helloworld directory can be used as a Python module within the egg.

The model.py file is for SQLObject classes should you choose to use SQLObject as your database object mapper. SQLObject classes defined in model.py will be loaded and present as model.YourClass inside your controllers. The database configuration string can be set in your development.ini file.

The websetup.py should contain any code that should be executed when an end user of your application runs the paster setup-app command.

You may also notice the Myghty cache directory which is created the first time you run the code.

Testing the template project

We can test the template project like this:

cd helloworld
paster serve --reload development.ini

Again Windows users may need a slightly longer version of the command last command with the path to their Scripts directory:

python "C:\Python24\Scripts\paster" serve  --reload development.ini

The --reload option ensures that the server is automatically reloaded if you make any changes to Python files or the development.ini config file. This is very useful during development.

If you visit http://localhost:5000/ you will see the welcome page.

The command paster serve development.ini loads our project server configuration file in development.ini and responds appropriately.

Try creating a new file named test.html in the helloworld/public directory with the following content:

<html>
<body>
Hello World!
</body>
</html>

If you visit http://localhost:5000/test.html you will see the message Hello World!. Any files in the public directory are served in the same way they would be by any webserver and if Pylons has a choice of whether to serve a file from the public directory or from code in a controller it will always choose the file in public.

Warning: If pylons doesn't appear to be serving the correct content check that it is not because there is a file in the public directory which is being served first.

Enabling Debugging

If you are developing an application you will want to enable the interactive debugging but it is disabled by default so that you don't accidentally use it on a production site. If you accidentally left debugging on, if an error occured the visitor would be able to execute malicious code.

Enable debugging by commenting out the line that looks like this in the [app:main] section of your development.ini file:

set debug = false

so that it looks like this:

# set debug = false

Now if an error occurs you will be able to interactively debug it.

Creating a Controller and modifying the Routes

You're now ready to start creating your own web application. First, lets create a basic hello World controller:

paster controller hello

This paster command will create the controllers/hello.py file for you with a basic layout as well as a helloworld/tests/functional/test_hello.py that is used for running functional tests of the controller.

Here's what a basic controller looks like to print out 'Hello World' and respond to http://localhost:5000/hello. Put the following text in the file helloworld/controllers/hello.py:

from helloworld.lib.base import *

class HelloController(BaseController):
    def index(self):
        m.write('hello world')

Pylons uses a powerful and flexible system for routing URLs to the appropriate piece of code and back.

We would like the hello controller to also be displayed for both the URL http://localhost:5000/hello and the URL http://localhost:5000/ which is the site route. We modify the ROUTES CONFIG in helloworld/config/routing.py like this:

# ROUTES CONFIG
map = Mapper(directory=root_path+'/controllers')

map.connect(':controller/:action/:id')
map.connect('', controller='hello', action='index')

This means that route mapper looks for URLs in the form controller/action/id but that if id, action or controller are not specified the defaults in the last line are used.

Since we have made changes to our routes we must restart the server. If you are using the --reload option this will happen automatically, otherwise close the old server and start it again using the same command as before. (Note: Controller and template changes do not require restarting the server even without the --reload option.)

Visit both http://localhost:5000/hello and http://localhost:5000/ and you will find that although the first URL produces the expected Hello World, the second URL produces the welcome page as before. This is because, as mentioned earlier, static files in the public directory are served before looking for code.

Delete the file public/index.html and the application works as expected.

More information on routes can be found in the Routes manual.

Using a template

Here's an example template, using Myghty, that prints some request information.

Create a template file helloworld/templates/serverinfo.myt containing the following:

<p>Hi, here's the server environment: <br />
<% str(request.environ) %></p>

<p>
and here's the URL you called: <% h.url_for() %>
</p>

To use this template you will need to add a new method to your HelloController in helloworld/controllers/hello.py. Add the following function to the end of the class:

def serverinfo(self):
    m.subexec('/serverinfo.myt')

The m.subexec('/serverinfo.myt') function will call Myghty to render your template.

If your server is still running you can view the page at: http://localhost:5000/hello/serverinfo

If not simply restart the server with paster serve --reload development.ini from the helloworld directory.

Controller variables and Template Globals

Pylons Globals

For convenience, there are several globals (imported from lib.base) available for use in your controllers:

session
Acts as a dict to store session data, see the Myghty Session docs for usage details
request
The current HTTP request object, corresponds to the r object from Myghty. This object contains common methods to access request information like request.method, request.headers_in and request.headers_out.
m
m is the Myghty object, described in detail in the Myghty docs. Used primarily for template rendering, and caching functionality.
h
h is the point at which all the Pylons helper functions are utilized from. By default Pylons will load all the helper functions available from the Web Helpers package. Keep in mind when reading the WebHelpers docs that all the functions listed should be prefixed by h. under Pylons as we use namespaces to keep them organized.
c
(described in Passing Variables to Templates)
g
(described in Application Global Variables)

Passing Variables to Templates

Pylons controllers are created for each request. This means you can attach variables to self if you want them passed around. However, it can be very inconvenient to keep track of all the variables and methods attached to self, especially if you want to pass them to a template.

To make it easier to set up your data for use by the template, the variable c is made available and is also available in all Myghty templates as the c global. Let's take a look at using it:

def serverinfo(self):
    c.value = 2
    m.subexec('/serverinfo.myt')

and modify the serverinfo.myt file in the templates directory to look like this:

<p>The value of <tt>c.value</tt> is:
<% c.value %>

You should see 2 printed out on the page. If you ask for an attribute on c that does not exist, rather than throwing an Attribute error an empty string will be returned. This makes it easy to toggle behavior depending on the response. For example:

<p>Hi there <% c.name or c.full_name or "Joe Smith" %>

There is one rule though, attributes of c must not start with an _ character so c.value = 1 is fine but c._value = 1 is not. This is because c has some slightly complicated code which you could accidentally damage if you assigned a variable starting with _. With this rule in place c is very robust.

The c global is also reset on each request so that you don't need to worry about a controller still having old values set from a previous request.

Application Globals and Persistent Objects

There are occasions where you might want information to be available to all controllers and not to be reset on each request. For example you might want a database connection that is made when the application is loaded, is available on all requests and is closed when the application exits or the server is stopped. You can do this through the g variable.

The g variable is an instance of your Globals class in your application's lib/app-globals.py file. Any class attributes you set in the __init__() method will be available as attributes of g throughout your Pylons application. Any attributes you set on g during one request will remain changed for all the other requests. You have to be very careful of setting global variables in requests.

Here is an example of using the g variable. First modify your lib/app_globals.py Globals class so that the __init__.py method looks like this:

def __init__(self, defaults, app, **extra):
    self.message = 'Hello'

Then add this new method to the end of the helloworld/controllers/hello.py:

def app_globals_test(self):
if g.message == 'Hello':
m.write(g.message) g.message = 'Hello World!'
else:
m.write(g.message)

This time if you run the server and visit http://localhost:5000/hello/app_globals_test/ you should see the message Hello. If you visit the page again the message will be changed to Hello World! and it will remain changed for all subsequent requests because the application global variable was modified on the first request.

The __init__() method takes the parameters global_conf and app_conf which are the values of the global_conf and application configuration variables specified in the development.ini file. This means you can set global variables based on configuration options. Note that you do not have access to m, r, h or other variables when adding application globals since they are setup before a request is ever made.

You can add code to the __del__() method to be run when the application exits.

Top