<commit_before>module Rabl
  module Partials
    include Rabl::Helpers

    # Renders a partial hash based on another rabl template
    # partial("users/show", :object => @user)
    # options must have :object
    # options can have :view_path, :child_root, :root
    def partial(file, options={}, &block)
      raise ArgumentError, "Must provide an :object option to render a partial" unless options.has_key?(:object)
      object, view_path = options.delete(:object), options.delete(:view_path)
      source, location = self.fetch_source(file, :view_path => view_path)
      engine_options = options.merge(:source => source, :source_location => location)
      self.object_to_hash(object, engine_options, &block)
    end

    # Returns a hash based representation of any data object given ejs template block
    # object_to_hash(@user) { attribute :full_name } => { ... }
    # object_to_hash(@user, :source => "...") { attribute :full_name } => { ... }
    # object_to_hash([@user], :source => "...") { attribute :full_name } => { ... }
    # options must have :source (rabl file contents)
    # options can have :source_location (source filename)
    def object_to_hash(object, options={}, &block)
      return object unless is_object?(object) || is_collection?(object)
      return [] if is_collection?(object) && object.blank? # empty collection
      engine_options = options.reverse_merge(:format => "hash", :root => (options[:root] || false))
      Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, &block)
    end

    # Returns source for a given relative file
    # fetch_source("show", :view_path => "...") => "...contents..."
    def fetch_source(file, options={})
      Rabl.source_cache(file, options[:view_path]) do
        if defined? Padrino
          file_path = fetch_padrino_source(file, options={})
        elsif defined?(Rails) && context_scope
          file_path = fetch_rails_source(file, options={})
        elsif defined? Sinatra
          file_path = fetch_sinatra_source(file, options={})
        end

        raise "Cannot find rabl template '#{file}' within registered views!" unless File.exist?(file_path.to_s)
        [File.read(file_path.to_s), file_path.to_s] if file_path
      end
    end

    private

    def fetch_padrino_source(file, options={})
      view_path = Array(options[:view_path] || context_scope.settings.views)
      # use Padrino's own template resolution mechanism
      file_path, _ = context_scope.instance_eval { resolve_template(file) }
      # Padrino chops the extension, stitch it back on
      File.join(view_path.first.to_s, (file_path.to_s + ".rabl"))
    end

    def fetch_rails_source(file, options={})
      # use Rails template resolution mechanism if possible (find_template)
      source_format = request_format if defined?(request_format)
      view_path = Array(options[:view_path] || context_scope.view_paths.to_a)
      if source_format && context_scope.respond_to?(:lookup_context) # Rails 3
        lookup_proc = lambda { |partial| context_scope.lookup_context.find_template(file, [], partial) }
        template = lookup_proc.call(false) rescue lookup_proc.call(true)
        file_path = template.identifier if template
      elsif source_format && context_scope.respond_to?(:view_paths) # Rails 2
        template = context_scope.view_paths.find_template(file, source_format, false)
        file_path = template.filename if template
      else # fallback to manual
        file_path = fetch_manual_template(view_path, file)
      end
      file_path
    end

    def fetch_sinatra_source(file, options={})
      view_path = Array(options[:view_path] || context_scope.settings.views)
      file_path = fetch_manual_template(view_path, file)
    end

    def fetch_manual_template(view_path, file)
      Dir[File.join("{#{view_path.join(",")}}", file + ".{*.,}rabl")].first
    end

  end # Partials
end # Rabl<commit_msg>[partials] Cleanup template resolution refactoring<commit_after>module Rabl
  module Partials
    include Rabl::Helpers

    # Renders a partial hash based on another rabl template
    # partial("users/show", :object => @user)
    # options must have :object
    # options can have :view_path, :child_root, :root
    def partial(file, options={}, &block)
      raise ArgumentError, "Must provide an :object option to render a partial" unless options.has_key?(:object)
      object, view_path = options.delete(:object), options.delete(:view_path)
      source, location = self.fetch_source(file, :view_path => view_path)
      engine_options = options.merge(:source => source, :source_location => location)
      self.object_to_hash(object, engine_options, &block)
    end

    # Returns a hash based representation of any data object given ejs template block
    # object_to_hash(@user) { attribute :full_name } => { ... }
    # object_to_hash(@user, :source => "...") { attribute :full_name } => { ... }
    # object_to_hash([@user], :source => "...") { attribute :full_name } => { ... }
    # options must have :source (rabl file contents)
    # options can have :source_location (source filename)
    def object_to_hash(object, options={}, &block)
      return object unless is_object?(object) || is_collection?(object)
      return [] if is_collection?(object) && object.blank? # empty collection
      engine_options = options.reverse_merge(:format => "hash", :root => (options[:root] || false))
      Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, &block)
    end

    # Returns source for a given relative file
    # fetch_source("show", :view_path => "...") => "...contents..."
    def fetch_source(file, options={})
      Rabl.source_cache(file, options[:view_path]) do
        file_path = if defined? Padrino
          fetch_padrino_source(file, options)
        elsif defined?(Rails) && context_scope
          fetch_rails_source(file, options)
        elsif defined? Sinatra
          fetch_sinatra_source(file, options)
        end

        raise "Cannot find rabl template '#{file}' within registered views!" unless File.exist?(file_path.to_s)
        [File.read(file_path.to_s), file_path.to_s] if file_path
      end
    end

    private

    def fetch_padrino_source(file, options={})
      view_path = Array(options[:view_path] || context_scope.settings.views)
      # use Padrino's own template resolution mechanism
      file_path, _ = context_scope.instance_eval { resolve_template(file) }
      # Padrino chops the extension, stitch it back on
      File.join(view_path.first.to_s, (file_path.to_s + ".rabl"))
    end

    def fetch_rails_source(file, options={})
      # use Rails template resolution mechanism if possible (find_template)
      source_format = request_format if defined?(request_format)
      view_path = Array(options[:view_path] || context_scope.view_paths.to_a)
      if source_format && context_scope.respond_to?(:lookup_context) # Rails 3
        lookup_proc = lambda { |partial| context_scope.lookup_context.find_template(file, [], partial) }
        template = lookup_proc.call(false) rescue lookup_proc.call(true)
        template.identifier if template
      elsif source_format && context_scope.respond_to?(:view_paths) # Rails 2
        template = context_scope.view_paths.find_template(file, source_format, false)
        template.filename if template
      else # fallback to manual
        fetch_manual_template(view_path, file)
      end
    end

    def fetch_sinatra_source(file, options={})
      view_path = Array(options[:view_path] || context_scope.settings.views)
      fetch_manual_template(view_path, file)
    end

    def fetch_manual_template(view_path, file)
      Dir[File.join("{#{view_path.join(",")}}", file + ".{*.,}rabl")].first
    end

  end # Partials
end # Rabl
{'fraction_non_alphanumeric': 0.11885875127942681, 'fraction_numerical': 0.0005117707267144319, 'mean_word_length': 3.5928319623971796, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3786202', 'n_tokens_mistral': 2327, 'n_tokens_neox': 2293, 'n_words': 572}