因此,如果我有一个名为“edit.html”的页面,它加载一个名为“_form.html”的部分,则每当我更新路由或更改_form.html中的内容时,我需要确保edit.html被修改过。
这很烦人而且非常棘手。是否有任何方法通知asset pipeline/sprockets避免缓存app/assets/templates目录?
我发现解决这个问题的最佳方案是不要使用资产管道(asset pipeline)来处理HTML模板文件。
相反,创建一个名为TemplatesController
的控制器,并仅创建一个动作。然后使用类似下面的路由将所有模板URL映射到该控制器:
get /templates/:path.html => 'templates#page', :constraints => { :path => /.+/ }
将所有模板文件移动到app/views/templates
中。
然后在控制器内进行以下设置:
caches_page :page
def page
@path = params[:path]
render :template => 'templates/' + @path, :layout => nil
end
这种方式可以让你的所有模板文件都从控制器中提供并缓存到public/templates中。为了避免缓存问题,你可以在模板路由中创建一个时间戳路径,以便你的缓存文件带有版本信息:
get '/templates/:timestamp/:path.html' => 'templates#page', :constraints => { :path => /.+/ }
通过这种方式,每次上传网站时您都可以获得一个新的时间戳,并且可以将模板文件夹存储在任何地方。您甚至可以将模板文件夹存储在S3上,并为其设置资产URL。然后无论您在哪里寻址模板文件,都可以使用自定义资产方法:
templateUrl : <%= custom_asset_template_url('some/file.html') %>
具体位置:
def custom_asset_template_url(path)
"http://custom-asset-server.website.com/templates/#{$some_global_timestamp}/#{path}"
end
如果资源文件不存在,只需将其重定向到Rails服务器,它就会被生成。或者可以在上传后预先生成所有模板文件。
有一个更好的方式来处理这个问题。
<%= path_to_asset("template_name.html") %>
这将从资产管道返回一个完整工作的文件,可以使用ERB等。虽然这是未记录的,但它是sprockets/asset pipeline的一部分。
# 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
请注意,我们在一个预处理过滤器中返回模板。这使我们能够返回静态内容而不触发其他过滤器。
然后,您可以创建一个路由,类似于以下内容:
resources :people do
collection do
get 'templates/:template' => 'people#templates', as: :templates
end
end
class PeopleController < ApplicationController
include HasTemplates
end
js_assets
(https://github.com/kavkaz/js_assets)。asset_path
函数,它模拟了 sprockets 的类似方法。对RandallB的回答进行了扩展; 这在资源管道的文档中明确提到:http://guides.rubyonrails.org/asset_pipeline.html
请注意,您必须将扩展名.erb附加到.coffee文件以使其起作用。 (例如,application.js.coffee.erb)
最干净的解决方案是使用ejs预编译您的html资源,并将它们作为其他javascript文件提供。
它的工作原理基本上就是这样:
#in you gemfile
gem 'ejs'
#in app/assets/javascripts/templates/my_template.jst.ejs
<p>my name is <%= name %> !<p>
#in your application.coffee
#= require_tree ./templates
JST['templates/my_template'](name: 'itkin')
=> '<p>my name is itkin !<p>'