Rails资产管道中的静态html模板文件和开发模式下的缓存

我正在使用AngularJS和Rails构建一个网站。 我用于模板的HTML文件存储在/ app / assets / templates下,每次更新路径或更改模板内部嵌套部分内的内容时,我都需要“触摸”最高级别的文件。我正在改变的html文件的/ app / assets / templates目录。

因此,如果我有一个页面“edit.html”加载部分“_form.html”,那么每当我更新路线或更改_form.html中的内容时,我都需要确保触及edit.html。

这很烦人,非常挑剔。 有没有办法通知资产管道/链轮,以避免app / assets / templates目录的缓存?

我发现的最佳解决方案是不要将资产管道用于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服务器(如果找不到它),它就会生成。 或者上传后可以预先生成所有模板文件。

有很多(更多!)更好的方法来解决这个问题。

<%= path_to_asset("template_name.html") %>

这将从资产管道返回一个完全工作的文件,它可以使用ERB等。它没有文档,但它是sprockets /资产管道的一部分。

在我看来,这里需要做几件事:

  1. 模板应该是命名空间,因此人员模板位于app / views / people / templates目录中
  2. 模板完全是静态的,因此不应该调用filter。
  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 

请注意,我们将在前置filter中返回模板。 这允许我们返回静态内容而不会遇到任何其他filter。

然后,您可以创建一个路径,如下所示:

 resources :people do collection do get 'templates/:template' => 'people#templates', as: :templates end end 

您的控制器变得简单:

 class PeopleController < ApplicationController include HasTemplates end 

现在,可以从url快速提供放置在/ app / views / people / templates中的任何文件。

扩展RandallB的答案; 这在资产管道的文档中明确提到: http : //guides.rubyonrails.org/asset_pipeline.html

请注意,您必须将扩展名.erb附加到.coffee文件才能使其正常工作。 (例如,application.js.coffee.erb)

您可以尝试gem js_assetshttps://github.com/kavkaz/js_assets )。

这允许您在javascript代码中运行asset_path ,模拟类似的链接器方法。

最干净的解决方案是使用ejs预编译您的html资源,并将其作为其他javascript文件提供。

  • 没有http查询
  • 缩小
  • 可以将js数据传递给模板以使它们动态化(ejs是来自下划线模板的端口,基本上表现得像jb的erb)

它基本上是这样的:

  #in you gemfile gem 'ejs' #in app/assets/javascripts/templates/my_template.jst.ejs 

my name is <%= name %> !

#in your application.coffee #= require_tree ./templates JST['templates/my_template'](name: 'itkin') => '

my name is itkin !

'