This is a huge post and I should have split this into several smaller ones so please bear with me while I get my series format tweaked. We last left off with Controllers, Views and Testing with a basic test, basic view and basic controller. Now with our basic scaffold built we can focus on making our views reusable, dynamic, and more pleasant to look at.
First before we dive too deeply into Mako, lets setup a default home page by doing the following:
###
Mako uses standard python mixed with HTML to display views. This gives you both a great deal of flexibility and a great deal of ability to hang yourself. So be warned, avoid putting to much logic into your view, since you can do about anything there.
Open up templatesindex.mako __replace the table rows in the table body with the following:
def test_recent_posts(self):
response = self.app.get(url(controller=‘home’, action=‘index’))
assert “ ” in response </div> </div>
jkruse New Kindle 06/24/2009
running nosetests –-with-pylons=test.init should give you two assertion failures.
now change “pylonsforumcontrollershome.py” to look like so:
from pylons import request, response, session, tmpl_context as c
from pylons.controllers.util import abort, redirect_to
from pylonsforum.lib.base import BaseController, render
log = logging.getLogger(__name__)
class Post(object):
def __init__(self, author, subject, dateadded):
self.author = author
self.subject = subject
self.dateadded = dateadded
class HomeController(BaseController):
def index(self):
c.username = “rsvihla”
c.posts = [Post(“jkruse”, “New Kindle”, “06/24/2009”)]
return render(‘index.mako’) </div> </div>
We’ve added a Post class with basic attributes and placed them in an array in the c.posts variable, also we’ve hardcoded the username “rsvihla”. I know the more experience developers here are cringing at my awful little Post class, don’t worry its a just a place holder and will be removed later. The point here is building functionality in steps with test coverage. Now run nosetests just as before and you should have all tests passing. For bonus measure refresh http://127.0.0.1:5000 .
We’ve built a very basic page now, but suppose we want to build several and have some bits of information show up over and over again, like user name or menu structure.
create a base template named “base.mako” in the templates directory that has the following in it:
<div id=“header”>Pylons Forum</div>
<div id=“sidebar”>
username: ${user.get_current_user()}
</div>
<div id=“content” >
${self.body()}
</div>
</div>
</body>
</html> </div> </div>
Most everything is standard HTML so lets restrict this to the interesting bits:
The namespace directive here is basically doing an import of a custom module and giving it an alias of user. This is no different than in normal python code typing:
This is used later in the div sidebar by pulling the current user from my customer users module:
the module source only contains a simple hard coded value for now so in pylonsforummodel make a users.py file with only the following:
Now onto the next non-HTML tidbits
Everyone of the above methods establishes a base method that the child templates must now call with the exception of self.body (which is called when the templates actually render the content anyway). So lets adjust “index.mako” template to the following: