2

誰かが同じ望ましい効果を達成するためのより良い方法を、異なる構造で持っているなら、私はこのデザインを放棄することを完全に嬉しく思います。

ここでの私の動機は、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にある現在のパーシャル作業ディレクトリを知るにはどうすればよいですか?これを知っていれば、その上のすべてのテンプレートをスキップして、無限の再帰を取得することはできません。

4

0 に答える 0