I'm building a website using AngularJS and Rails. The HTML files that I'm using for templates are stored under /app/assets/templates and each time I update a route or change something inside of a nested partial inside of a template I need to "touch" the highest level file in the /app/assets/templates directory for the html file I'm changing.
So if I have a page "edit.html" which loads a partial "_form.html" then whenever I update a route or change something in _form.html I need to make sure that edit.html is touched.
This is annoying and very finicky. Is there any way to inform the asset pipeline/sprockets to avoid caching for the app/assets/templates directory?
You can try gem js_assets
(https://github.com/kavkaz/js_assets).
This allows you to function asset_path
in javascript code that emulates a similar method of sprockets.
The best solution I've found to this is not to use the asset pipeline for HTML template files.
Instead make a controller called TemplatesController
and create only one action.
Then map all template URLs to that using a route such as:
get /templates/:path.html => 'templates#page', :constraints => { :path => /.+/ }
Then move all the template files into app/views/templates
Then inside the controller, setup the following:
caches_page :page
def page
@path = params[:path]
render :template => 'templates/' + @path, :layout => nil
end
This way all of your template files will be served from the controller and then will be cached into public/templates. To avoid cache problems, you can create a timestamp path into the template route so that your cached files are delivered with a version:
get '/templates/:timestamp/:path.html' => 'templates#page', :constraints => { :path => /.+/ }
This way you can have a new timestamp each time you upload the website and you can store the templates folder anywhere you like. You can even store the templates folder on S3 and have an assets URL for that. Then wherever your template files are addressed, you can use a custom asset method:
templateUrl : <%= custom_asset_template_url('some/file.html') %>
Where:
def custom_asset_template_url(path)
"http://custom-asset-server.website.com/templates/#{$some_global_timestamp}/#{path}"
end
Then just make the asset redirect to the Rails server if it's not found and it will be generated. Or all template files can be pre-generated once uploaded.
There's a much (much!) better way to deal with this.
<%= path_to_asset("template_name.html") %>
That will return a fully working file from the asset pipeline, which can use ERB, etc. It's undocumented, but it's a part of sprockets / the asset pipeline.
To my mind, several things are needed here:
Here's a possible solution using a Rails concern:
# Allows static content to be served from the templates
# directory of a controller
module HasTemplates
extend ActiveSupport::Concern
included do
# Prepend the filter
prepend_before_filter :template_filter, only: [:templates]
# Let's cache the action
caches_action :templates, :cache_path => Proc.new {|c| c.request.url }
end
# required to prevent route from baulking
def templates;end
# Catch all template requests and handle before any filters
def template_filter
render "/#{params[:controller]}/templates/#{params[:template]}", layout: 'blank'
rescue ActionView::MissingTemplate
not_found layout: 'blank'
false
end
end
Notice we are returning the template in a prepended filter. This allows us to return the static content without hitting any other filters.
You can then create a route, something like this:
resources :people do
collection do
get 'templates/:template' => 'people#templates', as: :templates
end
end
Your controller becomes simply:
class PeopleController < ApplicationController
include HasTemplates
end
Now any file placed in the /app/views/people/templates can be served at speed from a url.
Expanding on RandallB's answer a bit; this is mentioned explicitly in the documentation on the Asset Pipeline: http://guides.rubyonrails.org/asset_pipeline.html
Note that you have to append the extension .erb to your .coffee file to have this work. (e.g., application.js.coffee.erb)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With