compony 0.11.8 → 0.11.9
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/.yardopts +36 -1
- data/CHANGELOG.md +31 -0
- data/CLAUDE.md +85 -0
- data/Gemfile.lock +1 -1
- data/README.md +13 -3
- data/VERSION +1 -1
- data/compony.gemspec +3 -3
- data/doc/ComponentGenerator.html +1 -1
- data/doc/Components.html +1 -1
- data/doc/ComponentsGenerator.html +1 -1
- data/doc/Compony/Component.html +54 -54
- data/doc/Compony/ComponentMixins/Default/Labelling.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html +109 -70
- data/doc/Compony/ComponentMixins/Default/Standalone/VerbDsl.html +64 -28
- data/doc/Compony/ComponentMixins/Default/Standalone.html +1 -1
- data/doc/Compony/ComponentMixins/Default.html +1 -1
- data/doc/Compony/ComponentMixins/Resourceful.html +213 -74
- data/doc/Compony/ComponentMixins.html +1 -1
- data/doc/Compony/Components/Buttons/CssButton.html +1 -1
- data/doc/Compony/Components/Buttons/Link.html +1 -1
- data/doc/Compony/Components/Buttons.html +1 -1
- data/doc/Compony/Components/Destroy.html +83 -29
- data/doc/Compony/Components/Edit.html +110 -38
- data/doc/Compony/Components/Form.html +551 -208
- data/doc/Compony/Components/Index.html +1 -1
- data/doc/Compony/Components/List.html +3 -3
- data/doc/Compony/Components/New.html +110 -38
- data/doc/Compony/Components/Show.html +1 -1
- data/doc/Compony/Components/WithForm.html +194 -47
- data/doc/Compony/Components.html +1 -1
- data/doc/Compony/ControllerMixin.html +1 -1
- data/doc/Compony/Engine.html +1 -1
- data/doc/Compony/Intent.html +2 -2
- data/doc/Compony/ManageIntentsDsl.html +1 -1
- data/doc/Compony/MethodAccessibleHash.html +1 -1
- data/doc/Compony/ModelFields/Anchormodel.html +1 -1
- data/doc/Compony/ModelFields/Association.html +1 -1
- data/doc/Compony/ModelFields/Attachment.html +1 -1
- data/doc/Compony/ModelFields/Base.html +1 -1
- data/doc/Compony/ModelFields/Boolean.html +1 -1
- data/doc/Compony/ModelFields/Color.html +1 -1
- data/doc/Compony/ModelFields/Currency.html +1 -1
- data/doc/Compony/ModelFields/Date.html +1 -1
- data/doc/Compony/ModelFields/Datetime.html +1 -1
- data/doc/Compony/ModelFields/Decimal.html +1 -1
- data/doc/Compony/ModelFields/Email.html +1 -1
- data/doc/Compony/ModelFields/Float.html +1 -1
- data/doc/Compony/ModelFields/Integer.html +1 -1
- data/doc/Compony/ModelFields/Percentage.html +1 -1
- data/doc/Compony/ModelFields/Phone.html +1 -1
- data/doc/Compony/ModelFields/RichText.html +1 -1
- data/doc/Compony/ModelFields/String.html +1 -1
- data/doc/Compony/ModelFields/Text.html +1 -1
- data/doc/Compony/ModelFields/Time.html +1 -1
- data/doc/Compony/ModelFields/Url.html +1 -1
- data/doc/Compony/ModelFields.html +1 -1
- data/doc/Compony/ModelMixin.html +1 -1
- data/doc/Compony/NaturalOrdering.html +1 -1
- data/doc/Compony/RequestContext.html +1 -1
- data/doc/Compony/Version.html +1 -1
- data/doc/Compony/ViewHelpers.html +1 -1
- data/doc/Compony/VirtualModel.html +1 -1
- data/doc/Compony.html +1 -1
- data/doc/ComponyController.html +1 -1
- data/doc/_index.html +97 -1
- data/doc/file.CHANGELOG.html +758 -0
- data/doc/file.README.html +25 -4
- data/doc/file.basic_component.html +314 -0
- data/doc/file.cookbook.html +189 -0
- data/doc/file.destroy.html +105 -0
- data/doc/file.dsl_reference.html +672 -0
- data/doc/file.edit.html +109 -0
- data/doc/file.example.html +291 -0
- data/doc/file.example_advanced.html +257 -0
- data/doc/file.feasibility.html +115 -0
- data/doc/file.form.html +195 -0
- data/doc/file.generators.html +89 -0
- data/doc/file.glossary.html +217 -0
- data/doc/file.gotchas.html +222 -0
- data/doc/file.index.html +135 -0
- data/doc/file.inheritance.html +136 -0
- data/doc/file.installation.html +115 -0
- data/doc/file.integrations.html +218 -0
- data/doc/file.intents.html +265 -0
- data/doc/file.internal_datastructures.html +129 -0
- data/doc/file.list.html +253 -0
- data/doc/file.maintaining.html +127 -0
- data/doc/file.model_fields.html +137 -0
- data/doc/file.nesting.html +237 -0
- data/doc/file.new.html +109 -0
- data/doc/file.ownership.html +98 -0
- data/doc/file.patterns.html +669 -0
- data/doc/file.pre_built_components.html +99 -0
- data/doc/file.resourceful.html +181 -0
- data/doc/file.show.html +158 -0
- data/doc/file.standalone.html +233 -0
- data/doc/file.virtual_models.html +117 -0
- data/doc/file.with_form.html +157 -0
- data/doc/file_list.html +160 -0
- data/doc/guide/cookbook.md +41 -0
- data/doc/guide/dsl_reference.md +155 -0
- data/doc/guide/example_advanced.md +209 -0
- data/doc/guide/generators.md +1 -1
- data/doc/guide/glossary.md +42 -0
- data/doc/guide/gotchas.md +125 -0
- data/doc/guide/maintaining.md +64 -0
- data/doc/guide/patterns.md +681 -0
- data/doc/guide/pre_built_components/edit.md +1 -1
- data/doc/guide/pre_built_components/index.md +64 -1
- data/doc/guide/pre_built_components/list.md +111 -7
- data/doc/guide/pre_built_components/show.md +57 -2
- data/doc/guide/pre_built_components/with_form.md +56 -9
- data/doc/guide/pre_built_components.md +7 -2
- data/doc/guide/standalone.md +16 -1
- data/doc/index.html +25 -4
- data/doc/integrations.md +61 -0
- data/doc/llms.txt +62 -0
- data/doc/top-level-namespace.html +1 -1
- data/lib/compony/component.rb +8 -3
- data/lib/compony/component_mixins/default/standalone/standalone_dsl.rb +32 -15
- data/lib/compony/component_mixins/default/standalone/verb_dsl.rb +11 -3
- data/lib/compony/component_mixins/resourceful.rb +30 -16
- data/lib/compony/components/destroy.rb +21 -1
- data/lib/compony/components/edit.rb +25 -1
- data/lib/compony/components/form.rb +63 -21
- data/lib/compony/components/list.rb +1 -1
- data/lib/compony/components/new.rb +25 -1
- data/lib/compony/components/with_form.rb +20 -5
- data/lib/compony/intent.rb +1 -1
- metadata +43 -1
|
@@ -3,4 +3,67 @@
|
|
|
3
3
|
|
|
4
4
|
# Pre-built components: Index
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
`Compony::Components::Index` is a resourceful standalone component corresponding to Rails'
|
|
7
|
+
`index` controller action. It holds a collection of records and is a thin wrapper that
|
|
8
|
+
nests the [`List`](./list.md) component of the same family.
|
|
9
|
+
|
|
10
|
+
## What it does by default
|
|
11
|
+
|
|
12
|
+
The shipped `setup` (see `lib/compony/components/index.rb`) is deliberately minimal:
|
|
13
|
+
|
|
14
|
+
- **Route:** `standalone path: family_name` with a `verb :get` authorized by
|
|
15
|
+
`can?(:index, data_class)`, e.g. `/users`.
|
|
16
|
+
- **Label:** `label(:all) { data_class.model_name.human(count: 2) }` — e.g. "Users".
|
|
17
|
+
- **Data:** `load_data { @data = data_class.accessible_by(controller.current_ability) }`
|
|
18
|
+
— the full [CanCanCan](https://github.com/CanCanCommunity/cancancan)-scoped collection.
|
|
19
|
+
- **Exposed intent:** adds a `:new` intent (unless the model is
|
|
20
|
+
[owned](/doc/guide/ownership.md) by another).
|
|
21
|
+
- **Content:** `concat render_sub_comp(:list, @data)` — delegates all rendering to the
|
|
22
|
+
family's `List`.
|
|
23
|
+
|
|
24
|
+
So with both an `Index` and a `List` component present, a family lists out of the box:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
class Components::Users::Index < Compony::Components::Index; end
|
|
28
|
+
class Components::Users::List < Compony::Components::List
|
|
29
|
+
setup { columns :name, :email }
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Typical overrides
|
|
34
|
+
|
|
35
|
+
Narrow or order the collection:
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
class Components::Users::Index < Compony::Components::Index
|
|
39
|
+
setup do
|
|
40
|
+
load_data { @data = User.accessible_by(current_ability).active.order(:name) }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Customize the action toolbar via [exposed intents](/doc/guide/intents.md#exposed-intents):
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
setup do
|
|
49
|
+
exposed_intents do
|
|
50
|
+
add :index, :users, label: 'CSV', name: :csv, path: { format: :csv }
|
|
51
|
+
add :import, :users, method: :post, before: :new
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Add a second standalone route serving an alternative `List`:
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
setup do
|
|
60
|
+
standalone path: 'users/archived'
|
|
61
|
+
content :main, hidden: true do
|
|
62
|
+
concat render_sub_comp(:list, @data.archived)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
In practice apps put the layout/markup chrome in a `BaseComponents::Index` and inherit
|
|
68
|
+
from that — see [Real-world patterns](../patterns.md#3-index--load_data-scope--nested-list).
|
|
69
|
+
For column/filter/sort configuration, see [`List`](./list.md).
|
|
@@ -3,12 +3,116 @@
|
|
|
3
3
|
|
|
4
4
|
# Pre-built components: List
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
`Compony::Components::List` is a resourceful component that renders a table/list of
|
|
7
|
+
records. It is **not** standalone — it is meant to be nested, typically inside
|
|
8
|
+
[`Index`](./index.md) of the same family or [`Show`](./show.md) of an owning family, via
|
|
9
|
+
`render_sub_comp(:list, collection)`.
|
|
7
10
|
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
- Sorting: if the Ransack gem is installed and at least one sorting column has been specified, the component can automatically generate a select input for sorting as well as sorting links.
|
|
12
|
-
- Filtering / Searching: if the Ransack gem is installed and at least one filter has been specified, the component can automatically generate a filter / search form that works with Ransack.
|
|
11
|
+
Features: field-inferred or custom columns, per-row intents, pagination, and — when the
|
|
12
|
+
[Ransack](https://github.com/activerecord-hackery/ransack) gem is present and at least one
|
|
13
|
+
sort/filter is declared — sorting links, a sort select, and a filter/search form.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
## Column DSL
|
|
16
|
+
|
|
17
|
+
| Method | Signature | Description |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| `column` | `column(:name, label: nil, class: nil, link_opts: {}) { \|record\| ... }` | Add/define a column. No block → model-field column (auto label, value via `value_for`, only if `:index` permitted). Block is instance-exec'd per row and renders the cell. |
|
|
20
|
+
| `columns` | `columns(:a, :b, as_title: false, **kw)` | Bulk `column`. `as_title: true` marks title columns (shown as the card heading in mobile/card layouts). |
|
|
21
|
+
| `skip_column` | `skip_column(:name)` | Hide a (possibly inherited) column. |
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
class Components::Orders::List < Compony::Components::List
|
|
25
|
+
setup do
|
|
26
|
+
columns :number, :customer, as_title: true
|
|
27
|
+
columns :total, :created_at
|
|
28
|
+
column :status, class: 'text-end' do |order|
|
|
29
|
+
span order.status.label, class: "badge bg-#{order.status.key}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Filtering & sorting (Ransack)
|
|
36
|
+
|
|
37
|
+
| Method | Signature | Description |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| `filter` | `filter(:name, label: nil) { \|f\| ... }` | Add a filter. No block → field filter or a Ransack predicate string (e.g. `:id_eq`). Block gets the Ransack search form and renders label + input. |
|
|
40
|
+
| `filters` | `filters(:a, :b, **kw)` | Bulk `filter`. |
|
|
41
|
+
| `sort` | `sort(:name, label: nil)` | Add a sort criterion (must be Ransack-sortable). Generates one sort link + asc/desc entries. |
|
|
42
|
+
| `sorts` | `sorts(:a, :b)` | Bulk `sort`. |
|
|
43
|
+
| `default_sorting` | `default_sorting('id desc')` | Default Ransack sort applied when none chosen. |
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
setup do
|
|
47
|
+
filters :number, :status
|
|
48
|
+
filter :overdue, label: 'Overdue' do |f|
|
|
49
|
+
concat f.check_box(:overdue_eq, {}, true, false)
|
|
50
|
+
end
|
|
51
|
+
sorts :number, :created_at
|
|
52
|
+
default_sorting 'created_at desc'
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Per-row intents
|
|
57
|
+
|
|
58
|
+
`row_intents` opens the [intent management DSL](/doc/guide/intents.md#exposed-intents)
|
|
59
|
+
(`add`/`remove`, `before:`) applied to each row's record:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
setup do
|
|
63
|
+
row_intents do
|
|
64
|
+
remove :destroy
|
|
65
|
+
add :archive, ->(record) { record }, method: :patch, before: :edit
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Toggles, paging, styling
|
|
71
|
+
|
|
72
|
+
All have matching constructor kwargs so a nesting parent can override per render
|
|
73
|
+
(`render_sub_comp(:list, coll, skip_pagination: true, skip_columns: [:order])`).
|
|
74
|
+
|
|
75
|
+
| DSL | Default | Purpose |
|
|
76
|
+
| --- | --- | --- |
|
|
77
|
+
| `pagination(bool)` | on | Enable/disable paging (off loads all rows). |
|
|
78
|
+
| `results_per_page(n)` | 20 | Rows per page. |
|
|
79
|
+
| `filtering(bool)` | on | Enable/disable the filter form. |
|
|
80
|
+
| `sorting(bool)` / `sorting_in_filter(bool)` / `sorting_links(bool)` | on | Toggle sort UIs. |
|
|
81
|
+
| `filter_label_class` / `filter_input_class` / `filter_select_class` / `filter_item_wrapper_class` | — | CSS classes for filter form elements. |
|
|
82
|
+
|
|
83
|
+
Constructor `skip_*` kwargs: `skip_pagination`, `skip_filtering`, `skip_sorting`,
|
|
84
|
+
`skip_sorting_in_filter`, `skip_sorting_links`, `skip_columns:`, `skip_row_intents:`,
|
|
85
|
+
`skip_filters:`, `results_per_page:`, `default_sorting:`.
|
|
86
|
+
|
|
87
|
+
## Customizing rendering
|
|
88
|
+
|
|
89
|
+
`List` exposes named `content` blocks (`:data`, `:filter`, `:pagination`, `:sorting_links`,
|
|
90
|
+
…) that you override — almost always once, in an app `BaseComponents::List`, to fit your UI
|
|
91
|
+
framework, then inherited everywhere:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
module BaseComponents
|
|
95
|
+
class List < Compony::Components::List
|
|
96
|
+
setup do
|
|
97
|
+
filter_input_class 'form-control'
|
|
98
|
+
content :filter, hidden: true do
|
|
99
|
+
# Bootstrap-styled filter form wrapper
|
|
100
|
+
end
|
|
101
|
+
content :data, hidden: true do
|
|
102
|
+
# Bootstrap table / responsive cards
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Embedding a child list inside a Show, dropping the FK column and preserving the active tab
|
|
110
|
+
across filter submits:
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
concat render_sub_comp(:list, @data.line_items,
|
|
114
|
+
skip_columns: [:order],
|
|
115
|
+
params_in_filter: [param_name('tab')])
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
See [Real-world patterns](../patterns.md#4-list-customization) for the recurring app setup.
|
|
@@ -3,6 +3,61 @@
|
|
|
3
3
|
|
|
4
4
|
# Pre-built components: Show
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
`Compony::Components::Show` is a resourceful standalone component corresponding to a Rails
|
|
7
|
+
`show` action. It loads `@data` by `:id` and presents its fields.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
## What it does by default
|
|
10
|
+
|
|
11
|
+
From `lib/compony/components/show.rb`:
|
|
12
|
+
|
|
13
|
+
- **Route:** `standalone path: "/#{family_name}/:id"` with an `:id` constraint that accepts
|
|
14
|
+
integer **or** UUID ids, `verb :get` authorized by `can?(:show, @data)`.
|
|
15
|
+
- **Labels:** long = `data.label`; short = a generic translated "Show".
|
|
16
|
+
- **Exposed intents:** `:edit` and `:destroy` for `@data`, plus a `:back_to_owner` intent
|
|
17
|
+
if the model is [owned](/doc/guide/ownership.md).
|
|
18
|
+
- **Content blocks:**
|
|
19
|
+
- `:label` → `h2 component.label`
|
|
20
|
+
- `:main` → renders the `:data` block (override `:main` to wrap `:data` in a card etc.)
|
|
21
|
+
- `:data` (hidden) → if no columns were declared, calls `all_field_columns(@data)`, then
|
|
22
|
+
renders a two-column table of label/value per permitted field.
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
class Components::Users::Show < Compony::Components::Show; end # fully functional
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Column DSL
|
|
29
|
+
|
|
30
|
+
`Show` shares a `column`/`columns` DSL with [`List`](./list.md) (here "column" means an
|
|
31
|
+
attribute row, since Show renders one record).
|
|
32
|
+
|
|
33
|
+
| Method | Signature | Description |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| `column` | `column(:name, label: nil, class: nil, link_opts: {}, link_to_component: :show) { \|record\| ... }` | Add/define one attribute row. Without a block, treated as a model field; the block (instance-exec'd per record) supplies the value. |
|
|
36
|
+
| `columns` | `columns(:a, :b, **shared_kwargs)` | Bulk `column`. |
|
|
37
|
+
| `all_field_columns` | `all_field_columns(@data)` | Add a column for every model field (the default when none declared). |
|
|
38
|
+
| `skip_column` | `skip_column(:name)` | Drop an inherited column. When nesting Show in a parent, prefer the constructor's `skip_columns:` kwarg. |
|
|
39
|
+
|
|
40
|
+
Field columns are only rendered if the current ability permits `:show` on that attribute;
|
|
41
|
+
a `nil` value hides the row.
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
class Components::Users::Show < Compony::Components::Show
|
|
45
|
+
setup do
|
|
46
|
+
columns :name, :email, :created_at
|
|
47
|
+
column :status do |user| # custom computed row
|
|
48
|
+
user.active? ? 'Active' : 'Disabled'
|
|
49
|
+
end
|
|
50
|
+
skip_column :created_at # if inherited and unwanted
|
|
51
|
+
|
|
52
|
+
content do # wrap :data in app chrome
|
|
53
|
+
div class: 'card card-body' do
|
|
54
|
+
content :data
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
UUID/string ids work out of the box thanks to the route constraint. For nesting a Show (or
|
|
62
|
+
its `:data`) inside another component see [Nesting](/doc/guide/nesting.md); for the app
|
|
63
|
+
base-layer approach see [Real-world patterns](../patterns.md#1-the-app-base-component-layer).
|
|
@@ -3,16 +3,63 @@
|
|
|
3
3
|
|
|
4
4
|
# Pre-built components: WithForm
|
|
5
5
|
|
|
6
|
-
`Compony::Components::WithForm` is
|
|
6
|
+
`Compony::Components::WithForm` is the abstract base for components that render and submit
|
|
7
|
+
a form. It is **twinned** with a [`Form`](./form.md) component: WithForm provides the
|
|
8
|
+
route, authorization and resource handling; the Form provides the inputs and param schema.
|
|
9
|
+
[`New`](./new.md) and [`Edit`](./edit.md) both inherit from WithForm — you rarely subclass
|
|
10
|
+
it directly, but understanding the twinning explains how they work.
|
|
7
11
|
|
|
8
|
-
WithForm
|
|
12
|
+
A WithForm component may be resourceful (New/Edit are) but does not have to be.
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
- `form_comp` returns an instance of the Form component twinned with this component. If `form_comp_class` was never set, it will default to loading the component named `Form` in the same family as this component.
|
|
12
|
-
- `submit_verb` takes a symbol containing a verb, e.g. `:patch`. It defines this component's standalone verb that should be called when the twinned Form component is submitted.
|
|
13
|
-
- `submit_path` defaults to this component's standalone path. You can override this to submit the form to another component, should you need it.
|
|
14
|
+
## How the twinning works
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
- `form_comp` returns the Form instance, built lazily. It defaults to the component named
|
|
17
|
+
`Form` in the **same family**, instantiated with this component as `parent_comp` and
|
|
18
|
+
passed `submit_verb`, `submit_path` and `cancancan_action`.
|
|
19
|
+
- The Form renders inside this component's `content` (e.g. New/Edit do
|
|
20
|
+
`concat form_comp.render(controller, data: @data)`).
|
|
21
|
+
- The form's `<form>` posts back to `submit_path` using `submit_verb`; that same component
|
|
22
|
+
handles the submit verb (POST for New, PATCH for Edit) and runs the resourceful
|
|
23
|
+
lifecycle (`assign_attributes` → `store_data` → `respond`).
|
|
16
24
|
|
|
17
|
-
|
|
18
|
-
|
|
25
|
+
## DSL methods
|
|
26
|
+
|
|
27
|
+
| Method | Signature | Description |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| `submit_verb` | `submit_verb(:patch)` | HTTP verb the twinned form submits with. Mandatory (New sets `:post`, Edit `:patch`). |
|
|
30
|
+
| `form_comp_class` | `form_comp_class(Components::Users::SignupForm)` | Use a specific Form class instead of the same-family `Form`. |
|
|
31
|
+
| `submit_path` | `submit_path { Compony.path(:create, :users) }` | Override where the form submits. Block is given the controller; defaults to this component's own path. |
|
|
32
|
+
| `form_cancancan_action` | `form_cancancan_action(:edit)` | CanCanCan action used by the Form for per-field `permitted_attributes` (New sets `:new`, Edit `:edit`). Pass `nil` to disable per-field auth. |
|
|
33
|
+
| `form_comp` | `form_comp` | (Not DSL — a reader.) The Form instance; override in a subclass for full control. |
|
|
34
|
+
|
|
35
|
+
## Example: a custom non-default form
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
class Components::Users::Signup < Compony::Components::New
|
|
39
|
+
setup do
|
|
40
|
+
standalone path: 'signup' do
|
|
41
|
+
skip_authentication!
|
|
42
|
+
verb :get do authorize { true } end
|
|
43
|
+
verb :post do authorize { true } end
|
|
44
|
+
end
|
|
45
|
+
form_comp_class Components::Users::SignupForm # not the default Users::Form
|
|
46
|
+
on_created_redirect_path { Compony.path(:show, @data) }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class Components::Users::SignupForm < Compony::Components::Form
|
|
51
|
+
setup do
|
|
52
|
+
form_fields do
|
|
53
|
+
concat field(:email)
|
|
54
|
+
concat pw_field(:password)
|
|
55
|
+
end
|
|
56
|
+
schema_field :email
|
|
57
|
+
schema_pw_field :password
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For the full submit/redirect behavior see [`New`](./new.md) and [`Edit`](./edit.md); for
|
|
63
|
+
the form input/schema DSL see [`Form`](./form.md); for the lifecycle hooks see
|
|
64
|
+
[Resourceful](/doc/guide/resourceful.md). Multi-step and clone flows that reuse this
|
|
65
|
+
machinery are in [Real-world patterns](../patterns.md#11-non-crud-job-dispatch-toggles-clone).
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
Compony comes with a few pre-built components that cover the most common cases that can be speed up development. They are meant to be inherited from and the easiest way to do this is by using the [provided Rails generators](./generators.md) `rails g component ...`.
|
|
6
6
|
|
|
7
|
-
The pre-built components can be found in the module `Compony::Components`.
|
|
7
|
+
The pre-built components can be found in the module `Compony::Components`. They ship a
|
|
8
|
+
sensible, UI-agnostic default (plain HTML, no styling) — you typically inherit from them
|
|
9
|
+
in an app base layer that adds your UI framework's markup (see
|
|
10
|
+
[Real-world patterns](./patterns.md#1-the-app-base-component-layer)). `Show` and `Index`
|
|
11
|
+
are intentionally minimal because their presentation depends heavily on your UI framework;
|
|
12
|
+
they are easy to override (see the [example](./example.md)).
|
|
8
13
|
|
|
9
14
|
In the following, the pre-built components currently shipped with Compony are presented:
|
|
10
15
|
|
|
@@ -15,6 +20,6 @@ In the following, the pre-built components currently shipped with Compony are pr
|
|
|
15
20
|
- [WithForm](./pre_built_components/with_form.md): A base class for components containing and submitting forms
|
|
16
21
|
- [Form](./pre_built_components/form.md): Compony's equivalent to Rail's `_form` partial
|
|
17
22
|
- [New](./pre_built_components/new.md): Compony's equivalent to Rail's `new` and `create` controller action
|
|
18
|
-
- [Edit](./pre_built_components/
|
|
23
|
+
- [Edit](./pre_built_components/edit.md): Compony's equivalent to Rail's `edit` and `update` controller action
|
|
19
24
|
|
|
20
25
|
[Guide index](/README.md#guide--documentation)
|
data/doc/guide/standalone.md
CHANGED
|
@@ -139,6 +139,21 @@ end
|
|
|
139
139
|
|
|
140
140
|
By implementing `path do ... end` inside the `setup` method of a component, you can override the way paths to that component are generated. Customizing the path generation will affect all mentioned methods mentioned here involving paths, such as `Compony.path`, `render_intent` etc.
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
The block runs **outside** the request context, so build URLs via
|
|
143
|
+
`Rails.application.routes.url_helpers` (not `controller`/`helpers`). It is given an optional
|
|
144
|
+
model, positional path-helper args, the `standalone_name:` kwarg, and any extra kwargs.
|
|
145
|
+
|
|
146
|
+
This is an advanced usage. Refer to the default implementation of `Component`'s `path_block`
|
|
147
|
+
to see the baseline example.
|
|
148
|
+
|
|
149
|
+
Where overriding `path` is genuinely useful:
|
|
150
|
+
|
|
151
|
+
- **Inject a derived/looked-up param.** Callers pass a high-level argument and the block
|
|
152
|
+
turns it into concrete path params.
|
|
153
|
+
- **Mint a signed token into the URL** so an unauthenticated link can authorize itself —
|
|
154
|
+
a full worked recipe is in
|
|
155
|
+
[Real-world patterns §18 (signed-token capability links)](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding--magic-links)
|
|
156
|
+
(magic login, password reset, invite/confirm links).
|
|
157
|
+
- **Custom slugs / vanity paths** that differ from the Rails route helper's default shape.
|
|
143
158
|
|
|
144
159
|
[Guide index](/README.md#guide--documentation)
|
data/doc/index.html
CHANGED
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
</li><li>
|
|
91
91
|
<p>Compony seamlessly integrates with Rails and does not interfere with existing code. Using Compony, you <strong>can</strong> write your application as components, but it is still possible to have regular routes, controllers and views side-to-side to it. This way, you can migrate your applications to Compony little by little and enter and leave the Compony world as you please. It is also possible to render Compony components from regular views and vice versa.</p>
|
|
92
92
|
</li><li>
|
|
93
|
-
<p>Compony
|
|
93
|
+
<p>Compony requires Rails >= 7.2.1 and Ruby >= 3.3.5 (see <a href="./doc/integrations_md.html">doc/integrations.md</a> for all dependencies), and fully supports Stimulus and Turbo Drive. It is also compatible Turbo Frames and Streams, but there are not many helpers specifically targetting theme at this point..</p>
|
|
94
94
|
</li><li>
|
|
95
95
|
<p>Compony uses <a href="https://github.com/CanCanCommunity/cancancan">CanCanCan</a> for authorization but does not provide an authentication mechanism. You can easily build your own by creating login/logout components that manage cookies, and configure Compony to enforce authentication using the <code>Compony.authentication_before_action</code> setter. I have also successfully tested Compony to work with <a href="https://github.com/heartcombo/devise">Devise</a>.</p>
|
|
96
96
|
</li></ul>
|
|
@@ -109,8 +109,29 @@
|
|
|
109
109
|
<ul><li>
|
|
110
110
|
<p><a href="./doc/guide/example_md.html">Self-contained example</a> for those who like to dive straight into code</p>
|
|
111
111
|
</li><li>
|
|
112
|
+
<p><a href="./doc/guide/example_advanced_md.html">Advanced example</a>: custom form, feasibility, CSV export, virtual-model launch form</p>
|
|
113
|
+
</li><li>
|
|
112
114
|
<p><a href="./doc/guide/installation_md.html">Installation</a> (start here)</p>
|
|
113
115
|
</li><li>
|
|
116
|
+
<p>Quick reference (also handy for AI coding assistants):</p>
|
|
117
|
+
<ul><li>
|
|
118
|
+
<p><a href="./doc/guide/dsl_reference_md.html">DSL reference</a>: every DSL method with signature and context</p>
|
|
119
|
+
</li><li>
|
|
120
|
+
<p><a href="./doc/guide/glossary_md.html">Glossary</a>: one-line definitions of Compony vocabulary</p>
|
|
121
|
+
</li><li>
|
|
122
|
+
<p><a href="./doc/guide/gotchas_md.html">Gotchas</a>: known anti-patterns with symptom, cause, fix</p>
|
|
123
|
+
</li><li>
|
|
124
|
+
<p><a href="./doc/guide/patterns_md.html">Real-world patterns</a>: idioms distilled from production apps</p>
|
|
125
|
+
</li><li>
|
|
126
|
+
<p><a href="./doc/guide/cookbook_md.html">Cookbook</a>: recipes indexed by task (“I want to do X”)</p>
|
|
127
|
+
</li><li>
|
|
128
|
+
<p><a href="./doc/integrations_md.html">Integrations</a>: companion gems — required, optional, app-side</p>
|
|
129
|
+
</li><li>
|
|
130
|
+
<p><a href="./CLAUDE_md.html">Agent primer</a> and <a href="./doc/llms.txt">doc/llms.txt</a>: orientation for LLM-based tools</p>
|
|
131
|
+
</li><li>
|
|
132
|
+
<p><a href="./doc/guide/maintaining_md.html">Maintaining</a>: release & docs policy (for gem contributors)</p>
|
|
133
|
+
</li></ul>
|
|
134
|
+
</li><li>
|
|
114
135
|
<p>Concepts and usage:</p>
|
|
115
136
|
<ul><li>
|
|
116
137
|
<p><a href="./doc/guide/basic_component_md.html">A basic component</a>: Basic concepts relevant for all components</p>
|
|
@@ -135,7 +156,7 @@
|
|
|
135
156
|
</li><li>
|
|
136
157
|
<p><a href="./doc/guide/internal_datastructures_md.html">Internal datastructures</a>: Noteworthy datastructures provided by Compony</p>
|
|
137
158
|
</li><li>
|
|
138
|
-
<p><a href="./doc/guide/
|
|
159
|
+
<p><a href="./doc/guide/virtual_models_md.html">Virtual models</a>: Unleashing non-persistent interactions through Compony’s <code>ActiveType</code> integration</p>
|
|
139
160
|
</li></ul>
|
|
140
161
|
</li><li>
|
|
141
162
|
<p>Pre-built components shipped with Compony</p>
|
|
@@ -156,7 +177,7 @@
|
|
|
156
177
|
</li><li>
|
|
157
178
|
<p><a href="./doc/guide/pre_built_components/new_md.html">New</a>: Compony’s equivalent to Rail’s <code>new</code> and <code>create</code> controller action</p>
|
|
158
179
|
</li><li>
|
|
159
|
-
<p><a href="./doc/guide/pre_built_components/
|
|
180
|
+
<p><a href="./doc/guide/pre_built_components/edit_md.html">Edit</a>: Compony’s equivalent to Rail’s <code>edit</code> and <code>update</code> controller action</p>
|
|
160
181
|
</li></ul>
|
|
161
182
|
</li></ul>
|
|
162
183
|
|
|
@@ -199,7 +220,7 @@
|
|
|
199
220
|
</div></div>
|
|
200
221
|
|
|
201
222
|
<div id="footer">
|
|
202
|
-
Generated on
|
|
223
|
+
Generated on Mon May 18 13:55:32 2026 by
|
|
203
224
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
204
225
|
0.9.34 (ruby-3.3.5).
|
|
205
226
|
</div>
|
data/doc/integrations.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
[Back to the guide](/README.md#guide--documentation)
|
|
2
|
+
|
|
3
|
+
# Integrations & companion gems
|
|
4
|
+
|
|
5
|
+
What Compony pulls in, what it optionally lights up, and what you are expected to add
|
|
6
|
+
yourself. The authoritative source for hard dependencies and their version constraints is
|
|
7
|
+
the `:gemspec` task in [`Rakefile`](/Rakefile) (it generates `compony.gemspec`); the table
|
|
8
|
+
below mirrors it and must be updated together with it (see
|
|
9
|
+
[maintaining.md](/doc/guide/maintaining.md)).
|
|
10
|
+
|
|
11
|
+
## Hard runtime dependencies (installed automatically)
|
|
12
|
+
|
|
13
|
+
| Gem | Constraint | Why Compony needs it |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `rails` | `>= 7.2.1` | Routing, controllers, views Compony plugs into. |
|
|
16
|
+
| `request_store` | `>= 1.7` | Per-request storage (e.g. `Compony.root_comp`). |
|
|
17
|
+
| `dyny` | `>= 0.0.3` | HTML-as-Ruby templating used in `content` blocks. |
|
|
18
|
+
| `schemacop` | `>= 3.0.17` | Strong-param schema validation behind `schema_field` / `schema_line`. |
|
|
19
|
+
| `simple_form` | `>= 5.3.1` | The form builder behind the Form component's `field`. |
|
|
20
|
+
| `dslblend` | `>= 0.0.3` | Powers the `RequestContext` multi-provider DSL. |
|
|
21
|
+
| `anchormodel` | `>= 0.3.0` | `anchormodel` model-field type + enum-like associations. |
|
|
22
|
+
| `cancancan` | `~> 3.6.1` | Authorization: `authorize { can?(...) }`, `accessible_by`, per-field `permitted_attributes`. |
|
|
23
|
+
|
|
24
|
+
The Ruby floor is `>= 3.3.5` (`required_ruby_version`).
|
|
25
|
+
|
|
26
|
+
> Version note: the gemspec requires `rails >= 7.2.1`. If the README's prose mentions an
|
|
27
|
+
> older range, the gemspec wins — keep them in sync when bumping (see maintaining.md).
|
|
28
|
+
|
|
29
|
+
## Optional — presence unlocks a feature
|
|
30
|
+
|
|
31
|
+
These are **not** declared dependencies; Compony detects them and enables behavior if they
|
|
32
|
+
are in the host app's bundle.
|
|
33
|
+
|
|
34
|
+
| Gem | Unlocks |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `active_type` | `Compony::VirtualModel` (loaded only if `ActiveType::Object` is defined). Non-persistent / upload / wizard forms — [patterns §12](/doc/guide/patterns.md#12-virtual-model-for-non-persistent--upload-forms), [virtual_models.md](/doc/guide/virtual_models.md). |
|
|
37
|
+
| `ransack` | List filtering, sorting links and the sort select in [`List`](/doc/guide/pre_built_components/list.md). Without it, declare no `filter`/`sort` and those UIs stay off. |
|
|
38
|
+
|
|
39
|
+
## App-side companions (you add these)
|
|
40
|
+
|
|
41
|
+
Compony is UI- and auth-agnostic; these are conventional choices in real apps, pulled in
|
|
42
|
+
by your app, not by Compony.
|
|
43
|
+
|
|
44
|
+
| Concern | Typical choice | Used by |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| Authentication | Devise, or a custom login component + `Compony.authentication_before_action=` | Compony ships **no** auth ([README](/README.md)); token-link flows → [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding--magic-links) |
|
|
47
|
+
| Turbo / Stimulus | `turbo-rails`, `stimulus-rails` | Compony fully supports Turbo Drive; inline-edit → [patterns §15](/doc/guide/patterns.md#15-inline-edit-card-with-a-turbo-frame), ajax PATCH → [patterns §17](/doc/guide/patterns.md#17-inline-patch-without-a-form-reorder--quick-toggle) |
|
|
48
|
+
| Select / date inputs | TomSelect, Flatpickr (as registered `simple_form` inputs) | `field(:x, as: :tom_select/:flatpickr_*)` — [patterns §5–6](/doc/guide/patterns.md#5-custom-form--schemacop-kept-in-sync) |
|
|
49
|
+
| i18n | Rails I18n and/or FastGettext | Component labels; gem ships `config/locales/{de,en,fr}.yml` |
|
|
50
|
+
| File handling | ActiveStorage (+ a variant/processor) | Attachment fields, virtual-model uploads — [patterns §12](/doc/guide/patterns.md#12-virtual-model-for-non-persistent--upload-forms) |
|
|
51
|
+
| PDF / CSV | Prawn / wicked_pdf, Ruby `CSV` | Export endpoints — [patterns §10](/doc/guide/patterns.md#10-csv--pdf-via-respond-format) |
|
|
52
|
+
| Signed tokens | `jwt` | Capability links — [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding--magic-links) |
|
|
53
|
+
|
|
54
|
+
Incompatibility: `tailwindcss-rails` purges Compony component CSS (component HTML is not in
|
|
55
|
+
`app/views`); see [gotchas.md #13](/doc/guide/gotchas.md#13-tailwindcss-rails-purges-compony-styles).
|
|
56
|
+
|
|
57
|
+
## Development dependencies
|
|
58
|
+
|
|
59
|
+
`yard >= 0.9.28` (docs), `rubocop >= 1.48`, `rubocop-rails >= 2.18.0` (lint).
|
|
60
|
+
|
|
61
|
+
[Guide index](/README.md#guide--documentation)
|
data/doc/llms.txt
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Compony
|
|
2
|
+
|
|
3
|
+
> Compony is a Ruby on Rails gem for writing apps in component style: one Ruby class
|
|
4
|
+
> bundles a route, a controller action, and a view (Dyny). Components are subclassable,
|
|
5
|
+
> giving inheritance for views and controller logic, DRY CRUD via pre-built components,
|
|
6
|
+
> a model mixin for fields and feasibility, and an intent system for linking components.
|
|
7
|
+
|
|
8
|
+
Read CLAUDE.md first for the mental model and the public API surface. Source of truth for
|
|
9
|
+
behavior is the Ruby source under lib/compony/; the guide pages below explain intent.
|
|
10
|
+
|
|
11
|
+
## Agent entrypoints
|
|
12
|
+
|
|
13
|
+
- [Agent primer](/CLAUDE.md): mental model, public API table, source layout, conventions.
|
|
14
|
+
- [DSL reference](/doc/guide/dsl_reference.md): every setup/standalone/form/list DSL method with signature and context.
|
|
15
|
+
- [Glossary](/doc/guide/glossary.md): one-line definitions of Compony vocabulary.
|
|
16
|
+
- [Gotchas](/doc/guide/gotchas.md): numbered anti-patterns — symptom, cause, fix.
|
|
17
|
+
- [Real-world patterns](/doc/guide/patterns.md): 18 recurring idioms from production apps (base layer, thin leaves, tabs, exports, jobs, virtual models, webhooks, turbo-frame inline edit, multi-step wizard, inline PATCH, signed-token capability links).
|
|
18
|
+
- [Cookbook](/doc/guide/cookbook.md): pure task→pointer index ("I want to do X") into patterns/guide; no duplicated content.
|
|
19
|
+
- [Integrations](/doc/integrations.md): companion gems — hard runtime deps (versions), optional feature-unlocking gems, app-side companions.
|
|
20
|
+
- [Maintaining](/doc/guide/maintaining.md): contributor/AI policy — CHANGELOG per change, release steps, .yardopts, dependency + anonymization rules.
|
|
21
|
+
|
|
22
|
+
## Guide — concepts
|
|
23
|
+
|
|
24
|
+
- [README](/README.md): what Compony is, key aspects, caveats, guide index.
|
|
25
|
+
- [Self-contained example](/doc/guide/example.md): full small app (model, Show, Destroy, New, Form, Edit, Index).
|
|
26
|
+
- [Advanced example](/doc/guide/example_advanced.md): custom form, virtual fields, CSV export, exposed intents, feasibility, before_render guard.
|
|
27
|
+
- [Installation](/doc/guide/installation.md): setup steps.
|
|
28
|
+
- [Basic component](/doc/guide/basic_component.md): naming, setup, labelling, content blocks, before_render.
|
|
29
|
+
- [Standalone](/doc/guide/standalone.md): routing, verbs, authorize, respond, formats, scopes, constraints.
|
|
30
|
+
- [Inheritance](/doc/guide/inheritance.md): DRYing via base components.
|
|
31
|
+
- [Nesting](/doc/guide/nesting.md): sub_comp, embedding components.
|
|
32
|
+
- [Resourceful](/doc/guide/resourceful.md): @data auto-loading, load_data.
|
|
33
|
+
- [Intents](/doc/guide/intents.md): Compony.path, render_intent, render_sub_comp, buttons/styles, exposed_intents.
|
|
34
|
+
- [Feasibility](/doc/guide/feasibility.md): prevent, feasible?, disabling buttons.
|
|
35
|
+
- [Ownership](/doc/guide/ownership.md): owned_by, owner-aware redirects.
|
|
36
|
+
- [Model fields](/doc/guide/model_fields.md): field types, value_for, auto-generated UI.
|
|
37
|
+
- [Generators](/doc/guide/generators.md): rails g component / components.
|
|
38
|
+
- [Internal datastructures](/doc/guide/internal_datastructures.md): RequestContext, MethodAccessibleHash.
|
|
39
|
+
- [Virtual models](/doc/guide/virtual_models.md): non-persistent ActiveType-backed models.
|
|
40
|
+
|
|
41
|
+
## Guide — pre-built components
|
|
42
|
+
|
|
43
|
+
- [Introduction](/doc/guide/pre_built_components.md): overview of shipped CRUD components.
|
|
44
|
+
- [Show](/doc/guide/pre_built_components/show.md): Rails show equivalent.
|
|
45
|
+
- [Index](/doc/guide/pre_built_components/index.md): Rails index equivalent.
|
|
46
|
+
- [List](/doc/guide/pre_built_components/list.md): Rails _list partial equivalent (columns, filters, sorts, pagination).
|
|
47
|
+
- [Destroy](/doc/guide/pre_built_components/destroy.md): Rails destroy equivalent.
|
|
48
|
+
- [WithForm](/doc/guide/pre_built_components/with_form.md): base for form-submitting components.
|
|
49
|
+
- [Form](/doc/guide/pre_built_components/form.md): Rails _form partial equivalent (form_fields, schema_*).
|
|
50
|
+
- [New](/doc/guide/pre_built_components/new.md): Rails new+create equivalent.
|
|
51
|
+
- [Edit](/doc/guide/pre_built_components/edit.md): Rails edit+update equivalent.
|
|
52
|
+
|
|
53
|
+
## Source (behavior source of truth)
|
|
54
|
+
|
|
55
|
+
- lib/compony.rb: Compony.* module methods (public API).
|
|
56
|
+
- lib/compony/component.rb: base Component DSL (setup, content, before_render, exposed_intents).
|
|
57
|
+
- lib/compony/intent.rb: Intent — path, label, feasibility, button rendering.
|
|
58
|
+
- lib/compony/component_mixins/resourceful.rb: @data lifecycle hooks.
|
|
59
|
+
- lib/compony/component_mixins/default/standalone/: routing DSL (standalone/verb/respond/authorize).
|
|
60
|
+
- lib/compony/components/: pre-built component implementations.
|
|
61
|
+
- lib/compony/model_mixin.rb: model-side field/prevent/owned_by.
|
|
62
|
+
- lib/compony/virtual_model.rb: VirtualModel base.
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
</div>
|
|
103
103
|
|
|
104
104
|
<div id="footer">
|
|
105
|
-
Generated on
|
|
105
|
+
Generated on Mon May 18 13:55:34 2026 by
|
|
106
106
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
107
107
|
0.9.34 (ruby-3.3.5).
|
|
108
108
|
</div>
|
data/lib/compony/component.rb
CHANGED
|
@@ -123,7 +123,12 @@ module Compony
|
|
|
123
123
|
# Overrides how the path to this component should be generated.
|
|
124
124
|
# The block will be given the following args: a model (optional), pos. args for the path helper, the kwarg `standalone_name` and kwargs for the path helper.
|
|
125
125
|
# The block is expected to return a Rails path. It is not given `controller` or `helpers`, instead use: `Rails.application.routes.url_helpers`.
|
|
126
|
-
# For
|
|
126
|
+
# For the default block, refer to the initializer of this class.
|
|
127
|
+
# Useful when callers should pass a higher-level argument that is translated into path params here, e.g. minting a
|
|
128
|
+
# signed token into the URL so an unauthenticated link can authorize itself. Worked examples:
|
|
129
|
+
# see `doc/guide/standalone.md` ("Customizing path generation") and `doc/guide/patterns.md` §18 (signed-token capability links).
|
|
130
|
+
# @return [void] when defining (block given); otherwise the generated Rails path String.
|
|
131
|
+
# @api public
|
|
127
132
|
def path(*, **, &block)
|
|
128
133
|
if block_given?
|
|
129
134
|
# Assignment via DSL
|
|
@@ -214,8 +219,8 @@ module Compony
|
|
|
214
219
|
end
|
|
215
220
|
|
|
216
221
|
# DSL method
|
|
217
|
-
# If a block is given: Enters the DSL where exposed intents can be added or removed (use from {Component
|
|
218
|
-
# If no block is given: Builds the declared intents and returns them (use from a {
|
|
222
|
+
# If a block is given: Enters the DSL where exposed intents can be added or removed (use from {Compony::Component.setup} within the component).
|
|
223
|
+
# If no block is given: Builds the declared intents and returns them (use from a {Compony::RequestContext} outside the component).
|
|
219
224
|
def exposed_intents(&block)
|
|
220
225
|
if block_given?
|
|
221
226
|
# Enter DSL
|