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 /资产管道的一部分。
在我看来,这里需要做几件事:
- 模板应该是命名空间,因此人员模板位于app / views / people / templates目录中
- 模板完全是静态的,因此不应该调用filter。
- 应该缓存模板,使它们非常快。
以下是使用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_assets
( https://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 !
'