Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja2, Backbone.js and progressive enhancement

I have a working website build on top of Google App Engine (Python + Jinja2 template engine). I would like to start redesigning it to be single page application using Backbone.js and Underscore.js. The goal is to use progressive enhancement strategy.

The site will still be rendered using backend on the first visit. And then if the browser supports JavaScript the Backbone.js will take over.

I decided to do it this way for two reasons. First all the links I already have will stay intact and second the Google indexing bot will be able to crawl the site content.

I have two problems with this approach:

  1. I need to have two templates for almost everything on my site one on the backend (Jinja2) and one on the frontend (Underscore.js). I was wondering what are the best practices in cases like this? Is there anything you can suggest to avoid having two templates for everything?

  2. How do I load the templates for the frontend to use Backbone.js + Underscore.js? I can load them all in the initial request or request them asynchronously when they are needed.

I appreciate any thoughts! Thanks.

Some resources:

http://ricostacruz.com/backbone-patterns/

This one describes how to bind Backbone.js to existing HTML: http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-2-progressive-enhancement-with-backbone-js/

like image 758
rzajac Avatar asked Dec 29 '12 11:12

rzajac


Video Answer


1 Answers

So I recently(this year) went through a similar situation. I'll let you know a head of time that #1 is an incredibly tough thing to deal with. Keep in mind, that you not only would have to duplicate your templates, but ALL business logic surrounding your site. For example, let's say you allow users to add comments on a particular page. Using the method you described, you would have to both have a comment template on the server-side and the client-side, and additionally, duplicate the logic required to add/delete/edit a comment on both the client and the server(to accommodate users with and without javascript). Duplication of the templates is easy using Jinja2 function blocks, but the duplication of the logic is where it gets interesting. I attempted to do just that, and ended up doing a full re-write a few months later.

So the advice I would give to you is ditch the idea that you can support both javascript and non-javascript users. Make your site for one or the other. I personally chose to go the javascript route myself. This leaves you with two options. Make a single page app, or make an app that largely leverages javascript for functionality, but renders everything server-side. There are probably a number of other options, but those are the two most popular that I have seen. I went with the second option. So what I do, is the initial page load is done by the server. Backbone.js then consumes each element and makes models and views out of them. This is largely done leveraging data attributes. So for example to create a comment view I would have an element like this:

<div class="comment" data-id="1" data-body="You Suck"></div>

I would then consume said comment, and create a model out of it like so:

var CommentModel = Backbone.Model.extend();

var comment_el = $('.comment');
var comment_model = new CommentModel($(comment_el).data());

Finally, I would back a view with that created model, which can then add functionality to the site:

var CommentView = Backbone.View.extend({
    initialize: function() {},
    edit: function() {},
    delete: function() {}
});

var comment_view = new CommentView({
    model: comment_model
});

Then you might be asking, "What if I need to re-render something, don't I need client-side templates for that?" Nope. Client-side templates are a pretty new thing. I personally try to avoid them as I don't think we're quite there yet, and I have always felt that single-page apps are just not responsive enough for my tastes. I'm sure there are plenty of people who would disagree with me on that, but that's the stance I took with my most recent project. So that being said, I render everything on the server and send the html to the client in the form of JSON, which I then inject into the DOM. So I have a ton of api endpoints, which return JSON to my Backbone.js code. This is what is currently working out for me, but this problem is largely situational usually. You have to really look at what your needs are. For it's worth, I largely based my current system off of what Twitter eventually decided to do after trying the whole single-page app thing. You can read about it here.

like image 198
JayD3e Avatar answered Oct 08 '22 11:10

JayD3e