The best way for Google and friends to crawl and index a page is by finding static content. With applications that make heavy use of libraries like Backbone, Sproutcore or ember.js a lot of the content can be rendered in the browser. This can constitute a serious problem since the support methods from Google et. al. for alternative crawling coem with no guarantees.
We recently ran into this problem and came up with a neet solution where the client side templates can also be rendered server side.
There are two parts to the implementation. First, a method that can take a jade partial and its local variables, compile and evaluate it. Second, a view that calls out to that method and provides the template and the necessary local variables.
Part 1, the application_helper.rb
require 'tilt-jade/jade_js'
module ApplicationHelper
def html_from_jade_template(partial, options={})
data = File.open(
Rails.root.join("app", "assets", "templates", "#{partial}.js.jst.jade"
))
compiled = JadeJs.compile(data, locals: {}, client: true, compileDebug: false)
raw(JadeJs::Source.context.eval("(#{compiled})(#{options[:locals].to_json},
jade.runtime.attrs, jade.runtime.escape, jade.runtime.rethrow,
jade.runtime.merge)"
))
end
end
The method is pretty straight forward, it loads the template from the assets/template directory, compiles it and then evals it with the provided locals. The output is raw html that can be included in your view.
Part 2, a view that requests the compiled and eval’d templates from the server
- body = "This content comes from the server. Remove the param from the url or toggle
with the link in the upper right."
#menu
= html_from_jade_template("home/menu", locals: {items: [{title: "Server"},
{title: "Side"}, {title: "Rendered"}]})
#content
= html_from_jade_template("home/content", locals: {body: body })
Here the main thing is the call to the method in application helper that will produce the raw html given a template name and the necessary local variables.
That is pretty much it. It may take a little bit to figure out the requirements for the local variables in your template, especially since jade is very strict about them. If it can’t find one it will not compile.
I’ve put an example app on github with the complete source code for this post.
About the Author