{"id":1764,"date":"2012-04-12T16:16:04","date_gmt":"2012-04-12T13:16:04","guid":{"rendered":"http:\/\/blog.railsware.com\/?p=1764"},"modified":"2021-08-16T15:56:46","modified_gmt":"2021-08-16T12:56:46","slug":"shared-mustache-templates-for-rails-3","status":"publish","type":"post","link":"https:\/\/railsware.com\/blog\/shared-mustache-templates-for-rails-3\/","title":{"rendered":"Shared Mustache Templates for Rails 3"},"content":{"rendered":"\n<p>Hello my dear friends. Today we will talk about how we share mustache templates in Rails 3.<\/p>\n\n\n\n<p>Let&#8217;s imagine that we have a task, where on first load of the page we show only 10 products. But when user scroll, we should automatically load more products on page (aka continuous pagination).<br>Of course, this task can be solved in several ways, but I want solve this task by sharing one template between Rails and JavaScript.<\/p>\n\n\n\n<p>There are many JavaScripts templates exists today &#8211; <a href=\"http:\/\/twitter.github.com\/hogan.js\/\" target=\"_blank\" rel=\"noreferrer noopener\">Hogan.js<\/a>, <a href=\"http:\/\/handlebarsjs.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Handlebars<\/a>, <a href=\"http:\/\/mustache.github.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Mustache<\/a> etc. I choose Mustache, because it&#8217;s simple and has template engine implemented on many languages (we need JavaScript and Ruby). We created a gem for such type of tasks &#8211; <a href=\"https:\/\/github.com\/railsware\/smt_rails\" target=\"_blank\" rel=\"noreferrer noopener\">smt_rails<\/a>.<br>How it works?<\/p>\n\n\n\n<p>First of all you have to add this gem to your Gemfile and start &#8216;bundle install&#8217;:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">gem 'smt_rails', git: 'git:\/\/github.com\/railsware\/smt_rails.git'\n<\/pre>\n\n\n\n<p>Next launch generator:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">rails g smt_rails:install\n<\/pre>\n\n\n\n<p>That&#8217;s all.<\/p>\n\n\n\n<p>Now you can create a directory in &#8216;app\/templates&#8217; mustache templates (these templates ends with &#8216;.mustache&#8217; by default). Let&#8217;s create partial for the product:<\/p>\n\n\n\n<p>File: &#8216;app\/templates\/products\/_product.mustache<\/p>\n\n\n\n<p>Content:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;a href=\"{{url}}\">{{title}}&lt;\/a>\n&lt;p>{{description}}&lt;\/p>\n<\/pre>\n\n\n\n<p>You can render this partial in ActiveView:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;%= render \"products\/product\", :mustache => product.as_json %> \n<\/pre>\n\n\n\n<p>And in JavaScript:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var product = \u2026 ; come from ajax call as json\nvar content = SMT['products\/product'](product);\n<\/pre>\n\n\n\n<p>So in the end you&#8217;ll have only one template, which is shared between Rails and JavaScript.<\/p>\n\n\n\n<p>Demo application with scroll pagination you can find <a href=\"http:\/\/st-rails-example.herokuapp.com\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">here<\/a><\/p>\n\n\n\n<p>Source code: <a href=\"https:\/\/github.com\/le0pard\/st_rails_example\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/le0pard\/st_rails_example<\/a><\/p>\n\n\n\n<p>That&#8217;s all folks!<\/p>\n\n\n\n<p>SMT_rails (Shared Mustache Templates for Rails)<\/p>\n\n\n\n<p>Rubygems: <a href=\"https:\/\/rubygems.org\/gems\/smt_rails\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/rubygems.org\/gems\/smt_rails<\/a><\/p>\n\n\n\n<p>Source code: <a href=\"https:\/\/github.com\/railsware\/smt_rails\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/railsware\/smt_rails<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello my dear friends. Today we will talk about how we share mustache templates in Rails 3. Let&#8217;s imagine that we have a task, where on first load of the page we show only 10 products. But when user scroll, we should automatically load more products on page (aka continuous pagination).Of course, this task can&#8230;<\/p>\n","protected":false},"author":17,"featured_media":1771,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[],"coauthors":["Alexey Vasiliev"],"class_list":["post-1764","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"aioseo_notices":[],"categories_data":[{"name":"Engineering","link":"https:\/\/railsware.com\/blog?category=development"}],"post_thumbnails":"https:\/\/railsware.com\/blog\/wp-content\/themes\/railsware\/vendors\/images\/article-thumbnail-default.jpg","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/1764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/comments?post=1764"}],"version-history":[{"count":34,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/1764\/revisions"}],"predecessor-version":[{"id":14159,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/1764\/revisions\/14159"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/media\/1771"}],"wp:attachment":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/media?parent=1764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/categories?post=1764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/tags?post=1764"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/coauthors?post=1764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}