Deploying my first web app with a backend

For the first half of my web apps class, I worked on a Twitter-like social network. It’s deployed on Heroku using Heroku’s free deployment plan. The application is implemented in Django.

Example post on Nanoblog
Example post on Nanoblog

I learned a couple incredibly useful things from this project, in addition to the benefits of the Django framework:

HTML Templating in response to AJAX Requests

This project was my first experience with HTML templating. To produce a dynamic web page, you can register a function with Django to handle a particular web request. Within that function, you can define a context dictionary of variables, such as user and posts. Then you can simply use the render(html_file, context) shortcut to produce a dynamic page. The HTML file can include template syntax like {% for post in posts %} to include the same markup for each post in a list of posts, and <a href="{% url 'user' %}"> to include a link to the profile page of a post’s creator.

Before this project, I exclusively used static HTML pages and included dynamic content using JavaScript and AJAX. AJAX, especially with JQuery, makes it easy to make “function calls” to the server: JavaScript code can make an asynchronous HTTP GET or POST request to the server, with parameters, and receive a “return value” as a JSON file in a callback function. Within the callback function, the page’s DOM can be updated with the returned data values. This typically involves JQuery code that iterates through the data and formats new DOM elements, such as table cells, lists and images.

One of the requirements for the project is that, if a user is looking at a stream of blog posts and another user adds a new post, the post should appear at the top of the first user’s page pseudo-immediately without a page refresh. The best way to implement this is to make an AJAX request to the server every few seconds asking for new posts. Before I learned about HTML templating, I would have implemented this how I just described: request new posts’ data from as JSON and use JQuery to update the page. However, such JQuery code is cumbersome and necessarily implements the same logic as the template code that is used to generate the posts on original page (assuming we want new posts to look the same as old posts.) Duplicating the DOM logic in Python and JQuery is problematic because it is bug-prone and takes twice as long to change.

Now that I’ve learned about templating, I wrote the server code to return new blog posts using the render shortcut I mentioned above. My old style would return a JSON file with data that looks like this:

{success: true, new_posts: [{id: 3, text: "hello", creator: {id: 7, name: "chris", profile_picture: "http://..."}, ...}, ...]}

The JavaScript callback would then mangle the data into DOM elements before updating the page. Using HTML templating on the server, I instead return a JSON file with all of the markup formatting done:

{success: true, new_posts: '<li><div class="blog-post"><img src="...">post by <a href="...">chris</a>: ...</div></li>...'}

The client code becomes much simpler; it just needs to insert the HTML into the right place on the page. This method also has the huge advantage of using the same HTML template that is used to generate the original page. That is, when a user first loads the page the HTML template looks something like this:

{% include 'header.html' %}
{% include 'blog_posts.html' %}

When the server responds to an AJAX request and has new blog posts to return, it returns something like:

HTTPResponse(json.dumps({success: true, new_posts: render_to_string('blog_posts.html', {posts: new_posts})}))

This method is more maintainable, less error-prone, and more modularized. I saved a lot of debugging time by keeping the code to generate the view in one place.

CSS Libraries

I got a lot of compliments on my UI but I only wrote 30 lines of CSS, and it was mainly just to position profile pictures. I did everything else by adding Materialize CSS classes to my HTML elements. On other sites I made before this project, I spent a lot of time wrestling with the quirks of CSS to try to get my elements positioned smoothly. I spent very little time on styling for this app, after I figured out Materialize’s card paradigm. Admittedly, there are significant limits on what you can do with Materialize and if I wanted to do something more complex I would need to do it manually, but for this project it was an effective way to give a minimal, uniform look and feel to my site.

Leave a Reply

Your email address will not be published. Required fields are marked *