mountain_view 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +34 -2
- data/app/assets/javascripts/mountain_view.js.erb +1 -1
- data/app/assets/stylesheets/mountain_view.css.erb +1 -1
- data/app/helpers/mountain_view/component_helper.rb +2 -1
- data/lib/mountain_view.rb +2 -0
- data/lib/mountain_view/engine.rb +6 -2
- data/lib/mountain_view/presenter.rb +77 -0
- data/lib/mountain_view/version.rb +1 -1
- data/test/dummy/app/components/card/_card.html.erb +4 -3
- data/test/dummy/app/components/card/card.yml +4 -2
- data/test/dummy/app/components/card/card_component.rb +14 -0
- data/test/generators/component_generator_test.rb +5 -4
- data/test/helpers/mountain_view/component_helper_test.rb +1 -1
- data/test/mountain_view/presenter_test.rb +38 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e507562df73309d3251a7b7d4a3c12c8fc42c26
|
4
|
+
data.tar.gz: 3c74a87d9e0ae9b84aaf1b81d5917af054062f28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70cceab5e5b95b321ac3e3566076e2591f275697f307fc2ecd7c3005508052e908f32a4c2791a0108402537d8f0226af9dc5b41b2a13cfd56c9811e92ad9ea53
|
7
|
+
data.tar.gz: 03c34700700d0b959212f95ac163cfc18bde9865138753ac1ad9f42dd362a65e995ce9ebf4f9e383a4837732536a607a7e2e818d8f3427f2d0abe5b52b498346
|
data/README.md
CHANGED
@@ -26,6 +26,8 @@ Then execute:
|
|
26
26
|
|
27
27
|
$ bundle
|
28
28
|
|
29
|
+
Mountain View supports Ruby 2.0+.
|
30
|
+
|
29
31
|
## Usage
|
30
32
|
|
31
33
|
Use the built-in generator to create a new component:
|
@@ -44,6 +46,7 @@ app/
|
|
44
46
|
header.css
|
45
47
|
header.js
|
46
48
|
header.yml
|
49
|
+
header_component.rb # optional
|
47
50
|
```
|
48
51
|
|
49
52
|
Keep in mind that you can also use `scss`, `coffeescript`, `haml`, or any other
|
@@ -58,11 +61,40 @@ coffee-script as long as you have these preprocessors running on your app.
|
|
58
61
|
```erb
|
59
62
|
<!-- app/components/header/_header.html.erb -->
|
60
63
|
<div class="header">
|
61
|
-
<h1>This is a header component with the title: <%=
|
62
|
-
<h3>And subtitle <%=
|
64
|
+
<h1>This is a header component with the title: <%= title %></h1>
|
65
|
+
<h3>And subtitle <%= subtitle %></h3>
|
66
|
+
<% if show_links? %>
|
67
|
+
<ul>
|
68
|
+
<% links.each do |link| %>
|
69
|
+
<li><%= link %></li>
|
70
|
+
<% end %>
|
71
|
+
</ul>
|
72
|
+
<% end %>
|
63
73
|
</div>
|
64
74
|
```
|
65
75
|
|
76
|
+
```ruby
|
77
|
+
# app/components/header/header_component.rb
|
78
|
+
class HeaderComponent < MountainView::Presenter
|
79
|
+
properties :title, :subtitle
|
80
|
+
property :links, default: []
|
81
|
+
|
82
|
+
def title
|
83
|
+
properties[:title].titleize
|
84
|
+
end
|
85
|
+
|
86
|
+
def show_links?
|
87
|
+
links.any?
|
88
|
+
end
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
Including a component class is optional, but it helps avoid polluting your
|
93
|
+
views and helpers with presenter logic. Public methods in your component class
|
94
|
+
will be made available to the view, along with any properties you define.
|
95
|
+
You can also access all properties using the `properties` method in your
|
96
|
+
component class and views. You can even define property defaults.
|
97
|
+
|
66
98
|
### Using components on your views
|
67
99
|
You can then call your components on any view by using the following
|
68
100
|
helper:
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<% if Dir.
|
1
|
+
<% if Dir.exist?(MountainView.configuration.components_path) %>
|
2
2
|
<% depend_on MountainView.configuration.components_path.to_s %>
|
3
3
|
<% Dir.glob(MountainView.configuration.components_path.join('*')).each do |component_dir|
|
4
4
|
component = File.basename component_dir
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% MountainView.configuration.included_stylesheets.each do |included_stylesheet| %>
|
2
2
|
<%= require_asset included_stylesheet %>
|
3
3
|
<% end %>
|
4
|
-
<% if Dir.
|
4
|
+
<% if Dir.exist?(MountainView.configuration.components_path) %>
|
5
5
|
<% depend_on MountainView.configuration.components_path.to_s %>
|
6
6
|
<% Dir.glob(MountainView.configuration.components_path.join('*')).each do |component_dir|
|
7
7
|
component = File.basename component_dir
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module MountainView
|
2
2
|
module ComponentHelper
|
3
3
|
def render_component(slug, properties = {})
|
4
|
-
|
4
|
+
component = MountainView::Presenter.component_for(slug, properties)
|
5
|
+
component.render(controller.view_context)
|
5
6
|
end
|
6
7
|
end
|
7
8
|
end
|
data/lib/mountain_view.rb
CHANGED
data/lib/mountain_view/engine.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
require "rails"
|
2
|
-
require "mountain_view"
|
3
|
-
require "mountain_view/component"
|
4
2
|
|
5
3
|
module MountainView
|
6
4
|
class Engine < ::Rails::Engine
|
@@ -12,6 +10,12 @@ module MountainView
|
|
12
10
|
end
|
13
11
|
end
|
14
12
|
|
13
|
+
initializer "mountain_view.load_component_classes",
|
14
|
+
before: :set_autoload_paths do |app|
|
15
|
+
component_paths = "#{MountainView.configuration.components_path}/{*}"
|
16
|
+
app.config.autoload_paths += Dir[component_paths]
|
17
|
+
end
|
18
|
+
|
15
19
|
initializer "mountain_view.assets" do |app|
|
16
20
|
Rails.application.config.assets.paths <<
|
17
21
|
MountainView.configuration.components_path
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module MountainView
|
2
|
+
class Presenter
|
3
|
+
class_attribute :_properties, instance_accessor: false
|
4
|
+
self._properties = {}
|
5
|
+
|
6
|
+
attr_reader :slug, :properties
|
7
|
+
|
8
|
+
def initialize(slug, properties = {})
|
9
|
+
@slug = slug
|
10
|
+
@properties = default_properties.deep_merge(properties)
|
11
|
+
end
|
12
|
+
|
13
|
+
def render(context)
|
14
|
+
context.extend ViewContext
|
15
|
+
context.inject_component_context self
|
16
|
+
context.render partial: partial
|
17
|
+
end
|
18
|
+
|
19
|
+
def partial
|
20
|
+
"#{slug}/#{slug}"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def default_properties
|
26
|
+
self.class._properties.inject({}) do |sum, (k, v)|
|
27
|
+
sum[k] = v[:default]
|
28
|
+
sum
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class << self
|
33
|
+
def component_for(*args)
|
34
|
+
klass = "#{args.first.to_s.camelize}Component".safe_constantize
|
35
|
+
klass ||= self
|
36
|
+
klass.new(*args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def properties(*args)
|
40
|
+
opts = args.extract_options!
|
41
|
+
properties = args.inject({}) do |sum, name|
|
42
|
+
sum[name] = opts
|
43
|
+
sum
|
44
|
+
end
|
45
|
+
define_property_methods(args)
|
46
|
+
self._properties = _properties.merge(properties)
|
47
|
+
end
|
48
|
+
alias_method :property, :properties
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def define_property_methods(names = [])
|
53
|
+
names.each do |name|
|
54
|
+
next if method_defined?(name)
|
55
|
+
define_method name do
|
56
|
+
properties[name.to_sym]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module ViewContext
|
63
|
+
attr_reader :_component
|
64
|
+
delegate :properties, to: :_component
|
65
|
+
|
66
|
+
def inject_component_context(component)
|
67
|
+
@_component = component
|
68
|
+
protected_methods = MountainView::Presenter.public_methods(false)
|
69
|
+
methods = component.public_methods(false) - protected_methods
|
70
|
+
methods.each do |meth|
|
71
|
+
next if self.class.method_defined?(meth)
|
72
|
+
self.class.delegate meth, to: :_component
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -7,11 +7,12 @@
|
|
7
7
|
<% end %>
|
8
8
|
<div class="card__content">
|
9
9
|
<h3 class="card__content__title">
|
10
|
-
<a href="<%= properties[:link] %>"><%=
|
10
|
+
<a href="<%= properties[:link] %>"><%= title %></a>
|
11
11
|
</h3>
|
12
|
-
<%- if
|
12
|
+
<%- if has_description? %>
|
13
13
|
<p><%= properties[:description] %></p>
|
14
14
|
<%- end %>
|
15
|
+
<p>Location: <%= location %></p>
|
15
16
|
<div class="card__content__data">
|
16
17
|
<%- if properties[:data] && properties[:data].any? %>
|
17
18
|
<%- properties[:data].each do |data| %>
|
@@ -23,4 +24,4 @@
|
|
23
24
|
<% end %>
|
24
25
|
</div>
|
25
26
|
</div>
|
26
|
-
</div>
|
27
|
+
</div>
|
@@ -1,5 +1,6 @@
|
|
1
1
|
-
|
2
|
-
:title: "
|
2
|
+
:title: "Snowmass"
|
3
|
+
:location: "Aspen"
|
3
4
|
:description: "Aspen Snowmass is a winter resort complex located in Pitkin County in western Colorado in the United States. Owned and operated by the Aspen Skiing Company it comprises four skiing/snowboarding areas on four adjacent mountains in the vicinity of the towns of Aspen and Snowmass Village."
|
4
5
|
:link: "http://google.com"
|
5
6
|
:image_url: "http://i.imgur.com/QzuIJTo.jpg"
|
@@ -13,7 +14,8 @@
|
|
13
14
|
|
14
15
|
|
15
16
|
-
|
16
|
-
:title: "Breckenridge
|
17
|
+
:title: "Breckenridge"
|
18
|
+
:location: "Colorado"
|
17
19
|
:link: "http://facebook.com"
|
18
20
|
:image_url: "http://i.imgur.com/w7ZyWPg.jpg"
|
19
21
|
:data:
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CardComponent < MountainView::Presenter
|
2
|
+
include ActionView::Helpers::TagHelper
|
3
|
+
|
4
|
+
properties :title, :description, :link, :image_url, :location
|
5
|
+
property :data, default: []
|
6
|
+
|
7
|
+
def title
|
8
|
+
[location, properties[:title]].compact.join(", ")
|
9
|
+
end
|
10
|
+
|
11
|
+
def has_description?
|
12
|
+
description.present?
|
13
|
+
end
|
14
|
+
end
|
@@ -7,14 +7,17 @@ class ComponentGeneratorTest < Rails::Generators::TestCase
|
|
7
7
|
setup :prepare_destination
|
8
8
|
|
9
9
|
test "Assert all files are properly created" do
|
10
|
+
# reset engines
|
11
|
+
Rails.application.config.app_generators.template_engine nil
|
12
|
+
Rails.application.config.app_generators.stylesheet_engine nil
|
13
|
+
Rails.application.config.app_generators.javascript_engine nil
|
14
|
+
|
10
15
|
run_generator %w( widget )
|
11
16
|
|
12
17
|
assert_file "app/components/widget/_widget.html.erb"
|
13
18
|
assert_file "app/components/widget/widget.css"
|
14
19
|
assert_file "app/components/widget/widget.js"
|
15
20
|
assert_file "app/components/widget/widget.yml"
|
16
|
-
# Delete generated files so the test don't fail if the order is random
|
17
|
-
FileUtils.remove_dir(File.expand_path("../../tmp", __FILE__))
|
18
21
|
end
|
19
22
|
|
20
23
|
test "Generates different engines" do
|
@@ -28,7 +31,5 @@ class ComponentGeneratorTest < Rails::Generators::TestCase
|
|
28
31
|
assert_file "app/components/widget/widget.scss"
|
29
32
|
assert_file "app/components/widget/widget.coffee"
|
30
33
|
assert_file "app/components/widget/widget.yml"
|
31
|
-
# Delete generated files so the test don't fail if the order is random
|
32
|
-
FileUtils.remove_dir(File.expand_path("../../tmp", __FILE__))
|
33
34
|
end
|
34
35
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class InheritedPresenter < MountainView::Presenter
|
4
|
+
properties :title, :description
|
5
|
+
property :data, default: []
|
6
|
+
|
7
|
+
def title
|
8
|
+
"Foo#{properties[:title].downcase}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class MountainView::PresenterTest < ActiveSupport::TestCase
|
13
|
+
test "returns the correct partial path" do
|
14
|
+
presenter = MountainView::Presenter.new("header")
|
15
|
+
assert_equal "header/header", presenter.partial
|
16
|
+
end
|
17
|
+
|
18
|
+
test "exposes properties as provided" do
|
19
|
+
properties = { foo: "bar", hello: "world" }
|
20
|
+
presenter = MountainView::Presenter.new("header", properties)
|
21
|
+
assert_equal properties, presenter.properties
|
22
|
+
end
|
23
|
+
|
24
|
+
test "inherited presenter returns the correct title" do
|
25
|
+
presenter = InheritedPresenter.new("inherited", title: "Bar")
|
26
|
+
assert_equal "Foobar", presenter.title
|
27
|
+
end
|
28
|
+
|
29
|
+
test "inherited presenter responds to #data" do
|
30
|
+
presenter = InheritedPresenter.new("inherited", data: ["Foobar"])
|
31
|
+
assert_equal ["Foobar"], presenter.data
|
32
|
+
end
|
33
|
+
|
34
|
+
test "inherited presenter returns the default value for #data" do
|
35
|
+
presenter = InheritedPresenter.new("inherited", {})
|
36
|
+
assert_equal [], presenter.data
|
37
|
+
end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mountain_view
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ignacio Gutierrez
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-06-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- lib/mountain_view/component.rb
|
72
72
|
- lib/mountain_view/configuration.rb
|
73
73
|
- lib/mountain_view/engine.rb
|
74
|
+
- lib/mountain_view/presenter.rb
|
74
75
|
- lib/mountain_view/version.rb
|
75
76
|
- lib/tasks/mountain_view_tasks.rake
|
76
77
|
- test/dummy/README.rdoc
|
@@ -86,6 +87,7 @@ files:
|
|
86
87
|
- test/dummy/app/components/card/card.css
|
87
88
|
- test/dummy/app/components/card/card.js
|
88
89
|
- test/dummy/app/components/card/card.yml
|
90
|
+
- test/dummy/app/components/card/card_component.rb
|
89
91
|
- test/dummy/app/components/header/_header.html.erb
|
90
92
|
- test/dummy/app/components/header/header.css
|
91
93
|
- test/dummy/app/components/header/header.js
|
@@ -128,6 +130,7 @@ files:
|
|
128
130
|
- test/helpers/mountain_view/component_helper_test.rb
|
129
131
|
- test/mountain_view/component_test.rb
|
130
132
|
- test/mountain_view/configuration_test.rb
|
133
|
+
- test/mountain_view/presenter_test.rb
|
131
134
|
- test/mountain_view_test.rb
|
132
135
|
- test/test_helper.rb
|
133
136
|
- test/tmp/app/components/widget/_widget.html.haml
|
@@ -154,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
157
|
version: '0'
|
155
158
|
requirements: []
|
156
159
|
rubyforge_project:
|
157
|
-
rubygems_version: 2.
|
160
|
+
rubygems_version: 2.6.2
|
158
161
|
signing_key:
|
159
162
|
specification_version: 4
|
160
163
|
summary: Mountain View helps you create reusable visual components on your Rails Application.
|
@@ -170,6 +173,7 @@ test_files:
|
|
170
173
|
- test/dummy/app/components/card/card.css
|
171
174
|
- test/dummy/app/components/card/card.js
|
172
175
|
- test/dummy/app/components/card/card.yml
|
176
|
+
- test/dummy/app/components/card/card_component.rb
|
173
177
|
- test/dummy/app/components/header/_header.html.erb
|
174
178
|
- test/dummy/app/components/header/header.css
|
175
179
|
- test/dummy/app/components/header/header.js
|
@@ -214,6 +218,7 @@ test_files:
|
|
214
218
|
- test/helpers/mountain_view/component_helper_test.rb
|
215
219
|
- test/mountain_view/component_test.rb
|
216
220
|
- test/mountain_view/configuration_test.rb
|
221
|
+
- test/mountain_view/presenter_test.rb
|
217
222
|
- test/mountain_view_test.rb
|
218
223
|
- test/test_helper.rb
|
219
224
|
- test/tmp/app/components/widget/_widget.html.haml
|