You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -7,8 +7,6 @@ All this solutions are going to show you different approaches from which you can
7
7
8
8
In order to explain the following approaches we will shortly describe a scenario. Let's assume a very simple app, which has a landing page, products index page and a products show page. The landing page displays a nav, search bar and 3 product teasers. The products index page lists all components reusing the products teaser partial. The products show page just renders the details of a product.
9
9
10
-
1.[Custom components](#custom-components)
11
-
2.[In progress...](#in-progress)
12
10
13
11
## Custom components
14
12
@@ -32,11 +30,12 @@ Start by creating a file called `teaser.rb` in `app/matestack/components/product
link path: product_path(product), class: 'product-teaser'do
40
39
div do
41
40
heading size:2, text: product.name
42
41
paragraph text: product.description
@@ -48,21 +47,21 @@ class Components::Products::Teaser < Matestack::Ui::Component
48
47
end
49
48
```
50
49
51
-
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`. We have now a teaser component, but in order to use it we have to register it and include our registration in our `ApplicationController`.
50
+
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`.
52
51
53
52
Let's register our component by creating a component registry in `app/matestack/components/registry.rb`.
@@ -71,6 +70,16 @@ class ApplicationController < ActionController::Base
71
70
end
72
71
```
73
72
73
+
and make matestack `matestack_component` helper available in views by also including the `Matestack::Ui::Core::ApplicationHelper` in our `ApplicationHelper`.
74
+
75
+
`app/helpers/application_helper.rb`
76
+
77
+
```ruby
78
+
moduleApplicationHelper
79
+
includeMatestack::Ui::Core::ApplicationHelper
80
+
end
81
+
```
82
+
74
83
Now we can use our matestack component in our view. Replacing the `render partial:` call from before with a call to `matestack_component` on our landing page.
75
84
76
85
`app/views/static/index.html.erb`.
@@ -80,14 +89,197 @@ Now we can use our matestack component in our view. Replacing the `render partia
This approach gives you access inside this component to all matestack features except page transitions. You can use `async`, `toggle`, `collection`, `actions`, `forms`, `isolated`, `onclick` and more vue.js components inside your components, enabling you to build modern and interactive UIs in pure ruby, while keeping a low effort for integrating or slowly migrating your project to matestack.
89
98
99
+
To use matestack page transition feature you have to use matestack pages inside a matestack app.
100
+
101
+
## Components reusing views or partials
102
+
103
+
Another method to integrate matestack in your rails application is by reusing your partials with components. Matestack `rails_view` component offers the posssibility to render a view or partial by passing it's name and required params to it. You can either replace your views step by step refactoring them with components which reuse partials and keep the migration of these partials for later or you can reuse a complete view and create a page with a single component rendering the view.
104
+
105
+
### Components reusing partials
106
+
107
+
Above we created a new matestack component, recreating our product teaser partial, but instead of doing so we could also reuse this partial with a component. Let's create a matestack page and app, which will list trending products. We add another route `get :trending, to: 'static#trending'` to our `config/routes.rb` file. We create a matestack app in `app/matestack/shop/app.rb`.
108
+
109
+
```ruby
110
+
classShop::App < Matestack::Ui::App
111
+
112
+
defresponse
113
+
head_section
114
+
yield_page
115
+
end
116
+
117
+
private
118
+
119
+
defhead_section
120
+
header do
121
+
div class="round-header-background"
122
+
nav do
123
+
div class="logo" { plain "RAILS" }
124
+
end
125
+
div class="hero search"do
126
+
heading text:'Shopping never was easier'
127
+
end
128
+
end
129
+
end
130
+
end
131
+
```
132
+
133
+
It displays our header which we used on the other pages too and renders it as an app layout. Below the head section the page will be rendered, specified by the call to `yield_page`.
134
+
135
+
Now we create our trending page in `app/matestack/pages/trending.rb`.
As you see we used the `rails_view` component here to render our products teaser partial. Given the string rails searches for a partial in `app/views/products/_teaser.html.erb`. As our product teaser partial uses a `product` we pass in a product. All params except those for controlling the rendering like `:partial` or `:view` get passed to the partial or view as locals. Therefore the partial teaser can access the product like it does.
153
+
154
+
To render our trending page within the shop app to see the `rails_view` component working we have to make sure our `app/layouts/application.html.erb` contains an html element with the id "matestack-ui".
Lastly we implement the controller action in the `StaticController` which should render our page within our `Shop::App`. We could set the corresponding app by adding a call to `matestack_app Shop::App` at the top of our controller or by using `matestack_app: Shop::App` in our render call. In this example we use the second option.
177
+
178
+
```ruby
179
+
classStaticController < ApplicationController
180
+
181
+
defindex
182
+
@products=Product.limit(3)
183
+
end
184
+
185
+
deftrending
186
+
@products=Product.limit(3) # our trending products - for simplicity we just select the first three retrieved records
If we now start our rails server with `rails s` and visit [localhost:3000/trending](http://localhost:3000/trending) we can see our `rails_view` component renders our partial with the correct data.
194
+
195
+
`rails_view` works with ERB, Haml and Slim Templates. ERB and Haml are supported out of the box. In order to use slim templates the slim gem needs to be installed.
196
+
197
+
### Components reusing views
198
+
199
+
As mentioned above the `rails_view` component can not only render partials but also views. You can use this behavior to quickly switch to matestack pages and apps, allowing for page transitions between your views, which enables a more single page application or app like behaviour. Above we introduced our shop app, which we used to wrap our trending products page. We now want to be able to transition between the trending and startpage. Therefore our startpage has to be a matestack page and not a rails view. To simply achieve this we create another page in `app/matestack/shop/pages/` called `index.rb`.
As we moved the header inside the shop app (but without the form which we will just leave out for simplicity) and our products will not be accessible via instance variable `@products` but instead via the local `products` we need to make slight changes to our view. Removing the header and change all appearances of `@products` to `products`.
After that we update our `StaticController` in order to render our new page.
227
+
228
+
`app/controllers/static_controller.rb`
229
+
230
+
```ruby
231
+
classStaticController < ApplicationController
232
+
matestack_app Shop::App
233
+
234
+
defindex
235
+
@products=Product.limit(3)
236
+
render Shop::Pages::Index
237
+
end
238
+
239
+
deftrending
240
+
@products=Product.limit(3)
241
+
render Shop::Pages::Trending
242
+
end
243
+
244
+
end
245
+
```
246
+
247
+
We moved setting the corresponding app to the top of our controller by calling `matestack_app` instead of specifying it in every render call to keep things dry. We can now visit [localhost:3000](http://localhost:3000) to see our index page working, reusing our old view.
248
+
249
+
The next thing we can do is to add transition links to our app to transition between our index and trending page.
250
+
251
+
```ruby
252
+
classShop::App < Matestack::Ui::App
253
+
254
+
defresponse
255
+
head_section
256
+
yield_page
257
+
end
258
+
259
+
private
260
+
261
+
defhead_section
262
+
header do
263
+
div class: "round-header-background"
264
+
nav do
265
+
div(class: "logo"){ plain "RAILS" }
266
+
div class: 'links'do
267
+
transition path: root_path, text:'Home'
268
+
transition path: trending_path, text:'Trending'
269
+
end
270
+
end
271
+
div class: "hero search"do
272
+
heading text:'Shopping never was easier'
273
+
end
274
+
end
275
+
end
276
+
end
277
+
```
278
+
279
+
When we now access [localhost:3000](http://localhost:3000) and click on the trending link and home link, we see how only the content is replaced as those links are now matestack transitions.
280
+
281
+
So with `rails_view` we can quickly integrate matestack with ease in an existing application and use matestacks transition feature for a more app or single page application like behaviour.
0 commit comments