diff options
| author | Gibheer <gibheer@gmail.com> | 2013-02-27 22:27:02 +0100 | 
|---|---|---|
| committer | Gibheer <gibheer@gmail.com> | 2013-02-27 22:27:02 +0100 | 
| commit | 7fd2f6b25b2abd48a7292f7598e53ebd357e24f7 (patch) | |
| tree | 3dc4c831b47ea36ac0682248d1305a52c82b3a45 | |
| parent | 714c540e4b40c931be365d12c31bbe9cbdfa5fb9 (diff) | |
reworked the renderer
The renderer is now a bit smaller and asks the TemplateFinder for the
actual resources. That way it can just concentrate on rendering instead
of finding out, which stuff actually exists and which not.
| -rw-r--r-- | lib/zero/renderer.rb | 85 | ||||
| -rw-r--r-- | spec/fixtures/templates/special_layout.html.erb | 3 | ||||
| -rw-r--r-- | spec/unit/zero/renderer/initialize_spec.rb | 11 | ||||
| -rw-r--r-- | spec/unit/zero/renderer/read_template_path_bang_spec.rb | 16 | ||||
| -rw-r--r-- | spec/unit/zero/renderer/render_spec.rb | 71 | ||||
| -rw-r--r-- | spec/unit/zero/renderer/template_path.rb | 8 | ||||
| -rw-r--r-- | spec/unit/zero/renderer/templates_spec.rb | 13 | ||||
| -rw-r--r-- | spec/unit/zero/renderer/type_map_spec.rb | 13 | 
8 files changed, 106 insertions, 114 deletions
| diff --git a/lib/zero/renderer.rb b/lib/zero/renderer.rb index 2a848c2..f1930ea 100644 --- a/lib/zero/renderer.rb +++ b/lib/zero/renderer.rb @@ -24,77 +24,68 @@ module Zero      # This type map is used to extend the possible renderings for different      # types, which the clients sends.      # -    # @example create a simple renderer -    #   Renderer.new('app/templates') +    # @example create a simple renderer with a mapping from html to text/html +    #   Renderer.new('app/templates', {'html' => 'text/html'})      #      # @example create a renderer with a small map      #   Renderer.new('app', {      #     'html' => ['text/html', 'application/html+xml'],      #     'json' => ['application/json', 'application/aweomse+json']      #   }) +    # @example create a renderer with a specific layout +    #   Renderer.new('app'. 'layouts/layout', {'html' => 'text/html'})      # -    # @param template_path [String] a string to templates -    # @param type_map [Hash] a map of simple types to complex ones -    def initialize(template_path, type_map = {}) -      @template_path = template_path -      @type_map = type_map +    # @param path [String] the relative path to templates +    # @param layout [String] the key of the layouts +    # @param types [Hash{String => Array}] a map of short type names to long ones +    def initialize(path, layout = 'layout', types) +      @path   = path +      @layout = layout +      @types  = types      end      # returns the hash of type conversions      # @return [Hash] type conversion -    attr_reader :type_map +    attr_reader :types +    # returns the key for layout files +    # @return [String] the key for layouts +    attr_reader :layout      # get the path to the templates      # @return [String] the base template path -    attr_reader :template_path +    attr_reader :path      # get the tree of templates +    # +    # This function returns all templates with their keys.      # @api private      # @return [Hash] the template tree -    attr_reader :templates - -    # load the template tree -    # -    # This method gets all templates in the `template_path` and builds an -    # internal tree structure, where templates and types direct the request to -    # the wanted template. -    # @return [Self] returns the object -    def read_template_path! -      @templates = TemplateFinder.new(template_path, @type_map).get_templates +    def templates +      @templates ||= TemplateFinder.new(path, types)      end      # render a template      # -    # This method will render the given template, based on the type in the given -    # context. -    # @param name [String] the name of the template -    # @param type [Array] a list of accept types used to find the template -    # @param context [Object] the context in which to evaluate the template -    # @return [String] the rendered content -    def render(name, type, context) -      template(name, type).render(context) +    # This method will render the template according to the requested types. +    # @param template [String] the template to render +    # @param types [Array<String>] a list of types requested to render +    # @param context [Object] any object to use for rendering +    # @return [String] the result of rendering +    def render(template, types, context) +      unless templates.exist_for_types?(layout, types) +        return load_template(template, types).render(context)  +      end +      load_layout_template(types).render(context) do +        load_template(template, types).render(context) +      end      end      private -    # get the prepared template for the name and type -    # @api private -    # @param name [String] the name of the template -    # @param types [Array] the types for the template -    # @return [Tilt::Template] a prepared tilt template -    def template(name, types) -      if templates.has_key? name -        types.each do |type| -          template = templates[name][type] -          unless template.nil? -            # TODO Will be implemented later -            # return template if template.kind_of?(Tilt::Template) -            return Tilt.new(template) -          end -        end -        raise ArgumentError.new( -          "No template found for any of this types #{types.join ', '}!" -        ) -      end -      raise ArgumentError.new "No template found for '#{name}'!" +    def load_template(template, types) +      templates.get(template, types) +    end + +    def load_layout_template(types) +      templates.get(layout, types)      end    end  end diff --git a/spec/fixtures/templates/special_layout.html.erb b/spec/fixtures/templates/special_layout.html.erb new file mode 100644 index 0000000..4288509 --- /dev/null +++ b/spec/fixtures/templates/special_layout.html.erb @@ -0,0 +1,3 @@ +special layout loaded + +<%= yield %> diff --git a/spec/unit/zero/renderer/initialize_spec.rb b/spec/unit/zero/renderer/initialize_spec.rb new file mode 100644 index 0000000..39d7302 --- /dev/null +++ b/spec/unit/zero/renderer/initialize_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe Zero::Renderer, '#initialize' do +  subject { described_class.new(template_path, type_map) } +  let(:template_path) { 'foo/' } +  let(:type_map) { {'html' => ['text/html'] } } + +  its(:path)   { should be(template_path) } +  its(:layout) { should match(/layout/) } +  its(:types)  { should be(type_map) } +end diff --git a/spec/unit/zero/renderer/read_template_path_bang_spec.rb b/spec/unit/zero/renderer/read_template_path_bang_spec.rb deleted file mode 100644 index 9a2f875..0000000 --- a/spec/unit/zero/renderer/read_template_path_bang_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe Zero::Renderer, '#read_template_path!' do -  subject { Zero::Renderer.new(template_path, type_map) } -  let(:template_path) { 'spec/fixtures/templates/' } -  let(:type_map)      { {'html' => ['text/html']} } -  let(:result) { { -    'text/html' => template_path + 'index.html.erb', -    'json'      => template_path + 'index.json.erb' -    } } - -  it "loads the templates" do -    subject.read_template_path! -    expect(subject.templates['index']).to eq(result) -  end -end diff --git a/spec/unit/zero/renderer/render_spec.rb b/spec/unit/zero/renderer/render_spec.rb index 3270ac3..ed11857 100644 --- a/spec/unit/zero/renderer/render_spec.rb +++ b/spec/unit/zero/renderer/render_spec.rb @@ -1,7 +1,7 @@  require 'spec_helper'  describe Zero::Renderer, '#render' do -  subject { Zero::Renderer.new(template_path, type_map) } +  subject { described_class.new(template_path, type_map) }    let(:template_path) { 'spec/fixtures/templates/' }    let(:type_map) {{      'html' => ['text/html', 'text/xml', '*/*'], @@ -12,43 +12,54 @@ describe Zero::Renderer, '#render' do    let(:foo_types)  { ['foo/bar', 'bar/foo'] }    let(:binding) { SpecTemplateContext.new('foo') } -  before :each do -    subject.read_template_path! -  end +  context 'with default layout' do +    it 'returns a tilt template' do +      subject.render('index', html_types, binding).should be_kind_of(String) +    end -  it 'returns a tilt template' do -    subject.render('index', html_types, binding).should be_kind_of(String) -  end +    it 'renders html content' do +      subject.render('index', html_types, binding).should match('success') +    end -  it 'renders html content' do -    subject.render('index', html_types, binding).should match('success') -  end +    it 'returns a tilt template for different types' do +      subject.render('index', json_types, binding).should be_kind_of(String) +    end -  it 'returns a tilt template for different types' do -    subject.render('index', json_types, binding).should be_kind_of(String) -  end +    it 'renders json content' do +      subject.render('index', json_types, binding).should match("{text: 'success'}") +    end -  it 'renders json content' do -    subject.render('index', json_types, binding).should match("{text: 'success'}") -  end +    it 'returns an ArgumentError, if given template does not exist' do +      expect { +        subject.render('foobar', html_types, binding) +      }.to raise_error(ArgumentError, /Template 'foobar' does not exist/) +    end -  it 'returns an ArgumentError, if given template does not exist' do -    expect { -      subject.render('foobar', html_types, binding) -    }.to raise_error(ArgumentError, "No template found for 'foobar'!") -  end +    it 'returns an ArgumentError, if no template fits types' do +      expect { +        subject.render('index', foo_types, binding) +      }.to raise_error( +        ArgumentError, /Template 'index' not found/) +    end -  it 'returns an ArgumentError, if no template fits types' do -    expect { -      subject.render('index', foo_types, binding) -    }.to raise_error( -      ArgumentError, -      "No template found for any of this types #{foo_types.join ', '}!" -    ) +    it 'uses the context' do +      subject.render('context', html_types, binding).should match('foo') + +    end    end -  it 'uses the context' do -    subject.render('context', html_types, binding).should match('foo') +  context 'with special layout' do +    subject { described_class.new(template_path, layout, type_map) } +    let(:layout) { 'special_layout' } + +    it 'uses the layout for rendering' do +      expect(subject.render('index', html_types, binding) +            ).to match(/layout loaded/) +    end +    it 'renders the template into the layout' do +      expect(subject.render('index', html_types, binding) +            ).to match(/success/) +    end    end  end diff --git a/spec/unit/zero/renderer/template_path.rb b/spec/unit/zero/renderer/template_path.rb deleted file mode 100644 index 261faa8..0000000 --- a/spec/unit/zero/renderer/template_path.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'spec_helper' - -describe Zero::Renderer, '#template_path' do -  subject { Zero::Renderer.new(template_path) } -  let(:template_path) { 'foo' } - -  its(:type_map) { should be(template_path) } -end diff --git a/spec/unit/zero/renderer/templates_spec.rb b/spec/unit/zero/renderer/templates_spec.rb new file mode 100644 index 0000000..f86961b --- /dev/null +++ b/spec/unit/zero/renderer/templates_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe Zero::Renderer, '#templates' do +  let(:object) { described_class.new(template_path, types) } +  subject { object.templates } +   +  let(:template_path) { 'spec/fixtures/templates/' } +  let(:types) { {'html' => ['text/html']} } + +  it 'loads the template tree' do +    expect(subject).to be_kind_of(Zero::Renderer::TemplateFinder) +  end +end diff --git a/spec/unit/zero/renderer/type_map_spec.rb b/spec/unit/zero/renderer/type_map_spec.rb deleted file mode 100644 index 290e579..0000000 --- a/spec/unit/zero/renderer/type_map_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'spec_helper' - -describe Zero::Renderer, '#type_map' do -  subject { Zero::Renderer.new(template_path, type_map) } -  let(:template_path) { 'foo' } -  let(:type_map) { {'html' => ['text/html']} } - -  its(:type_map) { should be(type_map) } - -  it 'returns an empty Hash, if type_map is not set while initialization' do -    Zero::Renderer.new(template_path).type_map.should eq({}) -  end -end | 
