Skip to content

Commit a9dc582

Browse files
author
Nils Henning
committed
[TASK] extend basic building blocks guide
1 parent a052921 commit a9dc582

File tree

1 file changed

+170
-32
lines changed
  • docs/guides/200-basic_building_blocks

1 file changed

+170
-32
lines changed

docs/guides/200-basic_building_blocks/README.md

Lines changed: 170 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,192 @@
22

33
## Table of contents
44

5-
1) Concept
6-
1) Apps
7-
2) Pages
8-
3) Components
9-
2) Event System
10-
3) Core Features
5+
1. Concept
6+
1. Apps
7+
2. Pages
8+
3. Components
9+
2. Event System
10+
3. Core Features
1111

1212
## Concept
1313

1414
Matestack enables you to write modern user interfaces in pure ruby. Let's take a closer look at how matestacks concept works and what features it offers you. The below graphic shows the conceptual structure of apps, pages and components.
1515

1616
![Matestack app, pages, components concept](../../images/concept.png)
1717

18-
* describe matestack apps, pages, components concept with an image
19-
* first app -> layout
20-
* second page -> view
21-
* third component -> partial
18+
Apps are similiar to layouts in Rails. Apps wrap pages with provided content, like a top navigation or a sidebar as displayed in the above image. You will always have at least one app in your Rails application, but you can have as much as you want. For example you could have a public app, which wraps your landing, contact, about pages with a top navigation and a private app, which wraps management pages with a sidebar and different top navigation.
19+
20+
As we already mentioned pages it is time to explain them. Pages are similiar to Rails views. A controller action usually renders a view, with matestack a controller action usually renders a page.
21+
22+
Lastly there are components. Components can be compared to Rails partials. They can be used to structure content and define reusable ui parts. In the above image components are represented with a green background. There is one component containing a text block which is reused three times on the page and another component containing a button, which could be reused on other pages. So with components you can create reusable content blocks to structure your ui and keep it dry.
23+
Components can not only be used inside pages, but also in apps and other components.
24+
25+
26+
Apps, pages and components will live in a `matestack` folder inside your `app` directory. Apps, pages and components can be created as you like, but we recommend to namespace apps and pages. Imagine we have an online shop with a shop app and a management app. The corresponding folder structure should look like this:
27+
28+
```sh
29+
app/matestack/
30+
|
31+
└───shop/
32+
│ │ app.rb
33+
│ └───pages/
34+
│ │ │ home.rb
35+
|
36+
└───management/
37+
│ │ app.rb
38+
│ └───pages/
39+
│ │ │ dashboard.rb
40+
```
41+
42+
43+
Having taken a look at the overall concept of matestacks apps, pages and components and how they work together, we can take a deeper look at each one of them.
44+
2245

2346
### Apps
2447

25-
* describe an app in more details
26-
27-
* advantages of apps combined with pages
28-
* describe why we need a layout usually per app
29-
* where to put and how to namespace your apps
48+
As mentioned above apps wrap pages with provided content. But what advantages to we get from using an app with pages?
49+
50+
Apps can transition between pages corresponding to the same app. What does transition between pages mean? It means that an app can switch between pages without reloading the apps content. For example your navigation will not be reloaded, but only the page content, improving the user experience. With pure Rails views and layouts the browser would do a full reload of the website. With matestack only the content that should change is requested, rendered and replaced asynchronously without a full reload, providing a more app like or single page application like feeling.
51+
52+
**Creating an app**
53+
54+
Creating an app is easy. Let's create the shop app from the example at the beginning. As mentioned we recommend namespacing your apps and store pages, which in this case means we create our shop app under the namespace shop. Create a file `app/matestack/shop/app.rb` which will contain our app code.
55+
56+
```ruby
57+
class Shop::App < Matestack::Ui::App
58+
59+
def response
60+
heading text: 'Matestack Shop'
61+
yield_page
62+
end
63+
64+
end
65+
```
66+
67+
Apps need to inherit from `Matestack::Ui::App` and implement a `response` method. The `response` method contains the output which will be rendered. In our case it would add an "h1" saying "Matestack Shop" above the pages. The `yield_page` method determines where inside the app the page would be rendered. `yield_page` enables the app to transition between pages.
68+
69+
How the call of `heading text: "Matestack Shop"` works will be explained later in this guide.
70+
71+
As you might have read in the [installation](/docs/guides/000-installation/) guide you need to have a rails layout containing a html element with "matestack-ui" as class name. This is required because matestack uses vue.js and we mount to this class name. Because we do not yet support writing "html, head, meta" and other tags that are used outside the body in matestack you need at least one layout file. But we recommend using one layout file for each app.
72+
73+
**Accessing data in pages**
74+
TODO
3075

3176
### Pages
3277

33-
* describe a page in more details
34-
35-
* what offers a page
36-
* pages without an app and with an app
37-
* transitions of pages when wrapped in app
38-
* where to put pages and how to namespace them
78+
Pages come close to rails views, but give you the ability to transition between them without full website reloads when used with an app.
79+
80+
**Creating a page**
81+
82+
Let's create the home page from the online shop example. Therefore we create a file `app/matestack/shop/pages/home.rb`.
83+
84+
```ruby
85+
class Shop::Pages::Home < Matestack::Ui::Page
86+
87+
def response
88+
heading size: 2, text: 'A few products you may like'
89+
Products.limit(5).each do |product|
90+
paragraph text: product.name
91+
small text: product.price
92+
end
93+
end
94+
95+
end
96+
```
97+
98+
Pages need to inherit from `Matestack::Ui::Page` and like apps implement a `response` method. Within the `response` method we implement our UI which will be rendered when we call `render Shop::Pages::Home`. Our home page will render a "h2" saying "A few products you may like" followed by five sets of "p" and "small" tags containing the product name and price. With matestack you write pure ruby instead of html and therefore can leverage all of rubys and rails features.
99+
100+
Again, how the `heading`, `paragraph` and `small` calls work will be explained later in this guide.
101+
102+
**Advanced page**
103+
104+
Let's create another page, where we will give you an example what you could do because you're writing uis in pure ruby.
105+
106+
`app/matestack/shop/pages/products/index.rb`
107+
108+
```ruby
109+
class Shop::Pages::Products::Index < Matestack::Ui::Page
110+
111+
def response
112+
banner do
113+
heading text: 'New in the matestack shop'
114+
end
115+
banner do
116+
heading text: 'Sale'
117+
paragrap text: 'Now until tommorow'
118+
end
119+
Products.all.each do |product|
120+
product_teaser product.name, product.price
121+
end
122+
end
123+
124+
private
125+
126+
def banner(&block)
127+
div class: 'banner' do
128+
yield
129+
end
130+
end
131+
132+
def product_teaser(name, price)
133+
paragraph text: name,
134+
small text: prive
135+
end
136+
137+
end
138+
```
139+
140+
The possibilities are endless. Our `banner` method takes in a block and sourrounds it with a "div". This could be useful if you have complex repeating markup which is only relevant on this page and has different content inside. Our `product_teaser(name, price)` methods renders a "p" and "small" tag with the given name and price. But to be clear, we would recommend creating a component for product teaser. You will learn more about components in a second. There is much more you can do. For example you can inherit from your own page.
141+
142+
**Accessing data in pages**
143+
TODO
39144

40145
### Components
41146

42-
* describe components in more detail
43-
44-
* core components -> implemented in order to write uis in pure ruby
45-
* different types of components
46-
* components
47-
* vue.js components
48-
* short description of what they are and a few examples (in greater detail in core features)
49-
* how to use core components in order to create apps, pages, own components
50-
* what are own components good for
51-
* how to create and use a component
52-
* where to put components and how to namespace them
147+
We talked shortly about components and even adviced to create a component for the product teaser, but before doing this we will take a closer look at what components are.
148+
149+
Components are reusable UI parts. They can represent simple parts like a button with specific classes or more complex parts like a product teaser or whatever you think should be a reusable part of your UI. Components are used through method calls which are defined throug a component registry. More on that later.
150+
151+
**Core Components**
152+
153+
Above we used methods like `heading`, `paragraph`, `small` and `div`. These are all what we call core components provided trough a core component registry which is automatically loaded. They are components representing the corresponding html tag. For example calling `div` would result after rendering in `<div></div>`. Matestack a wide set of w3c's specified html tags for you, so you could write UIs in pure ruby. All available components are listed in our [components api](/docs/api/100-components/).
154+
155+
There are two different types of core components. Simple components and so called vue.js components. `div` for example is a simple component, it renders a "div" tag either emtpy or containing the content given by a block. `toggle` on the other hand is a vue.js component, because it comes with a corresponding vue.js component to enable dynamic behavior on the client side. `toggle` for example can show or hide content depending on events, enabling you to write such dynamic behavior without writing anything else than ruby.
156+
157+
**Using core components**
158+
159+
Like already mentioned core components are automatically available in apps, pages and components, which means you can right ahead write your UI with apps, pages and components in pure ruby. Just use them like in the examples above. Core components always take a hash as parameter which can contain all corresponding w3c specified html attributes in order to set them.
160+
161+
```ruby
162+
def response
163+
div id: 'product-1', class: 'product-teaser', data: { foo: 'bar' }
164+
paragraph text: 'I am a p tag', class: 'highlight'
165+
span text: 'I am a span', style: 'color: red;'
166+
end
167+
```
168+
169+
Most simple core components are callable like their tag name. For example `div` and `span` but some differ from their tag name. `paragraph` for example would overwrite the short version of `puts` `p` and therefore was named differently. Take a look at the component list in the [components api](/docs/api/000-base/).
170+
171+
**Creating own components**
172+
173+
Components can be used to structure the UI in smaller parts, which may be reusable. Creating a component is as easy as creating apps and pages. Create a file called `teaser.rb` inside `app/matestack/components/products/teaser.rb`. We put our component inside a components folder inside the matestack folder because we may want to reuse this component in both our apps (shop, management). If we knew we will use this component only in our shop, we could have placed it inside our shop folder inside a components folder.
174+
175+
```ruby
176+
class Components::Products::Teaser < Matestack::Ui::Component
177+
178+
def response
179+
paragraph 'Product name placeholder'
180+
small 'Product price placeholder'
181+
end
182+
183+
end
184+
```
185+
186+
Components need to inherit from `Matestack::Ui::Component` and implement a `response` method. If this component gets called somewhere in a page or app the response method will define the content that gets rendered.
187+
188+
**Accessing data in components**
189+
TODO
190+
53191

54192
## Event System
55193

0 commit comments

Comments
 (0)