rafters 0.2.0 → 1.0.0
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/README.md +4 -3
- data/lib/rafters/component.rb +12 -18
- data/lib/rafters/component_context.rb +10 -10
- data/lib/rafters/component_renderer.rb +2 -4
- data/lib/rafters/version.rb +1 -1
- data/rafters.gemspec +1 -0
- data/spec/dummy/app/components/post/views/post_component.html.erb +1 -1
- data/spec/dummy/app/components/posts/views/posts_component.html.erb +1 -1
- data/spec/dummy/app/views/posts/index.html.erb +3 -3
- data/spec/rafters/component_context_spec.rb +4 -11
- data/spec/rafters/component_renderer_spec.rb +0 -7
- data/spec/rafters/component_spec.rb +11 -11
- data/spec/spec_helper.rb +8 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46aa108c7fdb1430b81316137e96b4597788c632
|
4
|
+
data.tar.gz: 40bc5436d5e593f804b3d31bedc38a425ac73a79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 750fa198c767793cfec5e397b060ae88fbab408b28b3617827e6f25cf50618fdd2d6d733dc34dcbba42c4016397099f0316ce1d7ed15c571234e100413f2e491
|
7
|
+
data.tar.gz: 65f55f6c3c41678d035a9e1520f848a7f9ede30a34a81390a7686e26ca870944fd37fedc59a61d90d319c6b43f983e8bb610affa04a5d17c128b11dc9ef43700
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[](https://travis-ci.org/andyhite/rafters)
|
4
4
|
[](http://badge.fury.io/rb/rafters)
|
5
5
|
[](https://codeclimate.com/github/andyhite/rafters)
|
6
|
+
[](https://coveralls.io/r/andyhite/rafters)
|
6
7
|
|
7
8
|
Rafters lets you think about each page of your application as a collection of small pieces instead of monolithic, difficult to maintain
|
8
9
|
views.
|
@@ -61,12 +62,12 @@ The two most important files generated above are `app/rafters/[name]/[name]_comp
|
|
61
62
|
|
62
63
|
### Rendering a component
|
63
64
|
|
64
|
-
You can render components anywhere - in your view, in your controller, in another component, etc. - but the most common place will (obviously) be in your views. To render a component, call `render_component
|
65
|
+
You can render components anywhere - in your view, in your controller, in another component, etc. - but the most common place will (obviously) be in your views. To render a component, call `render_component :component_name, as: "unique-identifier"` in one of your app views. For example:
|
65
66
|
|
66
67
|
```erb
|
67
68
|
...
|
68
69
|
<div class="main">
|
69
|
-
<%= render_component :heading %>
|
70
|
+
<%= render_component :heading, as: "page-heading" %>
|
70
71
|
</div>
|
71
72
|
...
|
72
73
|
```
|
@@ -147,7 +148,7 @@ Setting values are specified when rendering a component:
|
|
147
148
|
```erb
|
148
149
|
...
|
149
150
|
<div class="main">
|
150
|
-
<%= render_component :posts, published: true %>
|
151
|
+
<%= render_component :posts, as: "published-posts", settings: { published: true } %>
|
151
152
|
</div>
|
152
153
|
...
|
153
154
|
```
|
data/lib/rafters/component.rb
CHANGED
@@ -2,13 +2,17 @@ module Rafters::Component
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
attr_writer :controller
|
5
|
+
attr_reader :identifier
|
5
6
|
|
6
7
|
included do
|
7
|
-
|
8
|
+
attributes :settings, :identifier
|
8
9
|
end
|
9
10
|
|
10
|
-
def initialize(
|
11
|
-
|
11
|
+
def initialize(options = {})
|
12
|
+
raise IdentifierMissing unless options.has_key?(:as)
|
13
|
+
|
14
|
+
@identifier = options.delete(:as)
|
15
|
+
@settings = options.delete(:settings) || {}
|
12
16
|
end
|
13
17
|
|
14
18
|
def name(without_postfix = false)
|
@@ -16,10 +20,6 @@ module Rafters::Component
|
|
16
20
|
without_postfix ? _name.gsub(/_component/, '') : _name
|
17
21
|
end
|
18
22
|
|
19
|
-
def identifier
|
20
|
-
@identifier ||= "#{name}-#{random_identifier}"
|
21
|
-
end
|
22
|
-
|
23
23
|
def template_name
|
24
24
|
@_template_name ||= begin
|
25
25
|
_template_name = (self.class._template_name || self.class.name.underscore)
|
@@ -43,7 +43,7 @@ module Rafters::Component
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def settings
|
46
|
-
@_settings ||= Hashie::Mash.new(@settings.
|
46
|
+
@_settings ||= Hashie::Mash.new(defaults.merge(@settings).merge(overrides))
|
47
47
|
end
|
48
48
|
|
49
49
|
def defaults
|
@@ -55,8 +55,10 @@ module Rafters::Component
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def overrides
|
58
|
+
return {} if @controller.nil?
|
59
|
+
|
58
60
|
@_overrides ||= Hashie::Mash.new.tap do |_overrides|
|
59
|
-
(controller(:params)[
|
61
|
+
(controller(:params)[identifier] || {}).each do |name, value|
|
60
62
|
_overrides[name] = value
|
61
63
|
end
|
62
64
|
end
|
@@ -78,14 +80,6 @@ module Rafters::Component
|
|
78
80
|
|
79
81
|
private
|
80
82
|
|
81
|
-
def random_seed
|
82
|
-
rand(DateTime.now.to_i).to_s
|
83
|
-
end
|
84
|
-
|
85
|
-
def random_identifier
|
86
|
-
Digest::MD5.hexdigest(random_seed)[0..6]
|
87
|
-
end
|
88
|
-
|
89
83
|
module ClassMethods
|
90
84
|
attr_accessor :_attributes, :_defaults, :_template_name
|
91
85
|
|
@@ -112,6 +106,6 @@ module Rafters::Component
|
|
112
106
|
end
|
113
107
|
end
|
114
108
|
|
115
|
-
class
|
109
|
+
class IdentifierMissing < StandardError; end
|
116
110
|
class InvalidSetting < StandardError; end
|
117
111
|
end
|
@@ -8,23 +8,23 @@ module Rafters::ComponentContext
|
|
8
8
|
alias_method_chain :render, :component
|
9
9
|
end
|
10
10
|
|
11
|
-
def component_attributes(name,
|
12
|
-
component = component(name,
|
11
|
+
def component_attributes(name, options = {})
|
12
|
+
component = component(name, options)
|
13
13
|
component.as_json
|
14
14
|
end
|
15
15
|
|
16
|
-
def render_component(name,
|
17
|
-
component = component(name,
|
18
|
-
component_renderer.render(component
|
16
|
+
def render_component(name, options = {})
|
17
|
+
component = component(name, options)
|
18
|
+
component_renderer.render(component)
|
19
19
|
end
|
20
20
|
|
21
21
|
def render_with_component(*args, &block)
|
22
22
|
if params[:component]
|
23
|
-
component, settings = params[:component], params[:
|
23
|
+
component, settings = params[:component], params[:options]
|
24
24
|
|
25
25
|
respond_to do |format|
|
26
|
-
format.html { render_without_component(text: render_component(component,
|
27
|
-
format.json { render_without_component(json: component_attributes(component,
|
26
|
+
format.html { render_without_component(text: render_component(component, options)) }
|
27
|
+
format.json { render_without_component(json: component_attributes(component, options)) }
|
28
28
|
end
|
29
29
|
else
|
30
30
|
render_without_component(*args, &block)
|
@@ -37,8 +37,8 @@ module Rafters::ComponentContext
|
|
37
37
|
@_component_renderer ||= Rafters::ComponentRenderer.new(self)
|
38
38
|
end
|
39
39
|
|
40
|
-
def component(name,
|
40
|
+
def component(name, options = {})
|
41
41
|
component_klass = "#{name}_component".classify.constantize
|
42
|
-
component = component_klass.new(
|
42
|
+
component = component_klass.new(options)
|
43
43
|
end
|
44
44
|
end
|
@@ -7,15 +7,13 @@ class Rafters::ComponentRenderer
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
def render(component
|
10
|
+
def render(component)
|
11
11
|
component.controller = @controller
|
12
12
|
|
13
|
-
template_name = (template_name || component.template_name)
|
14
|
-
|
15
13
|
store(component)
|
16
14
|
|
17
15
|
@controller.view_context.content_tag(:div, class: "component", id: component.identifier) do
|
18
|
-
@controller.view_context.render(file: "/#{template_name}", locals: component.attributes)
|
16
|
+
@controller.view_context.render(file: "/#{component.template_name}", locals: component.attributes)
|
19
17
|
end
|
20
18
|
end
|
21
19
|
|
data/lib/rafters/version.rb
CHANGED
data/rafters.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "rspec-rails", "~> 2.14"
|
25
25
|
spec.add_development_dependency "capybara", "~> 2.1"
|
26
26
|
spec.add_development_dependency "yard", "~> 0.8"
|
27
|
+
spec.add_development_dependency 'coveralls', "~> 0.6.7"
|
27
28
|
|
28
29
|
spec.add_dependency "rails", "> 3.2"
|
29
30
|
spec.add_dependency "sprockets", "> 2.2"
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<h2><%= link_to_if settings.link_to_post?, post.title, post_path(post.id) %></h2>
|
2
2
|
|
3
|
-
<%= render_component :author, id: post.author.id %>
|
3
|
+
<%= render_component :author, as: "author-#{post.author.id}", settings: { id: post.author.id } %>
|
4
4
|
|
5
5
|
<%= simple_format post.body %>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<div class="main">
|
2
2
|
<div class="content">
|
3
|
-
<%= render_component :heading, title: "Posts" %>
|
4
|
-
<%= render_component :posts %>
|
3
|
+
<%= render_component :heading, as: "heading", settings: { title: "Posts" } %>
|
4
|
+
<%= render_component :posts, as: "posts" %>
|
5
5
|
</div>
|
6
6
|
|
7
7
|
<div class="sidebar">
|
8
|
-
<%= render_component :links %>
|
8
|
+
<%= render_component :links, as: "links" %>
|
9
9
|
</div>
|
10
10
|
</div>
|
@@ -18,21 +18,14 @@ describe Rafters::ComponentContext do
|
|
18
18
|
|
19
19
|
describe "#render_component" do
|
20
20
|
it "renders the provided component" do
|
21
|
-
renderer.should_receive(:render).with(instance_of(FooComponent)
|
22
|
-
controller.render_component(:foo)
|
21
|
+
renderer.should_receive(:render).with(instance_of(FooComponent))
|
22
|
+
controller.render_component(:foo, as: "foo")
|
23
23
|
end
|
24
24
|
|
25
25
|
context "with settings" do
|
26
26
|
it "renders the provided component with the given settings" do
|
27
|
-
FooComponent.should_receive(:new).with({ test: true })
|
28
|
-
controller.render_component(:foo, test: true)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context "with a specified template name" do
|
33
|
-
it "renders the provided component using the given template name" do
|
34
|
-
renderer.should_receive(:render).with(instance_of(FooComponent), "template_name")
|
35
|
-
controller.render_component(:foo, {}, "template_name")
|
27
|
+
FooComponent.should_receive(:new).with({ as: "foo", settings: { test: true } })
|
28
|
+
controller.render_component(:foo, { as: "foo", settings: { test: true } })
|
36
29
|
end
|
37
30
|
end
|
38
31
|
end
|
@@ -35,12 +35,5 @@ describe Rafters::ComponentRenderer do
|
|
35
35
|
view_context.should_receive(:render).with(file: "/template", locals: { title: "Foo" })
|
36
36
|
subject.render(component)
|
37
37
|
end
|
38
|
-
|
39
|
-
context "with a specified template name" do
|
40
|
-
it "renders the component with the specified template" do
|
41
|
-
view_context.should_receive(:render).with(file: "/custom_template", locals: { title: "Foo" })
|
42
|
-
subject.render(component, "custom_template")
|
43
|
-
end
|
44
|
-
end
|
45
38
|
end
|
46
39
|
end
|
@@ -17,7 +17,7 @@ describe Rafters::Component do
|
|
17
17
|
HeadingComponent.send(:define_method, :title, -> { "Lorem Ipsum" })
|
18
18
|
HeadingComponent.attribute(:title)
|
19
19
|
|
20
|
-
heading = HeadingComponent.new
|
20
|
+
heading = HeadingComponent.new(as: "heading")
|
21
21
|
heading.attributes.should have_key(:title)
|
22
22
|
end
|
23
23
|
end
|
@@ -28,7 +28,7 @@ describe Rafters::Component do
|
|
28
28
|
HeadingComponent.send(:define_method, :subtitle, -> { "Dolor Sit Amet" })
|
29
29
|
HeadingComponent.attributes(:title, :subtitle)
|
30
30
|
|
31
|
-
heading = HeadingComponent.new
|
31
|
+
heading = HeadingComponent.new(as: "heading")
|
32
32
|
heading.attributes.keys.map(&:to_sym).should include(:title)
|
33
33
|
heading.attributes.keys.map(&:to_sym).should include(:subtitle)
|
34
34
|
end
|
@@ -38,7 +38,7 @@ describe Rafters::Component do
|
|
38
38
|
it "adds default values to the component settings" do
|
39
39
|
HeadingComponent.defaults(foo: "bar")
|
40
40
|
|
41
|
-
heading = HeadingComponent.new
|
41
|
+
heading = HeadingComponent.new(as: "heading")
|
42
42
|
heading.settings.foo.should == "bar"
|
43
43
|
end
|
44
44
|
end
|
@@ -49,15 +49,15 @@ describe Rafters::Component do
|
|
49
49
|
HeadingComponent.attribute(:title)
|
50
50
|
end
|
51
51
|
|
52
|
-
subject { HeadingComponent.new }
|
52
|
+
subject { HeadingComponent.new(as: "heading") }
|
53
53
|
|
54
54
|
it "returns the registered attributes and their values" do
|
55
|
-
subject.attributes.should == Hashie::Mash.new({ title: "Lorem Ipsum", settings: {} })
|
55
|
+
subject.attributes.should == Hashie::Mash.new({ title: "Lorem Ipsum", identifier: "heading", settings: {} })
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
describe "#settings" do
|
60
|
-
subject { HeadingComponent.new({ type: "h2" }) }
|
60
|
+
subject { HeadingComponent.new(as: "heading", settings: { type: "h2" }) }
|
61
61
|
|
62
62
|
it "returns the provided settings" do
|
63
63
|
subject.settings.should == Hashie::Mash.new({ type: "h2" })
|
@@ -70,7 +70,7 @@ describe Rafters::Component do
|
|
70
70
|
end
|
71
71
|
|
72
72
|
describe "#template_name" do
|
73
|
-
subject { HeadingComponent.new }
|
73
|
+
subject { HeadingComponent.new(as: "heading") }
|
74
74
|
|
75
75
|
context "with no specified template name" do
|
76
76
|
it "returns the inferred template name" do
|
@@ -103,7 +103,7 @@ describe Rafters::Component do
|
|
103
103
|
end
|
104
104
|
|
105
105
|
describe "#controller" do
|
106
|
-
subject { HeadingComponent.new }
|
106
|
+
subject { HeadingComponent.new(as: "heading") }
|
107
107
|
|
108
108
|
let(:controller) { Object.new }
|
109
109
|
|
@@ -132,8 +132,8 @@ describe Rafters::Component do
|
|
132
132
|
end
|
133
133
|
|
134
134
|
context "when there is neither a method nor an instance variable with the given name in the controller" do
|
135
|
-
it "
|
136
|
-
|
135
|
+
it "returns nil" do
|
136
|
+
subject.controller(:doesnt_exist).should == nil
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
@@ -141,7 +141,7 @@ describe Rafters::Component do
|
|
141
141
|
after do
|
142
142
|
# A little housekeeping after each spec runs, so that
|
143
143
|
# we have fresh values for each class attribute
|
144
|
-
HeadingComponent._attributes = [:settings]
|
144
|
+
HeadingComponent._attributes = [:settings, :identifier]
|
145
145
|
HeadingComponent._defaults = {}
|
146
146
|
HeadingComponent._template_name = nil
|
147
147
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
Coveralls.wear!
|
3
|
+
|
4
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
5
|
+
SimpleCov.start do
|
6
|
+
add_filter 'spec/dummy'
|
7
|
+
end
|
8
|
+
|
1
9
|
ENV["RAILS_ENV"] ||= 'test'
|
2
10
|
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
3
11
|
require 'rspec/rails'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rafters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Hite
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ~>
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0.8'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: coveralls
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.6.7
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.6.7
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: rails
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|