Nounoublog Updated

Over the last few weeks this blog has changed dramatically. It looks pretty much the same as when it started but under the covers the code of the blogging platform, Nounoublog is very different. I am going to talk about three of the features that I have been working on lately:

  • Archives
  • RSS Feed
  • Admin console

And I will show a few snippets of the actual code that powers the blog.

For those that visit the blog for the first time, Nououblog is a small blogging platform developed in Google App Engine. I started working on it basically for two reasons. First, I wanted to learn how to develop applications for Google App Engine. And second, because I wanted a simple but highly customizable platform, with free hosting and no ads.

Archives

Now the blog has an archives section. It is the small set of links in the right side. It will let you view all the posts since the creation of the blog.

For example, if you click in 2009, it will show you all the posts from the previous year. In order to enable this I had to update the url structure of the blog. Now paths have the form:

http://www.javiertordable.com/blog/2010/01/30/the-eternal-night

With slashes separating the different parts of the url. And all the following are valid urls:

http://www.javiertordable.com/blog/2010/01/30/
http://www.javiertordable.com/blog/2010/01/
http://www.javiertordable.com/blog/2010/

Each one will show respectively all the posts of the day, the month, and the year. Each one has its own handler. Here is for example the handler that returns all the posts in a year:

class BlogYear(webapp.RequestHandler):
  """Request handler for all blog posts in a given year.

  This handler answers all requests for /blog/YYYY and /blog/YYYY/.
  """
  def get(self):
    # Get the year from the path.
    path = self.request.path[len('/' + config.BLOG_PREFIX + '/'):]
    (year, month, day, desired_url) = extract_url_parts(path)

    # Get the list of all posts of the year.
    posts = get_posts_in_date(year, month=None, day=None)

    # And return an archives page with the posts.
    s = pages.ArchivesPageGenerator()
    self.response.out.write(s.generate(posts, str(year)))

There are similar handlers for all the posts in a month and all the posts in a day.

RSS Feed

An RSS feed is a specially formatted XML file, which includes data about the posts in a blog. It is updated automatically by the blog, so that when it changes, RSS subscribers know that there is new content. There are applications like Google Reader that are very helpful to keep track of many RSS feeds and alerting when there is new stuff to read.

In the Nounoublog blogging platform, you can access the RSS feed by clicking in the RSS link at the top of the page. In the browser you may see only a bunch of text, but if you add this link to your Google Reader subscriptions you will see a list of the most recent posts.

Same as before the RSS feed is powered by its own handler, which is very simple:

class RssFeed(webapp.RequestHandler):
  """Handler for the RSS feed.

  This feed contains a list with all the blog posts, from last to first.
  This list is subject to the maximum item retrieval limit of the DB.
  """
  def get(self):
    # Get the list of all posts.
    posts = get_all_posts()

    # Return the xml feed with the posts.
    template_values = {'posts': posts}
    self.response.out.write(template.render(template_path("rss_feed"),
                                            template_values))

Where the template provides the XML structure of the feed, and inserts the data corresponding to the posts

<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
<channel>

<title>Javier Tordable Blog</title>
<link>http://www.javiertordable.com</link>
<description>
  Javier Tordable blog on Software, Mathematics and Technology
</description>
<generator>Nounoublog</generator>
<docs>https://code.google.com/p/nounoublog/</docs>

{# Loop over all the blog posts. #}
{% for post in posts %}
<item>
<title>{{ post.title }}</title>
<link>{{ post.absolute_url }}</link>
<pubDate>{{ post.rss_pub_date }}</pubDate>
<guid>{{ post.absolute_url }}</guid>
<description>{{ post.escaped_content }}</description>
</item>
{% endfor %}

</channel>
</rss>

Notice that in the Django template the post elements appear as attributes while in fact they are method calls. Also I use as GUID the url of the post, as it is intended to be a permanent link.

Admin console

The last item that I have been working on is the administration console. This is still work in progress, but I expect that once I am done with it I will post more often.

The admin console will have options to:

  • Add posts
  • Edit posts
  • Add static pages
  • Edit static pages
  • Edit the CSS
  • Edit redirects

All these options seem very normal with the exception of the redirects. How does it work? For example, when going to:

http://www.javiertordable.com/blog/2009-12-01/my-first-blog-post

You are redirected to another url, which appears in the url bar. Notice how the dashes are now forward slash bars

http://www.javiertordable.com/blog/2009/12/01/my-first-blog-post

I added support for redirects because I changed the site several times (including the url structure), and I didn't want to serve 404 error pages for all old urls.

Keep visiting the blog or subscribe to the RSS feed for more news on Nouonublog!