誰かが同じ望ましい効果を達成するためのより良い方法を、異なる構造で持っているなら、私はこのデザインを放棄することを完全に嬉しく思います。
ここでの私の動機は、Rails 3で使用するための継承されたjavascriptウィジェットテンプレートシステムを作成することです。ユーザーがページに配置できるjavascriptウィジェットを作成し、さまざまな事前定義されたテンプレートから選択できるようにします。
理想的には、各テンプレートには「ベース」のjavascriptコードがあり、カスタマイズは一連の子テンプレートを介して階層化できます(したがって、テンプレートのスキン/新しい機能を作成します)。
これは、同じテンプレートに複数のコントローラーを使用したいという点で複雑です。
コントローラー
フォルダツリー- アプリ
- コントローラー
- ウィジェット
- モジュール
- 活動
- コンテンツ
- 画像
- コミュニティ
- モジュール
- 活動
- コンテンツ
- 画像
- ユーザー
- モジュール
- 活動
- コンテンツ
- 画像
- ウィジェット
- コントローラー
ビュー
ビューに関するメモとして、各「テンプレート」ディレクトリにconfig.rbというファイルを配置しました。このファイルは、テンプレートの親テンプレート名とフォルダーの場所を定義します。これがテンプレートリゾルバーにどのように読み込まれるかを示します。
継承構成ファイルの例
app / views / widgets / communitys / modules / template_custom_2/config.rbにあります
module InheritedTemplateConfig
def inherited_parent_base_path
"widgets/communities/modules"
end
def inherited_parent_template_name
"template_custom_1"
end
end
app / views / widgets / communitys / modules / template_custom_1/config.rbにあります
module InheritedTemplateConfig
def inherited_parent_base_path
"widgets/communities/modules"
end
def inherited_parent_template_name
"template"
end
end
app / views / widgets / communitys / modules / template/config.rbにあります
module InheritedTemplateConfig
def inherited_parent_base_path
"widgets/communities"
end
def inherited_parent_template_name
"template"
end
end
テンプレートファイルの例
app / views / widgets / communitys / modules / template_custom_2/modules.js.erbにあります
<%= render :partial => "(TEMPLATE)/same_template_test" %>
<%= render :partial => "(PARENT_TEMPLATE)/parent_template_test" %>
フォルダツリー
- アプリ
- ビュー
- ウィジェット
- モジュール
- レンプレート
- template_custom_1
- template_custom_2
- 活動
- レンプレート
- コンテンツ
- レンプレート
- 画像
- レンプレート
- コミュニティ
- レンプレート
- モジュール
- レンプレート
- template_custom_a
- template_custom_b
- 活動
- レンプレート
- コンテンツ
- レンプレート
- 画像
- レンプレート
- ユーザー
- レンプレート
- モジュール
- レンプレート
- 活動
- レンプレート
- コンテンツ
- レンプレート
- 画像
- レンプレート
- モジュール
- ウィジェット
- ビュー
したがって、いくつかのパスの例と、フォルダーのテンプレートチェーンが解決されると予想される場所。
- /widgets/modules.js
- / widgets / modules / template
- /widgets/communities/1/modules.js?template=custom_a
- / widgets / communitys / modules / template_custom_a
- / widgets / communitys / modules / template
- / widgets / modules / template
私の失敗した実装
言いたいのですが、これは非常に機能に近いです。残念ながら、リゾルバー(PARENT_TEMPLATE)のfind_template関数の場合は運が悪かったので、無限に繰り返されます。これは、解決時にスキップするテンプレートを知る方法がないためです。
動作しない唯一のことは、部分的に使用してレンダリングすることです<% render :partial => "(PARENT_TEMPLATE)/my_file" %>
class Widgets::Communities::ModulesController < ApplicationController
before_filter do
@community = Community.find(params[:community_id])
@template = params[:template].to_s
@template = "_#{@template}" if !@template.empty?
# Path to start searching for template files
prepend_view_path WidgetResolver.new("widgets/communities/modules", "template#{@template}")
end
def script
respond_to do |format|
format.js { render "modules" }
end
end
end
# Walks through from the sub_path to the base_path to find the template file
# This allows you to base one template on another template
class WigetResolver < ActionView::FileSystemResolver
attr_accessor :templates, :base_path
# Loads our current templates config, and any parent templates config
def load_template_config(base_path, template_name)
config_path = "#{Rails.root}/app/views/#{base_path}/#{template_name}/config.rb"
if File.exists?(config_path)
self.templates << {:template_name => template_name, :base_path => base_path} # This is a valid template, add it to our search path
load(config_path)
extend InheritedTemplateConfig
if !self.inherited_parent_base_path.nil? && !self.inherited_parent_template_name.nil?
self.load_template_config(self.inherited_parent_base_path, self.inherited_parent_template_name)
end
end
end
def initialize(base_path, template_name)
self.templates = []
# From our base config, load our complete config
self.load_template_config(base_path, template_name)
super("app/views")
end
def find_templates(name, prefix, partial, details)
# We want to use our custom template matching
if prefix.match(/^(TEMPLATE)/)
self.templates.each_with_index { |template,i|
result = super(name, "#{template[:base_path]}/#{template[:template_name]}", partial, details)
# We found the custom template path
return result if result.present?
}
# ----------------------------------------------------
# ERROR HERE - recurses to max depth
# ----------------------------------------------------
elsif prefix.match(/^(PARENT_TEMPLATE)/)
self.templates.each_with_index { |template,i|
# We need to skip template above the current partials template file path - HOW DO WE DO THIS?!
result = super(name, "#{template[:base_path]}/#{template[:template_name]}", partial, details)
# We found the custom template path
return result if result.present?
}
end
super(name, prefix, partial, details)
end
end
だから-質問。find_templatesにある現在のパーシャル作業ディレクトリを知るにはどうすればよいですか?これを知っていれば、その上のすべてのテンプレートをスキップして、無限の再帰を取得することはできません。