我正在使用AngularJS和Rails构建一个网站。我用于模板的HTML文件存储在/ app / assets / templates下,每次更新路径或更改模板内部嵌套部分内的内容时,我都需要“触摸”最高级别的文件。我正在改变的html文件的/ app / assets / templates目录。
因此,如果我有一个“edit.html”页面加载部分“_form.html”,那么每当我更新路线或更改_form.html中的内容时,我都需要确保触及edit.html。
这很烦人,非常挑剔。有没有办法通知资产管道/链轮以避免app / assets / templates目录的缓存?
答案 0 :(得分:21)
我发现的最佳解决方案是不要将资源管道用于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
这样,您的所有模板文件都将从控制器提供,然后将缓存到公共/模板中。为避免缓存问题,您可以创建模板路由的时间戳路径,以便使用版本传递缓存文件:
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服务器(如果找不到它),它将被生成。或者上传后可以预先生成所有模板文件。
答案 1 :(得分:6)
有很多(更多!)更好的方法来解决这个问题。
<%= path_to_asset("template_name.html") %>
这将从资产管道返回一个完全正常工作的文件,它可以使用ERB等。它没有文档,但它是链轮/资产管道的一部分。
答案 2 :(得分:3)
在我看来,这里需要做几件事:
这是使用Rails问题的可能解决方案:
# 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
现在可以从网址快速提供放置在/ app / views / people / templates中的任何文件。
答案 3 :(得分:1)
扩展RandallB的答案;这在资产管道的文档中明确提到:http://guides.rubyonrails.org/asset_pipeline.html
请注意,您必须将扩展名.erb附加到.coffee文件才能使其正常工作。 (例如,application.js.coffee.erb)
答案 4 :(得分:1)
您可以尝试使用gem js_assets
(https://github.com/kavkaz/js_assets)。
这允许您在javascript代码中运行asset_path
,模拟类似的链接器方法。
答案 5 :(得分:0)
最干净的解决方案是使用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>'