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 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