mountain_view 0.8.1 → 0.9.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/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
|