brut 0.13.0 → 0.14.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 +4 -4
- data/CHANGELOG.md +23 -0
- data/Gemfile.lock +1 -1
- data/brut-css/package-lock.json +57 -106
- data/brut-css/package.json +1 -1
- data/brut-js/package-lock.json +50 -50
- data/brut-js/package.json +1 -1
- data/brutrb.com/.vitepress/config.mjs +0 -1
- data/brutrb.com/layouts.md +70 -12
- data/brutrb.com/package-lock.json +428 -381
- data/lib/brut/front_end/components/page_identifier.rb +7 -4
- data/lib/brut/front_end/layout.rb +11 -0
- data/lib/brut/front_end/page.rb +1 -1
- data/lib/brut/version.rb +1 -1
- data/mkbrut/Gemfile.lock +1 -1
- data/mkbrut/lib/mkbrut/version.rb +1 -1
- data/mkbrut/templates/Base/app/src/front_end/layouts/blank_layout.rb +11 -0
- data/mkbrut/templates/Base/app/src/front_end/layouts/default_layout.rb.erb +3 -6
- metadata +2 -2
- data/brutrb.com/recipes/blank-layouts.md +0 -22
data/brutrb.com/layouts.md
CHANGED
@@ -12,14 +12,16 @@ Your app should include `app/src/front_end/layouts/default_layout.rb`. The name
|
|
12
12
|
A layout is a Phlex component that's expected to have a single call to `yield` in
|
13
13
|
its `view_template` method.
|
14
14
|
|
15
|
+
### Default Layout and Common Layout Needs
|
16
|
+
|
15
17
|
Here is the `DefaultLayout` provided to new Brut apps:
|
16
18
|
|
17
19
|
```ruby {33}
|
18
20
|
class DefaultLayout < Brut::FrontEnd::Layout
|
19
21
|
include Brut::FrontEnd::Components
|
20
22
|
|
21
|
-
def initialize(
|
22
|
-
@
|
23
|
+
def initialize(page:)
|
24
|
+
@page = page
|
23
25
|
end
|
24
26
|
|
25
27
|
def view_template
|
@@ -34,7 +36,7 @@ class DefaultLayout < Brut::FrontEnd::Layout
|
|
34
36
|
link(rel: "stylesheet", href: asset_path("/css/styles.css"))
|
35
37
|
script(defer: true, src: asset_path("/js/app.js"))
|
36
38
|
title { app_name }
|
37
|
-
PageIdentifier(
|
39
|
+
PageIdentifier(page)
|
38
40
|
I18nTranslations("cv.cs")
|
39
41
|
I18nTranslations("cv.this_field")
|
40
42
|
Traceparent()
|
@@ -46,7 +48,7 @@ class DefaultLayout < Brut::FrontEnd::Layout
|
|
46
48
|
end
|
47
49
|
body do
|
48
50
|
brut_tracing url: "/__brut/instrumentation", show_warnings: true
|
49
|
-
main class:
|
51
|
+
main class: page.page_name do
|
50
52
|
yield
|
51
53
|
end
|
52
54
|
end
|
@@ -65,8 +67,69 @@ included by default are important for other features of Brut:
|
|
65
67
|
| `Brut::FrontEnd::Components::Traceparent` | Includes the OpenTelemetry *traceparent* on the page so that client-side telemetry is reported back to the server. See `<brut-tracing>` and [observability](/instrumentation) |
|
66
68
|
| `<brut-tracing>` / `brut_tracing` | Custom element that collects the client-side telemetry and sends it back to the server. See [observability](/instrumentation) |
|
67
69
|
|
68
|
-
|
69
|
-
|
70
|
+
### Adding Logic/Dynamic Behavior to Layouts
|
71
|
+
|
72
|
+
Often, your pages will need to make slight tweaks to the layout that don't apply to all pages. For example, you may wish for a certain page to refresh on a schedule and you want to do that with a [meta refresh](https://en.wikipedia.org/wiki/Meta_refresh), which must appear in the `<head>` of the page.
|
73
|
+
|
74
|
+
Unlike Rails, which uses named blocks to render optional or dynamic content, Brut allows you to use methods and normal Ruby-based flow logic. Since your layouts have access to the page they are laying out, you can use your pages' APIs to do whatever it is you need.
|
75
|
+
|
76
|
+
Taking the meta refresh example, suppose your `AppPage` defines a method, `auto_refresh_seconds` that, if non-`nil` means your page should automatically reload itself after that many seconds. By default, you don't refresh, so it returns `nil`:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
class AppPage < Brut::FrontEnd::page
|
80
|
+
|
81
|
+
# ...
|
82
|
+
|
83
|
+
def auto_refresh_seconds = nil
|
84
|
+
|
85
|
+
# ...
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
Your layout can refrence this API, since it's just a method on a class:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
class DefaultLayout < Brut::FrontEnd::Layout
|
93
|
+
|
94
|
+
# ...
|
95
|
+
|
96
|
+
def view_template
|
97
|
+
doctype
|
98
|
+
html(lang: "en") do
|
99
|
+
head do
|
100
|
+
if page.auto_refresh_seconds
|
101
|
+
meta(http_equiv: safe("refresh"), content: page.auto_refresh_seconds)
|
102
|
+
end
|
103
|
+
|
104
|
+
# ...
|
105
|
+
end
|
106
|
+
# ...
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
Since your pages are a class hierarchy, you can override `auto_refresh_seconds` in any page, and that page will automatically refresh itself:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
class DashboardPage < AppPage
|
114
|
+
|
115
|
+
def auto_refresh_seconds = 60 * 60
|
116
|
+
|
117
|
+
# ...
|
118
|
+
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
### Alternate Layouts
|
123
|
+
|
124
|
+
If you used `mkbrut`, you should have access to a `BlankLayout` that is useful for allowing a page to respond to Ajax requests:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
class SomePage < AppPage
|
128
|
+
def layout = "blank"
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
See [creating alternate layouts](/recipes/alternate-layouts) for more information on creating alternate layouts based on your needs.
|
70
133
|
|
71
134
|
## Testing
|
72
135
|
|
@@ -87,12 +150,7 @@ be [global components](/components#global-components)
|
|
87
150
|
> Technical Notes are for deeper understanding and debugging. While we will try to keep them up-to-date with changes to Brut's
|
88
151
|
> internals, the source code is always more correct.
|
89
152
|
|
90
|
-
_Last Updated
|
153
|
+
_Last Updated Sep 9, 2025_
|
91
154
|
|
92
155
|
Layouts work due to the implementation of the method `view_template` in `Brut::FrontEnd::Page`. This is why a page class must provide `page_template` instead.
|
93
156
|
|
94
|
-
While you could override `view_template` in your page to provide a "blank layout",
|
95
|
-
this is discouraged, as the use of `view_template` should be considered a
|
96
|
-
private implementation detail.
|
97
|
-
|
98
|
-
|