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.
@@ -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(page_name:)
22
- @page_name = page_name
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(@page_name)
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: @page_name do
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
- See [creating alternate layouts](/recipes/alternate-layouts) and [blank
69
- layouts](/recipes/blank-layouts) for customization options.
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 July 1, 2025_
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
-