renee-render 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +38 -0
- data/Rakefile +8 -0
- data/lib/renee-render/version.rb +6 -0
- data/lib/renee-render.rb +136 -0
- data/renee-render.gemspec +28 -0
- data/test/render_test.rb +114 -0
- data/test/test_helper.rb +10 -0
- metadata +186 -0
data/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Renee Render
|
2
|
+
|
3
|
+
Rendering templates in Renee should be familiar and intuitive using the `render` command:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
run Renee::Core.new {
|
7
|
+
path('blog') do
|
8
|
+
get { render! :haml, :"blogs/index" }
|
9
|
+
end
|
10
|
+
}
|
11
|
+
```
|
12
|
+
|
13
|
+
This above is the standard render syntax, specifying the engine followed by the template. You can also render without specifying an engine:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
path('blog') do
|
17
|
+
get { render! "blogs/index" }
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
This will do a lookup in the views path to find the appropriately named template. You can also pass locals and layout options as you would expect:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
path('blog') do
|
25
|
+
get { render! "blogs/index", :locals => { :foo => "bar" }, :layout => :bar }
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
This will render the "blogs/index.erb" file if it exists, passing the 'foo' local variable
|
30
|
+
and wrapping the result in the 'bar.erb' layout file. You can also render without returning the response by using:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
path('blog') do
|
34
|
+
get { render "blogs/index" }
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
This allows you to render the content as a string without immediately responding.
|
data/Rakefile
ADDED
data/lib/renee-render.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
class Renee
|
4
|
+
# This module is responsible for handling the rendering of templates
|
5
|
+
# using Tilt supporting all included template engines.
|
6
|
+
module Render
|
7
|
+
##
|
8
|
+
# Exception responsible for when a generic rendering error occurs.
|
9
|
+
#
|
10
|
+
class RenderError < RuntimeError; end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Exception responsible for when an expected template does not exist.
|
14
|
+
#
|
15
|
+
class TemplateNotFound < RenderError; end
|
16
|
+
|
17
|
+
# Same as render but automatically halts.
|
18
|
+
# @param (see #render)
|
19
|
+
# @return (see #render)
|
20
|
+
# @see #render
|
21
|
+
def render!(*args, &blk)
|
22
|
+
halt render(*args, &blk)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Renders a string given the engine and the content.
|
27
|
+
#
|
28
|
+
# @param [Symbol] engine The template engine to use for rendering.
|
29
|
+
# @param [String] data The content or file to render.
|
30
|
+
# @param [Hash] options The rendering options to pass onto tilt.
|
31
|
+
#
|
32
|
+
# @return [String] The result of rendering the data with specified engine.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# render :haml, "%p test" => "<p>test</p>"
|
36
|
+
# render :haml, :index => "<p>test</p>"
|
37
|
+
# render "index" => "<p>test</p>"
|
38
|
+
#
|
39
|
+
# @api public
|
40
|
+
#
|
41
|
+
def render(engine, data=nil, options={}, &block)
|
42
|
+
# Handles the case where engine is unspecified by shifting the data (i.e render "index")
|
43
|
+
engine, data, options = nil, engine.to_sym, data if data.nil? || data.is_a?(Hash)
|
44
|
+
|
45
|
+
options ||= {}
|
46
|
+
options[:outvar] ||= '@_out_buf'
|
47
|
+
# TODO allow default encoding to be set (as an option)
|
48
|
+
options[:default_encoding] ||= "utf-8"
|
49
|
+
|
50
|
+
locals = options.delete(:locals) || {}
|
51
|
+
views = options.delete(:views) || settings.views_path || "./views"
|
52
|
+
layout = options.delete(:layout)
|
53
|
+
layout_engine = options.delete(:layout_engine) || engine
|
54
|
+
# TODO suppress template errors for layouts?
|
55
|
+
# TODO allow content_type to be set with an option to render?
|
56
|
+
scope = options.delete(:scope) || self
|
57
|
+
|
58
|
+
# TODO default layout file convention?
|
59
|
+
template = compile_template(engine, data, options, views)
|
60
|
+
output = template.render(scope, locals, &block)
|
61
|
+
|
62
|
+
if layout # render layout
|
63
|
+
# TODO handle when layout is missing better!
|
64
|
+
options = options.merge(:views => views, :layout => false, :scope => scope)
|
65
|
+
return render(layout_engine, layout, options.merge(:locals => locals)) { output }
|
66
|
+
end
|
67
|
+
|
68
|
+
output
|
69
|
+
end # render
|
70
|
+
|
71
|
+
##
|
72
|
+
# Constructs a template based on engine, data and options.
|
73
|
+
#
|
74
|
+
# @param [Symbol] engine The template engine to use for rendering.
|
75
|
+
# @param [String] data The content or file to render.
|
76
|
+
# @param [Hash] options The rendering options to pass onto tilt.
|
77
|
+
# @param [String] views The view_path from which to locate the template.
|
78
|
+
#
|
79
|
+
# @return [Tilt::Template] The tilt template to render with all required options.
|
80
|
+
# @raise [TemplateNotFound] The template to render could not be located.
|
81
|
+
# @raise [RenderError] The template to render could not be located.
|
82
|
+
#
|
83
|
+
# @api private
|
84
|
+
#
|
85
|
+
def compile_template(engine, data, options, views)
|
86
|
+
template_cache.fetch engine, data, options do
|
87
|
+
if data.is_a?(Symbol) # data is template path
|
88
|
+
file_path, engine = find_template(views, data, engine)
|
89
|
+
template = Tilt[engine]
|
90
|
+
raise TemplateNotFound, "Template engine not found: #{engine}" if template.nil?
|
91
|
+
raise TemplateNotFound, "Template '#{data}' not found in '#{views}'!" unless file_path
|
92
|
+
# TODO suppress errors for layouts?
|
93
|
+
template.new(file_path, 1, options)
|
94
|
+
elsif data.is_a?(String) # data is body string
|
95
|
+
# TODO figure out path based on caller file
|
96
|
+
path, line = options[:path] || "caller file", options[:line] || 1
|
97
|
+
body = data.is_a?(String) ? Proc.new { data } : data
|
98
|
+
template = Tilt[engine]
|
99
|
+
raise "Template engine not found: #{engine}" if template.nil?
|
100
|
+
template.new(path, line.to_i, options, &body)
|
101
|
+
else # data can't be handled
|
102
|
+
raise RenderError, "Cannot render data #{data.inspect}."
|
103
|
+
end
|
104
|
+
end # template_cache.fetch
|
105
|
+
end # compile_template
|
106
|
+
|
107
|
+
##
|
108
|
+
# Searches view paths for template based on data and engine with rendering options.
|
109
|
+
# Supports finding a template without an engine.
|
110
|
+
#
|
111
|
+
# @param [String] views The view paths
|
112
|
+
# @param [String] name The name of the template
|
113
|
+
# @param [Symbol] engine The engine to use for rendering.
|
114
|
+
#
|
115
|
+
# @return [<String, Symbol>] An array of the file path and the engine.
|
116
|
+
#
|
117
|
+
# @example
|
118
|
+
# find_template("./views", "index", :erb) => ["path/to/index.erb", :erb]
|
119
|
+
# find_template("./views", "foo") => ["path/to/index.haml", :haml]
|
120
|
+
#
|
121
|
+
# @api private
|
122
|
+
#
|
123
|
+
def find_template(views, name, engine=nil)
|
124
|
+
lookup_ext = (engine || File.extname(name.to_s)[1..-1] || "*").to_s
|
125
|
+
base_name = name.to_s.chomp(".#{lookup_ext}")
|
126
|
+
file_path = Dir[File.join(views, "#{base_name}.#{lookup_ext}")].first
|
127
|
+
engine ||= File.extname(file_path)[1..-1].to_sym if file_path
|
128
|
+
[file_path, engine]
|
129
|
+
end # find_template
|
130
|
+
|
131
|
+
# Maintain Tilt::Cache of the templates.
|
132
|
+
def template_cache
|
133
|
+
@template_cache ||= Tilt::Cache.new
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "renee-render/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "renee-render"
|
7
|
+
s.version = Renee::Render::VERSION
|
8
|
+
s.authors = ["Josh Hull", "Nathan Esquenazi", "Arthur Chiu"]
|
9
|
+
s.email = ["joshbuddy@gmail.com", "nesquena@gmail.com", "mr.arthur.chiu@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{The super-friendly web framework rendering component}
|
12
|
+
s.description = %q{The super-friendly web framework rendering component.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "renee"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'rack', "~> 1.3.0"
|
22
|
+
s.add_runtime_dependency 'tilt', "~> 1.3.3"
|
23
|
+
s.add_development_dependency 'minitest', "~> 2.6.1"
|
24
|
+
s.add_development_dependency 'rake'
|
25
|
+
s.add_development_dependency 'bundler', "~> 1.0.10"
|
26
|
+
s.add_development_dependency "rack-test", ">= 0.5.0"
|
27
|
+
s.add_development_dependency "haml", ">= 2.2.0"
|
28
|
+
end
|
data/test/render_test.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Renee::Render do
|
4
|
+
describe "#render" do
|
5
|
+
after { remove_views }
|
6
|
+
|
7
|
+
it "should allow rendering string with engine" do
|
8
|
+
mock_app {
|
9
|
+
path("/a") { get { render! :erb, "<p>test</p>" } }
|
10
|
+
path("/b") { get { render! :erb, "<p><%= foo %></p>", :locals => { :foo => "bar" } } }
|
11
|
+
path("/c") { get { halt render(:erb, "<p><%= foo %></p>", :locals => { :foo => "bar" }) } }
|
12
|
+
}
|
13
|
+
get('/a')
|
14
|
+
assert_equal 200, response.status
|
15
|
+
assert_equal "<p>test</p>", response.body
|
16
|
+
get('/b')
|
17
|
+
assert_equal 200, response.status
|
18
|
+
assert_equal "<p>bar</p>", response.body
|
19
|
+
get('/c')
|
20
|
+
assert_equal 200, response.status
|
21
|
+
assert_equal "<p>bar</p>", response.body
|
22
|
+
end # string, with engine
|
23
|
+
|
24
|
+
it "should allow rendering template file with engine" do
|
25
|
+
create_view :index, "%p test", :haml
|
26
|
+
create_view :foo, "%p= foo", :haml
|
27
|
+
mock_app {
|
28
|
+
path("/a") { get { render! :haml, :index } }
|
29
|
+
path("/b") { get { render! :haml, :foo, :locals => { :foo => "bar" } } }
|
30
|
+
path("/c") { get { halt render(:haml, :foo, :locals => { :foo => "bar" }) } }
|
31
|
+
}
|
32
|
+
get('/a')
|
33
|
+
assert_equal 200, response.status
|
34
|
+
assert_equal "<p>test</p>\n", response.body
|
35
|
+
get('/b')
|
36
|
+
assert_equal 200, response.status
|
37
|
+
assert_equal "<p>bar</p>\n", response.body
|
38
|
+
get('/c')
|
39
|
+
assert_equal 200, response.status
|
40
|
+
assert_equal "<p>bar</p>\n", response.body
|
41
|
+
end # template, with engine
|
42
|
+
|
43
|
+
it "should allow rendering template file with unspecified engine" do
|
44
|
+
create_view :index, "%p test", :haml
|
45
|
+
create_view :foo, "%p= foo", :haml
|
46
|
+
mock_app {
|
47
|
+
path("/a") { get { render! "index" } }
|
48
|
+
path("/b") { get { render! "foo.haml", :locals => { :foo => "bar" } } }
|
49
|
+
}
|
50
|
+
get('/a')
|
51
|
+
assert_equal 200, response.status
|
52
|
+
assert_equal "<p>test</p>\n", response.body
|
53
|
+
get('/b')
|
54
|
+
assert_equal 200, response.status
|
55
|
+
assert_equal "<p>bar</p>\n", response.body
|
56
|
+
end # template, unspecified engine
|
57
|
+
|
58
|
+
it "should allow rendering template file with engine and layout" do
|
59
|
+
create_view :index, "%p test", :haml
|
60
|
+
create_view :foo, "%p= foo", :haml
|
61
|
+
create_view :layout, "%div.wrapper= yield", :haml
|
62
|
+
mock_app {
|
63
|
+
path("/a") { get { render! :haml, :index, :layout => :layout } }
|
64
|
+
path("/b") { get { render! :foo, :layout => :layout, :locals => { :foo => "bar" } } }
|
65
|
+
}
|
66
|
+
get('/a')
|
67
|
+
assert_equal 200, response.status
|
68
|
+
assert_equal %Q{<div class='wrapper'><p>test</p></div>\n}, response.body
|
69
|
+
get('/b')
|
70
|
+
assert_equal 200, response.status
|
71
|
+
assert_equal %Q{<div class='wrapper'><p>bar</p></div>\n}, response.body
|
72
|
+
end # with engine and layout specified
|
73
|
+
|
74
|
+
it "should allow rendering template with different layout engines" do
|
75
|
+
create_view :index, "%p test", :haml
|
76
|
+
create_view :foo, "%p= foo", :haml
|
77
|
+
create_view :base, "<div class='wrapper'><%= yield %></div>", :erb
|
78
|
+
mock_app {
|
79
|
+
path("/a") { get { render! :haml, :index, :layout => :base, :layout_engine => :erb } }
|
80
|
+
path("/b") { get { render! :foo, :layout => :base, :locals => { :foo => "bar" } } }
|
81
|
+
}
|
82
|
+
get('/a')
|
83
|
+
assert_equal 200, response.status
|
84
|
+
assert_equal %Q{<div class='wrapper'><p>test</p>\n</div>}, response.body
|
85
|
+
get('/b')
|
86
|
+
assert_equal 200, response.status
|
87
|
+
assert_equal %Q{<div class='wrapper'><p>bar</p>\n</div>}, response.body
|
88
|
+
end # different layout and template engines
|
89
|
+
|
90
|
+
it "should fail properly rendering template file with invalid engine" do
|
91
|
+
create_view :index, "%p test", :haml
|
92
|
+
mock_app {
|
93
|
+
get { render! :fake, :index }
|
94
|
+
}
|
95
|
+
assert_raises(Renee::Render::TemplateNotFound) { get('/') }
|
96
|
+
end # template, invalid engine
|
97
|
+
|
98
|
+
it "should fail properly rendering missing template file with engine" do
|
99
|
+
create_view :index, "%p test", :haml
|
100
|
+
mock_app {
|
101
|
+
get { render! :haml, :foo }
|
102
|
+
}
|
103
|
+
assert_raises(Renee::Render::TemplateNotFound) { get('/') }
|
104
|
+
end # missing template, with engine
|
105
|
+
|
106
|
+
it "should fail properly rendering invalid data" do
|
107
|
+
create_view :index, "%p test", :haml
|
108
|
+
mock_app {
|
109
|
+
get { render! :haml, /invalid regex data/ }
|
110
|
+
}
|
111
|
+
assert_raises(Renee::Render::RenderError) { get('/') }
|
112
|
+
end # missing template, with engine
|
113
|
+
end
|
114
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
$: << File.expand_path('../../../renee-core/lib', __FILE__)
|
2
|
+
$: << File.expand_path('../../lib', __FILE__)
|
3
|
+
require 'renee-core'
|
4
|
+
require 'renee-render'
|
5
|
+
|
6
|
+
# TODO better registration method (?)
|
7
|
+
Renee::Core::Application.send(:include, Renee::Render)
|
8
|
+
|
9
|
+
# Load shared test helpers
|
10
|
+
require File.expand_path('../../../lib/test_helper', __FILE__)
|
metadata
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: renee-render
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Josh Hull
|
14
|
+
- Nathan Esquenazi
|
15
|
+
- Arthur Chiu
|
16
|
+
autorequire:
|
17
|
+
bindir: bin
|
18
|
+
cert_chain: []
|
19
|
+
|
20
|
+
date: 2011-10-15 00:00:00 Z
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 27
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 3
|
32
|
+
- 0
|
33
|
+
version: 1.3.0
|
34
|
+
requirement: *id001
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
name: rack
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 29
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 3
|
48
|
+
- 3
|
49
|
+
version: 1.3.3
|
50
|
+
requirement: *id002
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
name: tilt
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 21
|
61
|
+
segments:
|
62
|
+
- 2
|
63
|
+
- 6
|
64
|
+
- 1
|
65
|
+
version: 2.6.1
|
66
|
+
requirement: *id003
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
name: minitest
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
requirement: *id004
|
81
|
+
type: :development
|
82
|
+
prerelease: false
|
83
|
+
name: rake
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 1
|
93
|
+
- 0
|
94
|
+
- 10
|
95
|
+
version: 1.0.10
|
96
|
+
requirement: *id005
|
97
|
+
type: :development
|
98
|
+
prerelease: false
|
99
|
+
name: bundler
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
hash: 11
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
- 5
|
110
|
+
- 0
|
111
|
+
version: 0.5.0
|
112
|
+
requirement: *id006
|
113
|
+
type: :development
|
114
|
+
prerelease: false
|
115
|
+
name: rack-test
|
116
|
+
- !ruby/object:Gem::Dependency
|
117
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
hash: 7
|
123
|
+
segments:
|
124
|
+
- 2
|
125
|
+
- 2
|
126
|
+
- 0
|
127
|
+
version: 2.2.0
|
128
|
+
requirement: *id007
|
129
|
+
type: :development
|
130
|
+
prerelease: false
|
131
|
+
name: haml
|
132
|
+
description: The super-friendly web framework rendering component.
|
133
|
+
email:
|
134
|
+
- joshbuddy@gmail.com
|
135
|
+
- nesquena@gmail.com
|
136
|
+
- mr.arthur.chiu@gmail.com
|
137
|
+
executables: []
|
138
|
+
|
139
|
+
extensions: []
|
140
|
+
|
141
|
+
extra_rdoc_files: []
|
142
|
+
|
143
|
+
files:
|
144
|
+
- README.md
|
145
|
+
- Rakefile
|
146
|
+
- lib/renee-render.rb
|
147
|
+
- lib/renee-render/version.rb
|
148
|
+
- renee-render.gemspec
|
149
|
+
- test/render_test.rb
|
150
|
+
- test/test_helper.rb
|
151
|
+
homepage: ""
|
152
|
+
licenses: []
|
153
|
+
|
154
|
+
post_install_message:
|
155
|
+
rdoc_options: []
|
156
|
+
|
157
|
+
require_paths:
|
158
|
+
- lib
|
159
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
160
|
+
none: false
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
hash: 3
|
165
|
+
segments:
|
166
|
+
- 0
|
167
|
+
version: "0"
|
168
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
hash: 3
|
174
|
+
segments:
|
175
|
+
- 0
|
176
|
+
version: "0"
|
177
|
+
requirements: []
|
178
|
+
|
179
|
+
rubyforge_project: renee
|
180
|
+
rubygems_version: 1.8.10
|
181
|
+
signing_key:
|
182
|
+
specification_version: 3
|
183
|
+
summary: The super-friendly web framework rendering component
|
184
|
+
test_files:
|
185
|
+
- test/render_test.rb
|
186
|
+
- test/test_helper.rb
|