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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 83f60d5460852f2b3da478f9e0b26a5086eddaa4
4
- data.tar.gz: 72f7885a1f190095646f6d4ec09f3abcc719141f
3
+ metadata.gz: 7e507562df73309d3251a7b7d4a3c12c8fc42c26
4
+ data.tar.gz: 3c74a87d9e0ae9b84aaf1b81d5917af054062f28
5
5
  SHA512:
6
- metadata.gz: c887c08827b419b6c2c674ccbae3d4aef524565430d2fca40d0eb45d79e75a4e1aa050b07fabd2d71ebca512930a95da208ea26e85ec656bc03798d6eda637eb
7
- data.tar.gz: b20d3e97269e455e7859da4e48e0f7898d8fdbabd1e8c169c13210a0ee15ee663aee6aa5a2d7577f6c3ed424170a3ccf19816c45f2580277dd79098d1a7ab8b7
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: <%= properties[:title] %></h1>
62
- <h3>And subtitle <%= properties[:subtitle] %></h3>
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.exists?(MountainView.configuration.components_path) %>
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.exists?(MountainView.configuration.components_path) %>
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
- render "#{slug}/#{slug}", properties: properties
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
@@ -1,5 +1,7 @@
1
1
  require "mountain_view/version"
2
2
  require "mountain_view/configuration"
3
+ require "mountain_view/presenter"
4
+ require "mountain_view/component"
3
5
 
4
6
  module MountainView
5
7
  def self.configuration
@@ -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
@@ -1,3 +1,3 @@
1
1
  module MountainView
2
- VERSION = "0.8.1".freeze
2
+ VERSION = "0.9.0".freeze
3
3
  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] %>"><%= properties[:title] %></a>
10
+ <a href="<%= properties[:link] %>"><%= title %></a>
11
11
  </h3>
12
- <%- if properties[:description] %>
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: "Aspen Snowmass"
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, Colorado"
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
@@ -7,6 +7,6 @@ class MountainView::ComponentHelperTest < ActionView::TestCase
7
7
  expected = /Pepe/
8
8
 
9
9
  assert_match expected, rendered
10
- assert_match /href=\"\/products\/1\"/, rendered
10
+ assert_match %r(href=\"\/products\/1\"), rendered
11
11
  end
12
12
  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.8.1
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-03-06 00:00:00.000000000 Z
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.4.5.1
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