Skip to content

Commit 1dd578d

Browse files
authored
Merge pull request #477 from matestack/20201120_enable_viewcontext_for_standalone_components
20201120 enable viewcontext for standalone components
2 parents 9c2f305 + 320d89d commit 1dd578d

File tree

15 files changed

+61
-14
lines changed

15 files changed

+61
-14
lines changed

app/concepts/matestack/ui/core/component/base.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ def add_child(child_class, *args, &block)
245245

246246
# check only allowed keys are passed to isolated components
247247
if child_class < Matestack::Ui::Core::Isolated::Isolated
248-
unless args.empty? || args[0].keys.all? { |key| [:defer, :public_options, :rerender_on, :init_on, :rerender_delay, :matestack_context].include? key }
248+
unless args.empty? || args[0].keys.all? { |key| [:defer, :public_options, :rerender_on, :init_on, :rerender_delay, :matestack_context, :context].include? key }
249249
raise "isolated components can only take params in a public_options hash, which will be exposed to the client side in order to perform an async request with these params."
250250
end
251251
if args.any? { |arg| arg[:init_on].present? } && @matestack_skip_defer == true

app/helpers/matestack/ui/core/application_helper.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ def matestack_component(component, options = {}, &block)
102102
controller = (self.class <= ActionController::Base) ? self : @_controller
103103
context = (options[:matestack_context] ||= {}).merge(controller: controller)
104104
Matestack::Ui::Core::Component::Base
105-
.new(options.merge(matestack_context: context))
106-
.send(component, options.merge(matestack_context: context), &block).to_s
105+
.new(options.merge(context: context, matestack_context: context))
106+
.send(component, options.merge(context: context, matestack_context: context), &block).to_s
107107
end
108108
end
109109
end

app/lib/matestack/ui/core/has_view_context.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ module Matestack::Ui::Core::HasViewContext
22
def initialize(*args)
33
super
44
@view_context = @options.dig(:context, :view_context)
5+
unless @view_context
6+
@view_context = @options.dig(:matestack_context, :controller)&.view_context
7+
end
58
end
6-
79
def method_missing(*args, &block)
810
if @view_context.respond_to? args.first
911
@view_context.send(*args, &block)
1012
else
1113
raise NameError, "NameError: undefined method or local variable `#{args.first}' for #{self.class.name}"
1214
end
1315
end
14-
end
16+
end

app/lib/matestack/ui/core/rendering/main_renderer.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,14 @@ def render(controller_instance, page_class, options)
6161
end
6262
end
6363

64+
# needs refactoring!
65+
# we shouldn't pass in the parts of the controller_instance and the instance itself
6466
def create_context_hash(controller_instance)
6567
{
6668
view_context: controller_instance.view_context,
6769
params: controller_instance.params,
68-
request: controller_instance.request
70+
request: controller_instance.request,
71+
controller: controller_instance # if this is not included here, rails route helpers will fail with undefined method `url_options' for nil:NilClass in some cases
6972
}
7073
end
7174

docs/ui_components/100-rails_integration/README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@ The easiest way to integrate Matestack is by creating custom components and usin
1414

1515
This is a perfect place to start refactoring our application to use matestack. It's easy to start from the inside out, first replacing parts of your UI with components. As partials already are used to structure your UI in smaller reusable parts they are a perfect starting point. So let's refactor our product teaser into a custom component.
1616

17-
After successfully following the [installation guide](/docs/start/100-installation/README.md) we can start. Remember to set the id "matestack-ui" in your corresponding layout.
17+
After successfully following the [installation guide](/docs/start/100-installation/README.md) we can start.
1818

1919
Start by creating a file called `teaser.rb` in `app/matestack/components/products/teaser.rb`. Placement of this file is as you see similar to our partial. In this file we implement our component in pure ruby as follows:
2020

2121
```ruby
2222
class Components::Products::Teaser < Matestack::Ui::Component
23-
include ::Rails.application.routes.url_helpers
2423

2524
requires :product
2625

@@ -37,7 +36,7 @@ class Components::Products::Teaser < Matestack::Ui::Component
3736
end
3837
```
3938

40-
We inherit from `Matestack::Ui::Component` to create our teaser component. As it should display product informations it requires a product. We can access this product through a getter method `product`. To access Rails url helpers we have to include `Rails.application.routes.url_helpers` as components usually get access to them through the pages but we render our component outside a Matestack page. Now we have now a teaser component, but in order to use it we have to register it and include our registration in our `ApplicationController`.
39+
We inherit from `Matestack::Ui::Component` to create our teaser component. As it should display product informations it requires a product. We can access this product through a getter method `product`. Now we have now a teaser component, but in order to use it we have to register it and include our registration in our `ApplicationController`.
4140

4241
Let's register our component by creating a component registry in `app/matestack/components/registry.rb`.
4342

spec/dummy/app/controllers/legacy_views/pages_controller.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ class LegacyViews::PagesController < ApplicationController
66

77
def action_inline
88
end
9-
9+
1010
def action_custom_component
1111
@title = 'Test Title'
1212
end
13-
13+
1414
def async_custom_component
1515
end
16-
16+
1717
def async_inline
1818
end
1919

@@ -45,6 +45,9 @@ def form_custom_component
4545
def onclick_custom_component
4646
end
4747

48+
def viewcontext_custom_component
49+
end
50+
4851
def isolated_custom_component
4952
render 'isolated_custom_component'
5053
end
@@ -78,4 +81,4 @@ def dummy_model_params
7881
)
7982
end
8083

81-
end
84+
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Components::LegacyViews::Pages::Viewcontext < Matestack::Ui::Component
2+
3+
def response
4+
div id: "my-component" do
5+
if @view_context.view_renderer.instance_of?(ActionView::Renderer)
6+
plain "has access to ActionView Context"
7+
end
8+
plain link_to "Test Link", "/some/page" # calling an ActionView Url Helper here
9+
plain time_ago_in_words(3.minutes.from_now) # calling an ActionView Date Helper here
10+
plain "root_path: #{root_path}" # calling a Path Helper here
11+
end
12+
end
13+
14+
end

spec/dummy/app/matestack/components/registry.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module Components::Registry
1313
legacy_views_pages_form: Components::LegacyViews::Pages::Form,
1414
legacy_views_pages_onclick: Components::LegacyViews::Pages::Onclick,
1515
legacy_views_pages_isolated: Components::LegacyViews::Pages::Isolated,
16+
legacy_views_pages_viewcontext: Components::LegacyViews::Pages::Viewcontext,
1617
)
1718

1819
end
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<h1>Isolated Custom Component</h1>
22
<%=
33
matestack_component(:legacy_views_pages_isolated, rerender_on: 'update_time' )
4-
%>
4+
%>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<h1>Viewcontext Custom Component</h1>
2+
<%= matestack_component(:legacy_views_pages_viewcontext) %>

0 commit comments

Comments
 (0)