Django Blog project #3: Using CSS and Template Inheritance



This is my OLD blog. I've copied this post over to my NEW blog at:

http://www.saltycrane.com/blog/2008/06/django-blog-project-3-using-css-and/

You should be redirected in 2 seconds.



Version 0.0.1 of my new blog had no style. For 0.0.2, I added a little CSS to my Django template to make it look a little better.

Create new Django templates

I created two new Django templates, base.html and frontpage.html. base.html contains all the HTML and CSS that is common to all the web pages that will be on this site. frontpage.html is the template for the front page of my new blog. It uses the object-oriented technique of extending my base.html template. It uses the boilerplate code in base.html and then fills in sections with content specific to the front page. It is similar to server side includes, but more powerful because specific content can be inserted anywhere instead of just at the beginning or end. Django does have an include mechanism which acts like server side includes, but the extension method (also called Template Inheritance) is the preferred way of doing things.


Here is the code for frontpage.html:
{% extends "base.html" %}

{% block main %}
  {% for post in post_list %}
    {{ post }}
    <hr />
  {% endfor %}

{% endblock %}
Here is the code for base.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
body {
 margin: 0;
 padding: 0;
 font-family: Georgia, Times, "Times New Roman", serif;
 color: black;
 width: 600px;
 border-right: 1px solid black;
}
#header {
 background-color: #666;
 border-bottom: 1px solid #333;
}
#sidebarLeft {
 float: left;
 width: 160px;
 margin-left: 10px;
 padding-top: 1em;
}
#mainRight {
 padding-top: 1em;
 margin: 0 2em 0 200px;
}
#footer {
 clear: both;
 background-color: #ccc;
 padding-bottom: 1em;
 border-top: 1px solid #333;
 padding-left: 200px;
}
h2.sidebar {
  font-size: 120%;
}
</style>
<title>{% block title %}Sofeng's Blog Version 0.0.2{% endblock %}</title>
</head>
<body>

<div id="header">
  <h1>Sofeng's Blog Version 0.0.2</h1>
</div>
<div id="sidebarLeft">
  {% block sidebar %}
  <h2 class="sidebar">ABOUT</h2>
  <p>This is my new blog created using <a href="http://www.djangoproject.com">Django</a>,
    a <a href="http://www.python.org">Python</a> web framework. This site is under 
    construction. My current blog is located at: 
    <a href="http://iwiwdsmi.blogspot.com">http://iwiwdsmi.blogspot.com</a>.
  </p>
  {% endblock %}
</div>
<div id="mainRight">
  {% block main %}{% endblock %}
</div>
<div id="footer">
  A <a href="http://www.djangoproject.com/">Django</a> site.
</div> 

</body>
</html>

Modify view to use new template

To use the new template, I created a new view called frontpage in ~/src/django/myblogsite/myblogapp/views.py:

from django.shortcuts import render_to_response
from myblogsite.myblogapp.models import Post

def frontpage(request):
    posts = Post.objects.all()
    post_body_list = [post.body for post in posts]
    return render_to_response('frontpage.html', 
                              {'post_list': post_body_list})
Correction 7/6/2008: I previously had from myblogapp.models import Post on the second line. This works, but is inconsistent with my urls.py below and can (and did for me) cause subtle errors in the future. I corrected the line to read: from myblogsite.myblogapp.models import Post.

Map an URL to the new view

To complete the change, I mapped the url /blog to the new frontpage view in ~/src/django/myblogsite/urls.py:

from django.conf.urls.defaults import *
from myblogsite.myblogapp.views import *

urlpatterns = patterns(
    '',
    (r'^admin/', include('django.contrib.admin.urls')),
    (r'^myview1/$', myview1),
    (r'^blog/$', frontpage),
)

Upload project to Webfaction server

I updated my previous post to include a section on installing Mercurial. Here are my steps for pushing my changes to the server. It's a little more complicated than it should be because I was mucking with the repository, but future pushes should be much easier.

$ hg pull -u --remotecmd /home/sofeng/bin/hg ssh://sofeng@sofeng.webfactional.com/webapps/django/myblogsite
sofeng@sofeng.webfactional.com's password:
pulling from ssh://sofeng@sofeng.webfactional.com/webapps/django/myblogsite
searching for changes
adding changesets
adding manifests
adding file changes
added 5 changesets with 4 changes to 5 files (+1 heads)
not updating, since new heads added
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg merge
 local changed templates/base.html which remote deleted
use (c)hanged version or (d)elete? c
3 files updated, 0 files merged, 3 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m 'commit after merge'
$ hg push --remotecmd /home/sofeng/bin/hg ssh://sofeng@sofeng.webfactional.com/webapps/django/myblogsite
sofeng@sofeng.webfactional.com's password:
pushing to ssh://sofeng@sofeng.webfactional.com/webapps/django/myblogsite
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 3 changesets with 5 changes to 6 files

Deploy

With my cleanup of the mercurial repository, I didn't have to make any file changes. I just updated the working directory of my project using hg update -C and restarted the Apache web server.

$ cd ~/webapps/django/myblogsite
$ hg update -C
5 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ ~/webapps/django/apache2/bin/restart

Now, pointing my browser at http://saltycrane.com/blog/, shows new version 0.0.2 of my blog!

Here is a snapshot screenshot of my blog version 0.0.2:


Related posts:
   Django Blog Project #1: Creating a basic blog
   Django Blog Project #2: Deploying at Webfaction
   Django Blog Project #4: Adding post metadata
   Django Blog Project #5: YUI CSS and serving static media

2 comments:

Luis said...

Hello,

How do you manage using css like this:

< link rel="stylesheet" href="css/screen.css" >

sofeng said...

luis,
you need to set up your web server to serve static media files (e.g. your css stylesheet). see my Django blog project post #5

About

This is my *OLD* blog. I've copied all of my posts and comments over to my NEW blog at:

http://www.saltycrane.com/blog/.

Please go there for my updated posts. I will leave this blog up for a short time, but eventually plan to delete it. Thanks for reading.