PushState navigation and title issues
Hi guys,
For http://bustram-angers.fr/ (written in RoR) I had a couple of issues to deal with Backbone and pushState.
Parenthesis, if you don't know about ghost views, check this post : http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/
So, here is the issue : if you hit http://bustram-angers.fr/ and then click on the "Récents" tab, the content will be the same as if you did directly type the URL in your browser, but the title didn't change.
I found out a little trick to fix that. Basically, I have a different template for "regular" and "pushState" requests.
When I load a new page, it's not just the HTML content but a JSON object passing the content, the title and the description.
app/controllers/application_controller.rb
layout :get_layout
protected
def get_layout
request.xhr? ? params[:includeContext] == "true" ? "ajax" : nil : "application"
end
I have to explicitly pass "includeContext=true" when I load a new page to avoid interfering with other AJAX requests.
app/helpers/application_helper.rb
def title(page_title)
content_for :title, page_title.to_s
end
def description(description)
content_for :description, description.to_s
end
app/views/layouts/ajax.html.erb
{
"content": "<%= yield.gsub("\n", " ").gsub("\"", "\\\"").html_safe %>",
"description": "<%= yield :description %>",
"title": "<%= content_for?(:title) ? yield(:title) + " - " : "" %>Horaires Bus-Tram Angers"
}
Don't forget to escape double quotes and remove line returns. Otherwise, your JSON will be incorrect.
On the JS side, here is my loading function :
$.get(url, {includeContext: true}, function(data) {
var jsonData = JSON.parse(data);
_this.$el.html(jsonData.content);
document.title = jsonData.title;
$('meta[name=description]').attr("content", jsonData.description);
});
And that's it ! Here is what a view looks like :
<% title @stop.name %>
<% description "Prochains passages bus tram pour l'arrêt #{@stop.name} (#{@stop.city_name})." %>
<article id="showStop" class="stop">
[...]
Written by Emmanuel Bourgerie
Related protips
2 Responses
Instead of having 2 separate templates can you just embed those metadata into the rendered HTML itself?
I could, but then I would have to go through the DOM, take the content element, the title and the description (which is what does turbolinks if I'm correct).
It just doesn't feel right to me.