Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: libzero/zero
base: a6fa1475a2
...
head fork: libzero/zero
compare: 7fd2f6b25b
  • 3 commits
  • 14 files changed
  • 0 commit comments
  • 1 contributor
Commits on Feb 27, 2013
Gibheer Gibheer update dependencies d74f3da
Gibheer Gibheer reworked parts of the template finder
The template finder is now the instance to ask for templates. It was
already looking for them, so it should be able to handle questions
regarding the existence of templates too.
714c540
Gibheer Gibheer 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.
7fd2f6b
73 Gemfile.lock
View
@@ -7,12 +7,13 @@ PATH
GEM
remote: https://rubygems.org/
specs:
- abstract_type (0.0.2)
- adamantium (0.0.5)
- backports (~> 2.7.0)
- ice_nine (~> 0.6.0)
- backports (2.7.1)
- coderay (1.0.8)
+ abstract_type (0.0.4)
+ backports (~> 2.8.2)
+ adamantium (0.0.6)
+ backports (~> 2.8.2)
+ ice_nine (~> 0.7.0)
+ backports (2.8.2)
+ coderay (1.0.9)
descendants_tracker (0.0.1)
devutils (0.0.1)
rspec
@@ -31,10 +32,10 @@ GEM
reek
simplecov
diff-lcs (1.1.3)
- equalizer (0.0.3)
- adamantium (~> 0.0.5)
- backports (~> 2.7.0)
- flay (2.0.1)
+ equalizer (0.0.4)
+ adamantium (~> 0.0.6)
+ backports (~> 2.8.2)
+ flay (2.1.0)
ruby_parser (~> 3.0)
sexp_processor (~> 4.0)
flog (3.2.2)
@@ -49,57 +50,57 @@ GEM
guard-bundler (1.0.0)
bundler (~> 1.0)
guard (~> 1.1)
- guard-rspec (2.4.0)
+ guard-rspec (2.4.1)
guard (>= 1.1)
rspec (~> 2.11)
- ice_nine (0.6.0)
+ ice_nine (0.7.0)
+ inflecto (0.0.2)
kramdown (0.14.2)
- listen (0.7.2)
+ listen (0.7.3)
lumberjack (1.0.2)
- mbj-inflector (0.0.2)
method_source (0.8.1)
- multi_json (1.5.0)
- mutant (0.2.16)
- abstract_type (~> 0.0.2)
- adamantium (~> 0.0.4)
- backports (~> 2.6)
+ multi_json (1.6.1)
+ mutant (0.2.17)
+ abstract_type (~> 0.0.3)
+ adamantium (~> 0.0.6)
+ backports (~> 2.8.2)
descendants_tracker (~> 0.0.1)
diff-lcs (~> 1.1.3)
- equalizer (~> 0.0.1)
- ice_nine (~> 0.6.0)
- mbj-inflector (~> 0.0.1)
+ equalizer (~> 0.0.4)
+ ice_nine (~> 0.7.0)
+ inflecto (~> 0.0.2)
to_source (~> 0.2.14)
mutant-melbourne (2.0.3)
pelusa (0.2.2)
- pry (0.9.11.4)
+ pry (0.9.12)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
- pry (0.9.11.4-java)
+ pry (0.9.12-java)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
spoon (~> 0.0)
- rack (1.5.1)
+ rack (1.5.2)
redcarpet (2.2.2)
reek (1.3.1)
ruby2ruby (~> 2.0.2)
ruby_parser (~> 3.1.1)
sexp_processor
- rspec (2.12.0)
- rspec-core (~> 2.12.0)
- rspec-expectations (~> 2.12.0)
- rspec-mocks (~> 2.12.0)
- rspec-core (2.12.2)
- rspec-expectations (2.12.1)
- diff-lcs (~> 1.1.3)
- rspec-mocks (2.12.2)
- ruby2ruby (2.0.2)
+ rspec (2.13.0)
+ rspec-core (~> 2.13.0)
+ rspec-expectations (~> 2.13.0)
+ rspec-mocks (~> 2.13.0)
+ rspec-core (2.13.0)
+ rspec-expectations (2.13.0)
+ diff-lcs (>= 1.1.3, < 2.0)
+ rspec-mocks (2.13.0)
+ ruby2ruby (2.0.3)
ruby_parser (~> 3.1)
sexp_processor (~> 4.0)
ruby_parser (3.1.1)
sexp_processor (~> 4.1)
- sexp_processor (4.1.4)
+ sexp_processor (4.1.5)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
@@ -114,7 +115,7 @@ GEM
adamantium (~> 0.0.5)
equalizer (~> 0.0.3)
mutant-melbourne (~> 2.0.3)
- yard (0.8.3)
+ yard (0.8.5.2)
PLATFORMS
java
85 lib/zero/renderer.rb
View
@@ -24,77 +24,68 @@ class Renderer
# 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
76 lib/zero/renderer/template_finder.rb
View
@@ -61,6 +61,9 @@ class TemplateFinder
# @returns [Regex] the regex built from the path
attr_reader :path_regex
+ # returns all templates found
+ attr_reader :templates
+
# initialize a new template finder
#
# @example
@@ -75,6 +78,72 @@ def initialize(path, type_map)
@path = path
@type_map = sanity_map(type_map)
@path_regex = /#{path}/
+ @templates = load_templates
+ end
+
+ # get the template
+ #
+ # This function returns the template when found.
+ # @raise ArgumentError when the template was not found the type
+ # @param template [String] the template to return
+ # @param type [String] the type to return the template for
+ # @return [Tilt::Template] the tilt template
+ def get(template, types)
+ raise ArgumentError.new(<<-ERROR) unless exist?(template)
+ Template '#{template}' does not exist!
+ ERROR
+ types.each do |type|
+ return Tilt.new(get_template(template, type)) if has_template?(template, type)
+ end
+ raise ArgumentError.new(<<-ERROR)
+ Template '#{template}' not found!
+ types: #{types.inspect}
+ ERROR
+ end
+
+ # check if a specific template exists
+ #
+ # This function checks for the existance of the specifiec template.
+ # @param template [String] the template to find
+ # @returns [Boolean] true when template was found
+ def exist?(template)
+ templates.has_key?(template)
+ end
+
+ # check if the template exists for the specified types
+ #
+ # This function takes the template and searches for any template for the
+ # types.
+ # @param template [String] the template to look for
+ # @param types [Array<String>] the types to test
+ # @return [Boolean] true when a template is found, else false
+ def exist_for_types?(template, types)
+ return false unless exist?(template)
+ types.each do |type|
+ return has_template?(template, type)
+ end
+ false
+ end
+
+ private
+
+ # checks if the template has support for the type
+ #
+ # @param template [String] the template to look for
+ # @param type [String] the type to look for
+ # @return [Boolean] true when the template was found
+ def has_template?(template, type)
+ templates[template].has_key?(type)
+ end
+
+ # returns the template for the type
+ #
+ # This function returns the template for the specified type.
+ # @param template [String] the template to return
+ # @param type [String] the type to return the template for
+ # @return [String] the filename for the template
+ def get_template(template, type)
+ templates[template][type]
end
# traverses the template path to gather all templates
@@ -82,18 +151,17 @@ def initialize(path, type_map)
# This function traverses the template path, collects and sorts all
# templates into the target types given at initialization.
# @return [Hash] the map of type to template
- def get_templates
- result = Hash.new {|hash, key| hash[key] = {} }
+ def load_templates
+ result = {}
search_files.each do |file|
key, value = add_template(file)
+ result[key] = {} unless result.has_key?(key)
result[key] = result[key].merge(value)
end
result
end
- private
-
# returns a list of files found at @path
#
# This method returns all files found in @path, which look like a template.
3  spec/fixtures/templates/special_layout.html.erb
View
@@ -0,0 +1,3 @@
+special layout loaded
+
+<%= yield %>
11 spec/unit/zero/renderer/initialize_spec.rb
View
@@ -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
16 spec/unit/zero/renderer/read_template_path_bang_spec.rb
View
@@ -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
71 spec/unit/zero/renderer/render_spec.rb
View
@@ -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 @@
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
25 spec/unit/zero/renderer/template_finder/exist_for_types_predicate_spec.rb
View
@@ -0,0 +1,25 @@
+require 'spec_helper'
+
+describe Zero::Renderer::TemplateFinder, '#exist_for_types?' do
+ subject { described_class.new(template_path, type_map) }
+ let(:template_path) { 'spec/fixtures/templates/' }
+ let(:type_map) { {'html' => 'text/html'} }
+ let(:html_types) { ['text/html'] }
+ let(:foo_types) { ['foo/bar', 'bar/foo'] }
+
+ it 'returns true when template exists' do
+ expect(subject.exist_for_types?('index', html_types)).to be(true)
+ end
+
+ it 'returns false when template does not exist' do
+ expect(subject.exist_for_types?('not_found', html_types)).to be(false)
+ end
+
+ it 'returns false when template for types does not exists' do
+ expect(subject.exist_for_types?('index', foo_types)).to be(false)
+ end
+
+ it 'returns false when no types are defined' do
+ expect(subject.exist_for_types?('index', [])).to be(false)
+ end
+end
15 spec/unit/zero/renderer/template_finder/exist_predicate_spec.rb
View
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe Zero::Renderer::TemplateFinder, '#exist?' do
+ subject { described_class.new(template_path, type_map) }
+ let(:template_path) { 'spec/fixtures/templates/' }
+ let(:type_map) { {'html' => 'text/html'} }
+
+ it 'returns true when the template exists' do
+ expect(subject.exist?('index')).to be(true)
+ end
+
+ it 'returns false when the template does not exist' do
+ expect(subject.exist?('not_found')).to be(false)
+ end
+end
27 spec/unit/zero/renderer/template_finder/get_spec.rb
View
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+describe Zero::Renderer::TemplateFinder, '#get' do
+ subject { described_class.new(template_path, type_map) }
+ let(:template_path) { 'spec/fixtures/templates/' }
+ let(:type_map) {{
+ 'html' => ['text/html', 'text/xml', '*/*'],
+ 'json' => ['application/json', 'plain/text']
+ }}
+ let(:html_types) { ['text/html'] }
+ let(:json_types) { ['application/json'] }
+ let(:foo_types) { ['foo/bar', 'bar/foo'] }
+
+ it 'returns a Tilt template' do
+ expect(subject.get('index', html_types)).to be_kind_of(Tilt::Template)
+ end
+
+ it 'raises an Error when the template is not found' do
+ expect { subject.get('not_exist', html_types) }.to raise_error(
+ ArgumentError, /Template 'not_exist' does not exist/)
+ end
+
+ it 'raises an Error when no type for the template was found' do
+ expect { subject.get('index', foo_types) }.to raise_error(
+ ArgumentError, /Template 'index' not found/)
+ end
+end
9 ...ro/renderer/template_finder/get_templates_spec.rb → ...t/zero/renderer/template_finder/templates_spec.rb
View
@@ -17,7 +17,7 @@
shared_examples_for 'a template loader' do
it 'creates a template tree' do
- subject.get_templates['welcome/index'].should eq(result)
+ subject.templates['welcome/index'].should eq(result)
end
end
@@ -55,11 +55,4 @@
it_behaves_like 'a template loader'
end
-
- it 'creates an empty templates list without templates in path' do
- subject = Zero::Renderer.new("bar/", {})
- subject.read_template_path!
-
- subject.templates.should eq({})
- end
end
8 spec/unit/zero/renderer/template_path.rb
View
@@ -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
13 spec/unit/zero/renderer/templates_spec.rb
View
@@ -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
13 spec/unit/zero/renderer/type_map_spec.rb
View
@@ -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

No commit comments for this range

Something went wrong with that request. Please try again.