Skip to content

Commit 0200bdd

Browse files
committed
improved action_view_helper integration through new detached to_s rendering helper, specs will be added later
1 parent 72172d4 commit 0200bdd

File tree

4 files changed

+92
-26
lines changed

4 files changed

+92
-26
lines changed

docs/html-rendering/integrating-action-view-helpers.md

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,71 @@
1-
---
2-
description: Still WIP --> 3.0 and future 3.1 changes needs to be added here
3-
---
4-
51
# Integrating Action View Helpers
62

7-
Using Rails view helpers ([https://api.rubyonrails.org/classes/ActionView/Helpers.html](https://api.rubyonrails.org/classes/ActionView/Helpers.html)) in components, pages and apps is supported with some limitations currently. 
3+
Using Rails view helpers ([https://api.rubyonrails.org/classes/ActionView/Helpers.html](https://api.rubyonrails.org/classes/ActionView/Helpers.html)) in components, pages and layouts is supported when using the approaches shown below;
84

95
## Helpers without a block
106

11-
You just have to put a `plain` before a view helper, if this view helper is rendering a HTML string, for example:
7+
Simple Action View helpers working without a block, can easily be integrated in a Matestack class response by calling `plain`:
128

139
```ruby
14-
plain link_to "Show", post_path(@post)
10+
def response
11+
plain t("my.locale")
12+
# ...
13+
plain link_to "Show", post_path(@post)
14+
# ...
15+
plain my_own_view_helper_method
16+
# ...
17+
plain any_method_returning_a_string
18+
end
19+
```
20+
21+
## Helpers yielding a block
22+
23+
If you want to use a helper like `form_for` you have to follow following approach:
24+
25+
```ruby
26+
def response
27+
# ...
28+
plain do # <-- add this
29+
form_with url: "/some_path" do |f|
30+
matestack_to_s do # <-- add this, which converst following block to a string
31+
plain f.text_field :foo # <-- call plain here again
32+
br
33+
div class: "some-input-wrapper" do
34+
plain f.text_field :bar
35+
end
36+
br
37+
plain f.submit
38+
end
39+
end
40+
end
41+
# ...
42+
plain do
43+
link_to root_path do
44+
matestack_to_s do
45+
div class: "some-link-wrapper" do
46+
plain "foo from block"
47+
end
48+
end
49+
end
50+
end
51+
# ...
52+
# Code below will not work!
53+
plain link_to root_path do
54+
matestack_to_s do
55+
div class: "some-link-wrapper" do
56+
plain "foo from block"
57+
end
58+
end
59+
end
60+
end
1561
```
1662

1763
{% hint style="info" %}
1864
A component needs to be called in context of a controller (with included `Matestack::Ui::Core::Helper`), which is true when you're calling components from Rails views or on Matestack Pages/Layouts (which are themselves called by a controller normally).
1965

20-
When calling a component in isolation (which is possible), the view helpers might not work properly!
66+
When calling a component in isolation (which is possible), the view helpers might not work properly, especially when (implicitly) requiring a request object!
2167
{% endhint %}
2268

23-
## Helpers yielding a block
24-
25-
{% hint style="danger" %}
26-
It's currently not possible to use view helpers requiring a block, such as the `form_for`. We're working on supporting them soon!
69+
{% hint style="info" %}
70+
We're currently working on an improved way to integrate ActionView Helpers which will enable removing the `plain` calls from your code.
2771
{% endhint %}
28-
29-
If you want to use a helper like `form_for` please bypass the current limitation by integrating a Rails partials as describe in the next section.

docs/migrate-from-2.x-to-3.0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class DemoController < ActionController::Base
3939
end
4040
```
4141

42-
# `Matestack::Ui::Layout` `Matestack::Ui::Page` wrapping DOM structures
42+
## `Matestack::Ui::Layout` `Matestack::Ui::Page` wrapping DOM structures
4343

4444
- previously, `Matestack::Ui::App` added some wrapping DOM structure around the whole layout and around it's `yield`
4545
- this enabled dynamic page transition and loading state animations

lib/matestack/ui/core/base.rb

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ class Base
1414
def initialize(html_tag = nil, text = nil, options = {}, &block)
1515
return unless render?
1616

17-
self.bind_to_parent = ([:without_parent].include?(html_tag) ? false : true)
17+
if options && options[:detach_from_parent] == true
18+
self.bind_to_parent = false
19+
else
20+
self.bind_to_parent = ([:without_parent].include?(html_tag) ? false : true)
21+
end
1822
self.slots = self.options.delete(:slots) if self.options
1923
# extract_options(text, options) is called in properties
2024
self.html_tag = html_tag if self.bind_to_parent
@@ -101,17 +105,25 @@ def view_context
101105
end
102106

103107
def method_missing(name, *args, &block)
104-
return view_context.send(name, *args, &block) if view_context && view_context.respond_to?(name, true)
105-
return Rails.application.routes.url_helpers.send(name, *args, &block) if Rails.application.routes.url_helpers.respond_to?(name, true)
108+
if view_context && view_context.respond_to?(name, true)
109+
if block_given?
110+
view_context_response = view_context.send(name, *args, &Proc.new)
111+
return view_context_response
112+
else
113+
view_context_response = view_context.send(name, *args)
114+
return view_context_response
115+
end
116+
end
117+
if Rails.application.routes.url_helpers.respond_to?(name, true)
118+
return Rails.application.routes.url_helpers.send(name, *args, &block)
119+
end
106120
return raise NameError, "#{name} is not defined for #{self.class}", caller
107121
end
108122

109-
# MOVED TO VUE MODULE
110-
#
111-
# # give easy access to vue data attributes
112-
# def vue
113-
# Matestack::Ui::Core::VueAttributes
114-
# end
123+
def to_str
124+
render_content
125+
end
126+
alias to_s to_str
115127

116128
end
117129
end

lib/matestack/ui/core/tag_helper.rb

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ module TagHelper
2424
end
2525
end
2626

27-
def plain(text)
28-
Matestack::Ui::Core::Base.new(nil, text, nil)
27+
def plain(text=nil, options=nil, &block)
28+
raise "please specify an argument or block when using plain" if text.nil? && !block_given?
29+
Matestack::Ui::Core::Base.new(nil, text||yield, options)
2930
end
3031

3132
def unescape(text)
@@ -90,6 +91,17 @@ def rails_render(options = {})
9091
plain render options
9192
end
9293

94+
def detached(text=nil, options=nil, &block)
95+
options = {} if options.nil?
96+
options[:detach_from_parent] = true
97+
Matestack::Ui::Core::Base.new(nil, text, options, &block)
98+
end
99+
100+
def detached_to_s(text=nil, options=nil, &block)
101+
detached(text, options, &block).to_str
102+
end
103+
alias matestack_to_s detached_to_s
104+
93105
end
94106
end
95107
end

0 commit comments

Comments
 (0)