compony 0.7.1 → 0.8.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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +10 -14
  5. data/VERSION +1 -1
  6. data/compony.gemspec +4 -4
  7. data/doc/ComponentGenerator.html +1 -1
  8. data/doc/Components.html +1 -1
  9. data/doc/ComponentsGenerator.html +1 -1
  10. data/doc/Compony/Component.html +193 -457
  11. data/doc/Compony/ComponentMixins/Default/Labelling.html +1 -1
  12. data/doc/Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html +1 -1
  13. data/doc/Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html +3 -3
  14. data/doc/Compony/ComponentMixins/Default/Standalone/VerbDsl.html +1 -1
  15. data/doc/Compony/ComponentMixins/Default/Standalone.html +187 -1
  16. data/doc/Compony/ComponentMixins/Default.html +1 -1
  17. data/doc/Compony/ComponentMixins/Resourceful.html +2 -2
  18. data/doc/Compony/ComponentMixins.html +1 -1
  19. data/doc/Compony/Components/Button.html +2 -2
  20. data/doc/Compony/Components/Buttons/CssButton.html +282 -0
  21. data/doc/Compony/Components/Buttons/Link.html +252 -0
  22. data/doc/Compony/Components/Buttons.html +126 -0
  23. data/doc/Compony/Components/Destroy.html +11 -11
  24. data/doc/Compony/Components/Edit.html +14 -14
  25. data/doc/Compony/Components/Form.html +100 -100
  26. data/doc/Compony/Components/Index.html +2 -2
  27. data/doc/Compony/Components/List.html +3 -3
  28. data/doc/Compony/Components/New.html +2 -2
  29. data/doc/Compony/Components/Show.html +24 -24
  30. data/doc/Compony/Components/WithForm.html +3 -3
  31. data/doc/Compony/Components.html +5 -3
  32. data/doc/Compony/ControllerMixin.html +2 -2
  33. data/doc/Compony/Engine.html +1 -1
  34. data/doc/Compony/ExposedIntentsDsl.html +403 -0
  35. data/doc/Compony/Intent.html +1503 -0
  36. data/doc/Compony/MethodAccessibleHash.html +1 -1
  37. data/doc/Compony/ModelFields/Anchormodel.html +1 -1
  38. data/doc/Compony/ModelFields/Association.html +2 -2
  39. data/doc/Compony/ModelFields/Attachment.html +1 -1
  40. data/doc/Compony/ModelFields/Base.html +1 -1
  41. data/doc/Compony/ModelFields/Boolean.html +1 -1
  42. data/doc/Compony/ModelFields/Color.html +1 -1
  43. data/doc/Compony/ModelFields/Currency.html +1 -1
  44. data/doc/Compony/ModelFields/Date.html +1 -1
  45. data/doc/Compony/ModelFields/Datetime.html +1 -1
  46. data/doc/Compony/ModelFields/Decimal.html +1 -1
  47. data/doc/Compony/ModelFields/Email.html +1 -1
  48. data/doc/Compony/ModelFields/Float.html +1 -1
  49. data/doc/Compony/ModelFields/Integer.html +1 -1
  50. data/doc/Compony/ModelFields/Percentage.html +1 -1
  51. data/doc/Compony/ModelFields/Phone.html +1 -1
  52. data/doc/Compony/ModelFields/RichText.html +1 -1
  53. data/doc/Compony/ModelFields/String.html +1 -1
  54. data/doc/Compony/ModelFields/Text.html +1 -1
  55. data/doc/Compony/ModelFields/Time.html +1 -1
  56. data/doc/Compony/ModelFields/Url.html +1 -1
  57. data/doc/Compony/ModelFields.html +1 -1
  58. data/doc/Compony/ModelMixin.html +1 -1
  59. data/doc/Compony/NaturalOrdering.html +1 -1
  60. data/doc/Compony/RequestContext.html +177 -14
  61. data/doc/Compony/Version.html +1 -1
  62. data/doc/Compony/ViewHelpers.html +15 -272
  63. data/doc/Compony/VirtualModel.html +1 -1
  64. data/doc/Compony.html +303 -837
  65. data/doc/ComponyController.html +1 -1
  66. data/doc/_index.html +30 -2
  67. data/doc/class_list.html +1 -1
  68. data/doc/file.README.html +11 -18
  69. data/doc/guide/basic_component.md +12 -8
  70. data/doc/guide/example.md +17 -17
  71. data/doc/guide/feasibility.md +4 -2
  72. data/doc/guide/generators.md +4 -2
  73. data/doc/guide/inheritance.md +4 -2
  74. data/doc/guide/installation.md +4 -2
  75. data/doc/guide/intents.md +167 -0
  76. data/doc/guide/internal_datastructures.md +4 -2
  77. data/doc/guide/model_fields.md +4 -2
  78. data/doc/guide/nesting.md +5 -3
  79. data/doc/guide/ownership.md +5 -3
  80. data/doc/guide/pre_built_components/destroy.md +3 -3
  81. data/doc/guide/pre_built_components/edit.md +1 -1
  82. data/doc/guide/pre_built_components/form.md +1 -1
  83. data/doc/guide/pre_built_components/index.md +1 -1
  84. data/doc/guide/pre_built_components/list.md +1 -1
  85. data/doc/guide/pre_built_components/new.md +2 -2
  86. data/doc/guide/pre_built_components/show.md +1 -1
  87. data/doc/guide/pre_built_components/with_form.md +1 -1
  88. data/doc/guide/pre_built_components.md +4 -3
  89. data/doc/guide/resourceful.md +5 -3
  90. data/doc/guide/standalone.md +10 -2
  91. data/doc/guide/virtual_models.md +4 -2
  92. data/doc/index.html +11 -18
  93. data/doc/method_list.html +273 -161
  94. data/doc/top-level-namespace.html +1 -1
  95. data/lib/compony/component.rb +19 -48
  96. data/lib/compony/component_mixins/default/standalone/standalone_dsl.rb +2 -2
  97. data/lib/compony/component_mixins/default/standalone.rb +16 -0
  98. data/lib/compony/component_mixins/resourceful.rb +1 -1
  99. data/lib/compony/components/buttons/css_button.rb +32 -0
  100. data/lib/compony/components/buttons/link.rb +31 -0
  101. data/lib/compony/components/destroy.rb +9 -8
  102. data/lib/compony/components/edit.rb +5 -4
  103. data/lib/compony/components/form.rb +7 -1
  104. data/lib/compony/components/index.rb +2 -2
  105. data/lib/compony/components/list.rb +4 -4
  106. data/lib/compony/components/new.rb +1 -1
  107. data/lib/compony/components/show.rb +8 -11
  108. data/lib/compony/components/with_form.rb +1 -1
  109. data/lib/compony/exposed_intents_dsl.rb +29 -0
  110. data/lib/compony/intent.rb +145 -0
  111. data/lib/compony/model_fields/association.rb +1 -1
  112. data/lib/compony/request_context.rb +21 -0
  113. data/lib/compony/view_helpers.rb +5 -48
  114. data/lib/compony.rb +63 -149
  115. metadata +12 -6
  116. data/doc/guide/helpers.md +0 -156
  117. data/doc/guide/pre_built_components/button.md +0 -8
  118. data/doc/guide/root_actions.md +0 -67
  119. data/lib/compony/components/button.rb +0 -61
@@ -114,7 +114,7 @@
114
114
  </div>
115
115
 
116
116
  <div id="footer">
117
- Generated on Thu Nov 20 12:44:24 2025 by
117
+ Generated on Thu Nov 27 16:02:23 2025 by
118
118
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
119
119
  0.9.34 (ruby-3.3.5).
120
120
  </div>
data/doc/_index.html CHANGED
@@ -124,7 +124,7 @@
124
124
  </li>
125
125
 
126
126
  <li>
127
- <span class='object_link'><a href="Compony/Components/Button.html" title="Compony::Components::Button (class)">Button</a></span>
127
+ <span class='object_link'><a href="Compony/Components/Buttons.html" title="Compony::Components::Buttons (module)">Buttons</a></span>
128
128
 
129
129
  <small>(Compony::Components)</small>
130
130
 
@@ -198,6 +198,13 @@
198
198
 
199
199
  </li>
200
200
 
201
+ <li>
202
+ <span class='object_link'><a href="Compony/Components/Buttons/CssButton.html" title="Compony::Components::Buttons::CssButton (class)">CssButton</a></span>
203
+
204
+ <small>(Compony::Components::Buttons)</small>
205
+
206
+ </li>
207
+
201
208
  <li>
202
209
  <span class='object_link'><a href="Compony/ModelFields/Currency.html" title="Compony::ModelFields::Currency (class)">Currency</a></span>
203
210
 
@@ -277,6 +284,13 @@
277
284
 
278
285
  </li>
279
286
 
287
+ <li>
288
+ <span class='object_link'><a href="Compony/ExposedIntentsDsl.html" title="Compony::ExposedIntentsDsl (class)">ExposedIntentsDsl</a></span>
289
+
290
+ <small>(Compony)</small>
291
+
292
+ </li>
293
+
280
294
  </ul>
281
295
  </ul>
282
296
 
@@ -321,6 +335,13 @@
321
335
 
322
336
  </li>
323
337
 
338
+ <li>
339
+ <span class='object_link'><a href="Compony/Intent.html" title="Compony::Intent (class)">Intent</a></span>
340
+
341
+ <small>(Compony)</small>
342
+
343
+ </li>
344
+
324
345
  </ul>
325
346
  </ul>
326
347
 
@@ -339,6 +360,13 @@
339
360
 
340
361
  </li>
341
362
 
363
+ <li>
364
+ <span class='object_link'><a href="Compony/Components/Buttons/Link.html" title="Compony::Components::Buttons::Link (class)">Link</a></span>
365
+
366
+ <small>(Compony::Components::Buttons)</small>
367
+
368
+ </li>
369
+
342
370
  <li>
343
371
  <span class='object_link'><a href="Compony/Components/List.html" title="Compony::Components::List (class)">List</a></span>
344
372
 
@@ -594,7 +622,7 @@
594
622
  </div>
595
623
 
596
624
  <div id="footer">
597
- Generated on Thu Nov 20 12:44:23 2025 by
625
+ Generated on Thu Nov 27 16:02:21 2025 by
598
626
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
599
627
  0.9.34 (ruby-3.3.5).
600
628
  </div>
data/doc/class_list.html CHANGED
@@ -43,7 +43,7 @@
43
43
 
44
44
  <ul id="full_list" class="class">
45
45
  <li id="object_" class="odd"><div class="item" style="padding-left:30px"><span class='object_link'><a href="top-level-namespace.html" title="Top Level Namespace (root)">Top Level Namespace</a></span></div></li>
46
- <li id='object_ComponentGenerator' class='even'><div class='item' style='padding-left:30px'><span class='object_link'><a href="ComponentGenerator.html" title="ComponentGenerator (class)">ComponentGenerator</a></span> &lt; NamedBase<small class='search_info'>Top Level Namespace</small></div></li><li id='object_Components' class='odd'><div class='item' style='padding-left:30px'><span class='object_link'><a href="Components.html" title="Components (module)">Components</a></span><small class='search_info'>Top Level Namespace</small></div></li><li id='object_ComponentsGenerator' class='even'><div class='item' style='padding-left:30px'><span class='object_link'><a href="ComponentsGenerator.html" title="ComponentsGenerator (class)">ComponentsGenerator</a></span> &lt; NamedBase<small class='search_info'>Top Level Namespace</small></div></li><li id='object_Compony' class='odd'><div class='item' style='padding-left:30px'><a class='toggle'></a> <span class='object_link'><a href="Compony.html" title="Compony (module)">Compony</a></span><small class='search_info'>Top Level Namespace</small></div><ul><li id='object_Compony::Component' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/Component.html" title="Compony::Component (class)">Component</a></span> &lt; Object<small class='search_info'>Compony</small></div></li><li id='object_Compony::ComponentMixins' class='collapsed odd'><div class='item' style='padding-left:45px'><a class='toggle'></a> <span class='object_link'><a href="Compony/ComponentMixins.html" title="Compony::ComponentMixins (module)">ComponentMixins</a></span><small class='search_info'>Compony</small></div><ul><li id='object_Compony::ComponentMixins::Default' class='collapsed'><div class='item' style='padding-left:60px'><a class='toggle'></a> <span class='object_link'><a href="Compony/ComponentMixins/Default.html" title="Compony::ComponentMixins::Default (module)">Default</a></span><small class='search_info'>Compony::ComponentMixins</small></div><ul><li id='object_Compony::ComponentMixins::Default::Labelling' class='collapsed'><div class='item' style='padding-left:75px'><span class='object_link'><a href="Compony/ComponentMixins/Default/Labelling.html" title="Compony::ComponentMixins::Default::Labelling (module)">Labelling</a></span><small class='search_info'>Compony::ComponentMixins::Default</small></div></li><li id='object_Compony::ComponentMixins::Default::Standalone' class='collapsed'><div class='item' style='padding-left:75px'><a class='toggle'></a> <span class='object_link'><a href="Compony/ComponentMixins/Default/Standalone.html" title="Compony::ComponentMixins::Default::Standalone (module)">Standalone</a></span><small class='search_info'>Compony::ComponentMixins::Default</small></div><ul><li id='object_Compony::ComponentMixins::Default::Standalone::ResourcefulVerbDsl' class='collapsed'><div class='item' style='padding-left:90px'><span class='object_link'><a href="Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html" title="Compony::ComponentMixins::Default::Standalone::ResourcefulVerbDsl (class)">ResourcefulVerbDsl</a></span> &lt; VerbDsl<small class='search_info'>Compony::ComponentMixins::Default::Standalone</small></div></li><li id='object_Compony::ComponentMixins::Default::Standalone::StandaloneDsl' class='collapsed'><div class='item' style='padding-left:90px'><span class='object_link'><a href="Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html" title="Compony::ComponentMixins::Default::Standalone::StandaloneDsl (class)">StandaloneDsl</a></span> &lt; Base<small class='search_info'>Compony::ComponentMixins::Default::Standalone</small></div></li><li id='object_Compony::ComponentMixins::Default::Standalone::VerbDsl' class='collapsed'><div class='item' style='padding-left:90px'><span class='object_link'><a href="Compony/ComponentMixins/Default/Standalone/VerbDsl.html" title="Compony::ComponentMixins::Default::Standalone::VerbDsl (class)">VerbDsl</a></span> &lt; Base<small class='search_info'>Compony::ComponentMixins::Default::Standalone</small></div></li></ul></li></ul></li><li id='object_Compony::ComponentMixins::Resourceful' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ComponentMixins/Resourceful.html" title="Compony::ComponentMixins::Resourceful (module)">Resourceful</a></span><small class='search_info'>Compony::ComponentMixins</small></div></li></ul></li><li id='object_Compony::Components' class='collapsed even'><div class='item' style='padding-left:45px'><a class='toggle'></a> <span class='object_link'><a href="Compony/Components.html" title="Compony::Components (module)">Components</a></span><small class='search_info'>Compony</small></div><ul><li id='object_Compony::Components::Button' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Button.html" title="Compony::Components::Button (class)">Button</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Destroy' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Destroy.html" title="Compony::Components::Destroy (class)">Destroy</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Edit' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Edit.html" title="Compony::Components::Edit (class)">Edit</a></span> &lt; WithForm<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Form' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Form.html" title="Compony::Components::Form (class)">Form</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Index' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Index.html" title="Compony::Components::Index (class)">Index</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::List' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/List.html" title="Compony::Components::List (class)">List</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::New' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/New.html" title="Compony::Components::New (class)">New</a></span> &lt; WithForm<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Show' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Show.html" title="Compony::Components::Show (class)">Show</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::WithForm' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/WithForm.html" title="Compony::Components::WithForm (class)">WithForm</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li></ul></li><li id='object_Compony::ControllerMixin' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/ControllerMixin.html" title="Compony::ControllerMixin (module)">ControllerMixin</a></span><small class='search_info'>Compony</small></div></li><li id='object_Compony::Engine' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/Engine.html" title="Compony::Engine (class)">Engine</a></span> &lt; Engine<small class='search_info'>Compony</small></div></li><li id='object_Compony::MethodAccessibleHash' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/MethodAccessibleHash.html" title="Compony::MethodAccessibleHash (class)">MethodAccessibleHash</a></span> &lt; Hash<small class='search_info'>Compony</small></div></li><li id='object_Compony::ModelFields' class='collapsed even'><div class='item' style='padding-left:45px'><a class='toggle'></a> <span class='object_link'><a href="Compony/ModelFields.html" title="Compony::ModelFields (module)">ModelFields</a></span><small class='search_info'>Compony</small></div><ul><li id='object_Compony::ModelFields::Anchormodel' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Anchormodel.html" title="Compony::ModelFields::Anchormodel (class)">Anchormodel</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Association' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Association.html" title="Compony::ModelFields::Association (class)">Association</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Attachment' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Attachment.html" title="Compony::ModelFields::Attachment (class)">Attachment</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Base' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Base.html" title="Compony::ModelFields::Base (class)">Base</a></span> &lt; Object<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Boolean' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Boolean.html" title="Compony::ModelFields::Boolean (class)">Boolean</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Color' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Color.html" title="Compony::ModelFields::Color (class)">Color</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Currency' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Currency.html" title="Compony::ModelFields::Currency (class)">Currency</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Date' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Date.html" title="Compony::ModelFields::Date (class)">Date</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Datetime' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Datetime.html" title="Compony::ModelFields::Datetime (class)">Datetime</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Decimal' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Decimal.html" title="Compony::ModelFields::Decimal (class)">Decimal</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Email' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Email.html" title="Compony::ModelFields::Email (class)">Email</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Float' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Float.html" title="Compony::ModelFields::Float (class)">Float</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Integer' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Integer.html" title="Compony::ModelFields::Integer (class)">Integer</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Percentage' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Percentage.html" title="Compony::ModelFields::Percentage (class)">Percentage</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Phone' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Phone.html" title="Compony::ModelFields::Phone (class)">Phone</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::RichText' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/RichText.html" title="Compony::ModelFields::RichText (class)">RichText</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::String' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/String.html" title="Compony::ModelFields::String (class)">String</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Text' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Text.html" title="Compony::ModelFields::Text (class)">Text</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Time' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Time.html" title="Compony::ModelFields::Time (class)">Time</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Url' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Url.html" title="Compony::ModelFields::Url (class)">Url</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li></ul></li><li id='object_Compony::ModelMixin' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/ModelMixin.html" title="Compony::ModelMixin (module)">ModelMixin</a></span><small class='search_info'>Compony</small></div></li><li id='object_Compony::NaturalOrdering' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/NaturalOrdering.html" title="Compony::NaturalOrdering (class)">NaturalOrdering</a></span> &lt; Array<small class='search_info'>Compony</small></div></li><li id='object_Compony::RequestContext' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/RequestContext.html" title="Compony::RequestContext (class)">RequestContext</a></span> &lt; Base<small class='search_info'>Compony</small></div></li><li id='object_Compony::Version' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/Version.html" title="Compony::Version (module)">Version</a></span><small class='search_info'>Compony</small></div></li><li id='object_Compony::ViewHelpers' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/ViewHelpers.html" title="Compony::ViewHelpers (module)">ViewHelpers</a></span><small class='search_info'>Compony</small></div></li><li id='object_Compony::VirtualModel' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/VirtualModel.html" title="Compony::VirtualModel (class)">VirtualModel</a></span> &lt; Object<small class='search_info'>Compony</small></div></li></ul></li><li id='object_ComponyController' class='odd'><div class='item' style='padding-left:30px'><span class='object_link'><a href="ComponyController.html" title="ComponyController (class)">ComponyController</a></span> &lt; ApplicationController<small class='search_info'>Top Level Namespace</small></div></li>
46
+ <li id='object_ComponentGenerator' class='even'><div class='item' style='padding-left:30px'><span class='object_link'><a href="ComponentGenerator.html" title="ComponentGenerator (class)">ComponentGenerator</a></span> &lt; NamedBase<small class='search_info'>Top Level Namespace</small></div></li><li id='object_Components' class='odd'><div class='item' style='padding-left:30px'><span class='object_link'><a href="Components.html" title="Components (module)">Components</a></span><small class='search_info'>Top Level Namespace</small></div></li><li id='object_ComponentsGenerator' class='even'><div class='item' style='padding-left:30px'><span class='object_link'><a href="ComponentsGenerator.html" title="ComponentsGenerator (class)">ComponentsGenerator</a></span> &lt; NamedBase<small class='search_info'>Top Level Namespace</small></div></li><li id='object_Compony' class='odd'><div class='item' style='padding-left:30px'><a class='toggle'></a> <span class='object_link'><a href="Compony.html" title="Compony (module)">Compony</a></span><small class='search_info'>Top Level Namespace</small></div><ul><li id='object_Compony::Component' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/Component.html" title="Compony::Component (class)">Component</a></span> &lt; Object<small class='search_info'>Compony</small></div></li><li id='object_Compony::ComponentMixins' class='collapsed odd'><div class='item' style='padding-left:45px'><a class='toggle'></a> <span class='object_link'><a href="Compony/ComponentMixins.html" title="Compony::ComponentMixins (module)">ComponentMixins</a></span><small class='search_info'>Compony</small></div><ul><li id='object_Compony::ComponentMixins::Default' class='collapsed'><div class='item' style='padding-left:60px'><a class='toggle'></a> <span class='object_link'><a href="Compony/ComponentMixins/Default.html" title="Compony::ComponentMixins::Default (module)">Default</a></span><small class='search_info'>Compony::ComponentMixins</small></div><ul><li id='object_Compony::ComponentMixins::Default::Labelling' class='collapsed'><div class='item' style='padding-left:75px'><span class='object_link'><a href="Compony/ComponentMixins/Default/Labelling.html" title="Compony::ComponentMixins::Default::Labelling (module)">Labelling</a></span><small class='search_info'>Compony::ComponentMixins::Default</small></div></li><li id='object_Compony::ComponentMixins::Default::Standalone' class='collapsed'><div class='item' style='padding-left:75px'><a class='toggle'></a> <span class='object_link'><a href="Compony/ComponentMixins/Default/Standalone.html" title="Compony::ComponentMixins::Default::Standalone (module)">Standalone</a></span><small class='search_info'>Compony::ComponentMixins::Default</small></div><ul><li id='object_Compony::ComponentMixins::Default::Standalone::ResourcefulVerbDsl' class='collapsed'><div class='item' style='padding-left:90px'><span class='object_link'><a href="Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html" title="Compony::ComponentMixins::Default::Standalone::ResourcefulVerbDsl (class)">ResourcefulVerbDsl</a></span> &lt; VerbDsl<small class='search_info'>Compony::ComponentMixins::Default::Standalone</small></div></li><li id='object_Compony::ComponentMixins::Default::Standalone::StandaloneDsl' class='collapsed'><div class='item' style='padding-left:90px'><span class='object_link'><a href="Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html" title="Compony::ComponentMixins::Default::Standalone::StandaloneDsl (class)">StandaloneDsl</a></span> &lt; Base<small class='search_info'>Compony::ComponentMixins::Default::Standalone</small></div></li><li id='object_Compony::ComponentMixins::Default::Standalone::VerbDsl' class='collapsed'><div class='item' style='padding-left:90px'><span class='object_link'><a href="Compony/ComponentMixins/Default/Standalone/VerbDsl.html" title="Compony::ComponentMixins::Default::Standalone::VerbDsl (class)">VerbDsl</a></span> &lt; Base<small class='search_info'>Compony::ComponentMixins::Default::Standalone</small></div></li></ul></li></ul></li><li id='object_Compony::ComponentMixins::Resourceful' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ComponentMixins/Resourceful.html" title="Compony::ComponentMixins::Resourceful (module)">Resourceful</a></span><small class='search_info'>Compony::ComponentMixins</small></div></li></ul></li><li id='object_Compony::Components' class='collapsed even'><div class='item' style='padding-left:45px'><a class='toggle'></a> <span class='object_link'><a href="Compony/Components.html" title="Compony::Components (module)">Components</a></span><small class='search_info'>Compony</small></div><ul><li id='object_Compony::Components::Buttons' class='collapsed'><div class='item' style='padding-left:60px'><a class='toggle'></a> <span class='object_link'><a href="Compony/Components/Buttons.html" title="Compony::Components::Buttons (module)">Buttons</a></span><small class='search_info'>Compony::Components</small></div><ul><li id='object_Compony::Components::Buttons::CssButton' class='collapsed'><div class='item' style='padding-left:75px'><span class='object_link'><a href="Compony/Components/Buttons/CssButton.html" title="Compony::Components::Buttons::CssButton (class)">CssButton</a></span> &lt; Link<small class='search_info'>Compony::Components::Buttons</small></div></li><li id='object_Compony::Components::Buttons::Link' class='collapsed'><div class='item' style='padding-left:75px'><span class='object_link'><a href="Compony/Components/Buttons/Link.html" title="Compony::Components::Buttons::Link (class)">Link</a></span> &lt; Component<small class='search_info'>Compony::Components::Buttons</small></div></li></ul></li><li id='object_Compony::Components::Destroy' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Destroy.html" title="Compony::Components::Destroy (class)">Destroy</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Edit' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Edit.html" title="Compony::Components::Edit (class)">Edit</a></span> &lt; WithForm<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Form' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Form.html" title="Compony::Components::Form (class)">Form</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Index' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Index.html" title="Compony::Components::Index (class)">Index</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::List' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/List.html" title="Compony::Components::List (class)">List</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::New' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/New.html" title="Compony::Components::New (class)">New</a></span> &lt; WithForm<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::Show' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/Show.html" title="Compony::Components::Show (class)">Show</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li><li id='object_Compony::Components::WithForm' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/Components/WithForm.html" title="Compony::Components::WithForm (class)">WithForm</a></span> &lt; Component<small class='search_info'>Compony::Components</small></div></li></ul></li><li id='object_Compony::ControllerMixin' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/ControllerMixin.html" title="Compony::ControllerMixin (module)">ControllerMixin</a></span><small class='search_info'>Compony</small></div></li><li id='object_Compony::Engine' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/Engine.html" title="Compony::Engine (class)">Engine</a></span> &lt; Engine<small class='search_info'>Compony</small></div></li><li id='object_Compony::ExposedIntentsDsl' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/ExposedIntentsDsl.html" title="Compony::ExposedIntentsDsl (class)">ExposedIntentsDsl</a></span> &lt; Base<small class='search_info'>Compony</small></div></li><li id='object_Compony::Intent' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/Intent.html" title="Compony::Intent (class)">Intent</a></span> &lt; Object<small class='search_info'>Compony</small></div></li><li id='object_Compony::MethodAccessibleHash' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/MethodAccessibleHash.html" title="Compony::MethodAccessibleHash (class)">MethodAccessibleHash</a></span> &lt; Hash<small class='search_info'>Compony</small></div></li><li id='object_Compony::ModelFields' class='collapsed even'><div class='item' style='padding-left:45px'><a class='toggle'></a> <span class='object_link'><a href="Compony/ModelFields.html" title="Compony::ModelFields (module)">ModelFields</a></span><small class='search_info'>Compony</small></div><ul><li id='object_Compony::ModelFields::Anchormodel' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Anchormodel.html" title="Compony::ModelFields::Anchormodel (class)">Anchormodel</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Association' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Association.html" title="Compony::ModelFields::Association (class)">Association</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Attachment' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Attachment.html" title="Compony::ModelFields::Attachment (class)">Attachment</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Base' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Base.html" title="Compony::ModelFields::Base (class)">Base</a></span> &lt; Object<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Boolean' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Boolean.html" title="Compony::ModelFields::Boolean (class)">Boolean</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Color' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Color.html" title="Compony::ModelFields::Color (class)">Color</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Currency' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Currency.html" title="Compony::ModelFields::Currency (class)">Currency</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Date' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Date.html" title="Compony::ModelFields::Date (class)">Date</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Datetime' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Datetime.html" title="Compony::ModelFields::Datetime (class)">Datetime</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Decimal' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Decimal.html" title="Compony::ModelFields::Decimal (class)">Decimal</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Email' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Email.html" title="Compony::ModelFields::Email (class)">Email</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Float' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Float.html" title="Compony::ModelFields::Float (class)">Float</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Integer' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Integer.html" title="Compony::ModelFields::Integer (class)">Integer</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Percentage' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Percentage.html" title="Compony::ModelFields::Percentage (class)">Percentage</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Phone' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Phone.html" title="Compony::ModelFields::Phone (class)">Phone</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::RichText' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/RichText.html" title="Compony::ModelFields::RichText (class)">RichText</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::String' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/String.html" title="Compony::ModelFields::String (class)">String</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Text' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Text.html" title="Compony::ModelFields::Text (class)">Text</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Time' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Time.html" title="Compony::ModelFields::Time (class)">Time</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li><li id='object_Compony::ModelFields::Url' class='collapsed'><div class='item' style='padding-left:60px'><span class='object_link'><a href="Compony/ModelFields/Url.html" title="Compony::ModelFields::Url (class)">Url</a></span> &lt; Base<small class='search_info'>Compony::ModelFields</small></div></li></ul></li><li id='object_Compony::ModelMixin' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/ModelMixin.html" title="Compony::ModelMixin (module)">ModelMixin</a></span><small class='search_info'>Compony</small></div></li><li id='object_Compony::NaturalOrdering' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/NaturalOrdering.html" title="Compony::NaturalOrdering (class)">NaturalOrdering</a></span> &lt; Array<small class='search_info'>Compony</small></div></li><li id='object_Compony::RequestContext' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/RequestContext.html" title="Compony::RequestContext (class)">RequestContext</a></span> &lt; Base<small class='search_info'>Compony</small></div></li><li id='object_Compony::Version' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/Version.html" title="Compony::Version (module)">Version</a></span><small class='search_info'>Compony</small></div></li><li id='object_Compony::ViewHelpers' class='collapsed odd'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/ViewHelpers.html" title="Compony::ViewHelpers (module)">ViewHelpers</a></span><small class='search_info'>Compony</small></div></li><li id='object_Compony::VirtualModel' class='collapsed even'><div class='item' style='padding-left:45px'><span class='object_link'><a href="Compony/VirtualModel.html" title="Compony::VirtualModel (class)">VirtualModel</a></span> &lt; Object<small class='search_info'>Compony</small></div></li></ul></li><li id='object_ComponyController' class='odd'><div class='item' style='padding-left:30px'><span class='object_link'><a href="ComponyController.html" title="ComponyController (class)">ComponyController</a></span> &lt; ApplicationController<small class='search_info'>Top Level Namespace</small></div></li>
47
47
 
48
48
  </ul>
49
49
  </div>
data/doc/file.README.html CHANGED
@@ -71,7 +71,7 @@
71
71
 
72
72
  <h1 id="label-About+Compony">About Compony</h1>
73
73
 
74
- <p>Compony is a Gem that allows you to write your Rails application in component-style fashion. It combines a controller action and route along with its view into a single Ruby class. This allows writing much DRYer code, using inheritance even in views and much easier refactoring for your Rails applications, helping you to keep the code clean as the application evolves.</p>
74
+ <p>Compony is a Gem that allows you to write your Rails application in <strong>component-style</strong> fashion. It combines a controller action and route along with its view into a single Ruby class. Along with the DSL approach and a powerful model mixin, Compony <strong>makes your application’s code more semantic</strong>, allows writing <strong>much DRYer code</strong>, using inheritance even in views and <strong>much easier refactoring</strong> for your Rails applications, helping you to <strong>keep the code clean as the application evolves</strong>.</p>
75
75
 
76
76
  <p>Compony’s key aspects:</p>
77
77
  <ul><li>
@@ -79,17 +79,18 @@
79
79
  </li><li>
80
80
  <p>Refactor common logic into your own components and inherit from them to DRY up your code.</p>
81
81
  </li><li>
82
- <p>Compony’s powerful model mixin allows you to define metadata in your models and react to them. Examples:</p>
83
- </li><li>
82
+ <p>Compony’s model mixin allows you to define metadata in your models and react to them, resulting in more semantic code. Examples:</p>
83
+ <ul><li>
84
84
  <p>Compony fields capture attributes that should be made visible in your UI. They allow you to implement formatting behavior and parameter sanitization for various types, e.g. URLs, phone numbers, colors etc. ready to be used in your lists, detail panels, or forms.</p>
85
85
  </li><li>
86
86
  <p>Compony’s feasibility framework allows you to prohibit actions based on conditions, along with an error message. This causes all buttons pointing to that action to be disabled with a meaningful error message.</p>
87
+ </li></ul>
87
88
  </li><li>
88
89
  <p>Compony only structures your code, but provides no style whatsoever. It is like a bookshelf rather than a reader’s library. You still implement your own layouts, CSS and Javascript to define the behavior of your front-end.</p>
89
90
  </li><li>
90
- <p>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>
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>
91
92
  </li><li>
92
- <p>Compony is built for Rails 7 and fully supports Stimulus and Turbo Drive. Turbo Frames and Streams are not yet targeted, so Compony is currently meant for websites where every click triggers a “full page load” (in quotes because they are not actually full page loads due to Turbo Drive).</p>
93
+ <p>Compony is built for Rails 7, 7.1 and 8, and fully supports Stimulus and Turbo Drive. Turbo Frames and Streams are not yet targeted, but can be used alongside, just like with any Rails application.</p>
93
94
  </li><li>
94
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>
95
96
  </li></ul>
@@ -98,7 +99,7 @@
98
99
 
99
100
  <p>I am actively using this framework in various applications and both performance and reliability are good. However, the project is experimental and lacking peer reviews and especially automatic testing, such as unit and integration tests. Also, expect there to be (<a href="/CHANGELOG_md.html">documented</a>) breaking changes in the future, as the API will likely be further refined, resulting in renamings and deprecation of various methods.</p>
100
101
 
101
- <h2 id="label-Related+projects">Related projects</h2>
102
+ <h2 id="label-Other+projects+exploring+similar+concepts">Other projects exploring similar concepts</h2>
102
103
 
103
104
  <p>A project with a similar aim, but a different approach, is <a href="https://github.com/phlex-ruby/phlex">Phlex</a>.</p>
104
105
 
@@ -122,11 +123,9 @@
122
123
  </li><li>
123
124
  <p><a href="./doc/guide/resourceful_md.html">Resourceful components</a>: How to create components that deal with Rails-style resources</p>
124
125
  </li><li>
125
- <p><a href="./doc/guide/helpers_md.html">Compony helpers, links and buttons</a>: Important tools for concise Compony programming</p>
126
- </li><li>
127
- <p><a href="./doc/guide/root_actions_md.html">Root actions</a>: How to provide context-sensitive buttons to your application</p>
126
+ <p><a href="./doc/guide/intents_md.html">Intents</a>: How to point to a component and provide custom components for rendering intents</p>
128
127
  </li><li>
129
- <p><a href="./doc/guide/feasibility_md.html">Feasibility</a>: Disabiling buttons based on context (contains <code>prevent</code>)</p>
128
+ <p><a href="./doc/guide/feasibility_md.html">Feasibility</a>: Disabiling intents based on context (contains <code>prevent</code>)</p>
130
129
  </li><li>
131
130
  <p><a href="./doc/guide/ownership_md.html">Ownership</a>: Informing Compony that a resource is conceptually part of another resource</p>
132
131
  </li><li>
@@ -143,8 +142,6 @@
143
142
  <ul><li>
144
143
  <p><a href="./doc/guide/pre_built_components_md.html">Introduction</a></p>
145
144
  </li><li>
146
- <p><a href="./doc/guide/pre_built_components/button_md.html">Button</a>: This component class gets instanciated whenever using <code>Compony.button</code> or <code>compony_button</code>.</p>
147
- </li><li>
148
145
  <p><a href="./doc/guide/pre_built_components/show_md.html">Show</a>: Compony’s equivalent to Rail’s <code>show</code> controller action</p>
149
146
  </li><li>
150
147
  <p><a href="./doc/guide/pre_built_components/index_md.html">Index</a>: Compony’s equivalent to Rail’s <code>index</code> controller action</p>
@@ -189,11 +186,7 @@
189
186
  </li><li>
190
187
  <p>At this point, I haven’t gotten into Turbo Streams and Turbo Frames. It would be interesting to extend Compony such it also makes writing applications using these features much easier.</p>
191
188
  </li><li>
192
- <p>Feasibility:</p>
193
- </li><li>
194
- <p>The feasibility framework does not yet enforce prevention, but only has effects on buttons. Actions should be structured more explicitly such that prevention becomes as tight as authorization.</p>
195
- </li><li>
196
- <p>Feasibility for links is not yet implemented.</p>
189
+ <p>The feasibility framework does not yet enforce prevention, but only has effects on buttons.</p>
197
190
  </li><li>
198
191
  <p>Compony is not compatible with <code>tailwindcss-rails</code>. This is likely due to Tailwind automatically removing any CSS that is not used by the application and the usage detection not picking up Compony components, as their content is not provided in views.</p>
199
192
  </li></ul>
@@ -206,7 +199,7 @@
206
199
  </div></div>
207
200
 
208
201
  <div id="footer">
209
- Generated on Thu Nov 20 12:44:23 2025 by
202
+ Generated on Thu Nov 27 16:02:21 2025 by
210
203
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
211
204
  0.9.34 (ruby-3.3.5).
212
205
  </div>
@@ -1,4 +1,4 @@
1
- [Back to the guide](/README.md#guide)
1
+ [Back to the guide](/README.md#guide--documentation)
2
2
 
3
3
  # What is a component?
4
4
 
@@ -49,7 +49,7 @@ Note that rendering a component always requires the controller as an argument. I
49
49
 
50
50
  ## Setup
51
51
 
52
- Every component must call the static method `setup` which will contain most of the code of your components. This can be achieved either by a call directly from your class, or by inheriting from a component that calls `setup`. If both classes call the method, the inherited class' `setup` is run first and the inheriting's second, thus, the child class can override setup properties of the parent class.
52
+ Every component must call the static method `setup` which will contain most of the code of your components. This can be achieved either by a call directly from your class, or by [inheriting](/doc/guide/inheritance.md) from a component that calls `setup`. If both classes call the method, the inherited class' `setup` is run first and the inheriting's second, thus, the child class can override setup properties of the parent class.
53
53
 
54
54
  Call setup as follows:
55
55
 
@@ -65,7 +65,7 @@ The code in setup is run at the end the component's initialization. In this bloc
65
65
 
66
66
  ### Labelling
67
67
 
68
- This defines a component's label, both as seen from within the component and from the outside. You can query the label in order to display it as a title in your component. Links and buttons to components will also display the same label, allowing you to easily rename a component, including any parts of your UI that point to it.
68
+ This defines a component's label, both as seen from within the component and from the outside, e.g. from an [intent](/doc/guide/intents.md). You can query the label in order to display it as a title in your component. Links and buttons to components will also display the same label, allowing you to easily rename a component, including any parts of your UI that point to it.
69
69
 
70
70
  Labels come in different formats, short and long, with long being the default. Define them as follows if your component is about a specific object, for instance a show component for a specific user:
71
71
 
@@ -86,7 +86,7 @@ label(User.first) # This returns the long version: "Displaying user John Doe".
86
86
  label(User.first, format: :short) # This returns the short version "John Doe".
87
87
  ```
88
88
 
89
- It is important to note that since your label block takes an argument, you must provide the argument when reading the label (exception: if the component implements the method `data` returning an object, the argument can be omitted and the label block will be provided that object). Only up to one argument is supported.
89
+ It is important to note that since your label block takes an argument, you must provide the argument when reading the label. Only up to one argument is supported. Typically, label blocks of all [resourceful components](/doc/guide/resourceful.md) take 1 argument while all others take 0.
90
90
 
91
91
  Here is an example on how labelling looks like for a component that is not about a specific object, such as an index component for users:
92
92
 
@@ -124,7 +124,7 @@ my_component.icon # [:'fa-solid', :circle]
124
124
 
125
125
  ### Providing content
126
126
 
127
- Basic components do not come with default content. Instead, you must call the method `content` inside the setup block and provide a block containing your view. It will be evaluated inside a `RequestContext` (more on that later).
127
+ Basic components do not come with default content. Instead, you must call the method `content` inside the setup block and provide a block containing your view. It will be evaluated inside a [request context](/doc/guide/internal_datastructures.md#requestcontext).
128
128
 
129
129
  In this block, provide the HTML to be generated using Dyny: [https://github.com/kalsan/dyny](https://github.com/kalsan/dyny)
130
130
 
@@ -170,7 +170,7 @@ This results in:
170
170
  - This paragraph is inserted between the others.
171
171
  - Thank you and see you tonight.
172
172
 
173
- As you see, overusing this feature can lead to messy code as it becomes unclear what happens in what order. For this reason, this feature should only be used to decouple the content of your abstract components for allowing surgical overrides in subclasses.
173
+ As you see, overusing this feature can lead to messy code as it becomes unclear what happens in what order. For this reason, this feature should only be used to decouple the content of your abstract components for allowing surgical overrides in [subclasses](/doc/guide/inheritance.md).
174
174
 
175
175
  It is a good convention to always have one content block named `:main`, as you might want to refer to it in subclasses.
176
176
 
@@ -245,7 +245,7 @@ setup do
245
245
  current_time = Time.zone.now
246
246
  if current_time.hour >= 11 && current_time.hour < 14
247
247
  flash.notice = "Sorry, it's not lunch time."
248
- redirect_to all_menus_path
248
+ redirect_to Compony.path(:index, :menus)
249
249
  end
250
250
  end
251
251
 
@@ -256,4 +256,8 @@ setup do
256
256
  end
257
257
  ```
258
258
 
259
- Similarly to `content`, the `before_render` method also accepts a name, defaulting to `:main`, as well as a `before:` keyword. This allows you to selectively extend and/or override `before_render` blocks in subclasses.
259
+ Note how Compony's [path helper](/doc/guide/intents.md#componypath) is used to generate the path. This is the recommended approach to redirecting to a component.
260
+
261
+ Similarly to `content`, the `before_render` method also accepts a name, defaulting to `:main`, as well as a `before:` keyword. This allows you to selectively extend and/or override `before_render` blocks in subclasses.
262
+
263
+ [Guide index](/README.md#guide--documentation)
data/doc/guide/example.md CHANGED
@@ -1,4 +1,4 @@
1
- [Back to the guide](/README.md#guide)
1
+ [Back to the guide](/README.md#guide--documentation)
2
2
 
3
3
  # Example
4
4
 
@@ -6,7 +6,7 @@ To get you a rough idea what working with Compony feels like, let's look at a sm
6
6
 
7
7
  The example is meant to be read top-down and information will mostly not be repeated. Comments will give you a rough idea of what's going on on each line. The features are more completely documented in subsequent chapters.
8
8
 
9
- Please note that from this example alone, you won't be able to comprehend the underlying concepts - refer to the rest of the [guide](/README.md#guide) for this.
9
+ Please note that from this example alone, you won't be able to comprehend the underlying concepts - refer to the rest of the [guide](/README.md#guide--documentation) for this.
10
10
 
11
11
  Let's implement a simple user management page with Compony. User's have a name, an integer age, a comment, as well as a role (which we will conveniently model using `AnchorModel`: https://github.com/kalsan/anchormodel). We want to be able to list, show, create, edit and destroy users. Users having the role Admin shall not be destroyed.
12
12
 
@@ -72,11 +72,12 @@ class Components::Users::Show < Compony::Component
72
72
  label(:short) { |_u| 'Show' } # The short format is suitable for e.g. a button in a list of users.
73
73
  label(:long) { |u| "Show user #{u.label}" } # The long format is suitable e.g. in a link in a text about this user.
74
74
 
75
- # Actions point to other components. They have a name that is used to identify them (e.g. in the `prevent` call above) and a block returning a button.
76
- # Compony buttons take the name to an action and either a family name or instance, e.g. a Rails model instance.
77
- # Whether or not an instance must be passed is defined by the component the button is pointing to (see the comment for `label` earlier in the example).
78
- action(:index) { Compony.button(:index, :users) } # This points to `Components::Users::Index` without passing a model (because it's an index).
79
- action(:edit) { Compony.button(:edit, @data) } # This points to `Components::Users::Edit` for the currently loaded model. This also checks feasibility.
75
+ # Intents point to other components. They have a name that is used to identify them and encapsulate both the target component and current context.
76
+ # Exposed intents can be rendered by the application layout.
77
+ exposed_intents do
78
+ add :index, :users # This points to `Components::Users::Index` without passing a model (because it's an index).
79
+ add :edit, @data # This points to `Components::Users::Edit` for the currently loaded model. This also checks feasibility.
80
+ end
80
81
 
81
82
  # When a standalone config is present, Compony creates one or multiple Rails routes. Components without standalone config must be nested within others.
82
83
  standalone path: 'users/show/:id' do # This specifies the path to this component.
@@ -108,7 +109,7 @@ Here is what our Show component looks like when we have a layout with the bare m
108
109
 
109
110
  ![Screenshot of our component with an absolutely minimal layout](/doc/imgs/intro-example-show.png)
110
111
 
111
- It is important to note that actions, buttons, navigation, notifications etc. are handled by the application layout. In this and the subsequent screenshots, we explicitely use minimalism, as it makes the generated HTML clearer.
112
+ It is important to note that button styles, navigation, notifications etc. are handled by the application layout. In this and the subsequent screenshots, we explicitely use minimalism, as it makes the generated HTML clearer.
112
113
 
113
114
  ## The Destroy component
114
115
 
@@ -196,7 +197,7 @@ class Components::Users::Index < Compony::Component
196
197
  content do
197
198
  h4 'Users:' # Provide a title
198
199
  # Provide a button that creates a new user. Note that we must write `:users` (plural) because the component's family is `Users`.
199
- concat compony_button(:new, :users) # The `Users::New` component does not take a model, thus we just pass the symbol `:users`, not a model.
200
+ concat render_intent(:new, :users) # The `Users::New` component does not take a model, thus we just pass the symbol `:users`, not a model.
200
201
 
201
202
  div class: 'users' do # Opening tag <div class="users">
202
203
  @data.each do |user| # Iterate the collection
@@ -206,13 +207,10 @@ class Components::Users::Index < Compony::Component
206
207
  concat "#{field.label}: #{field.value_for(user)} " # Display the field's label and apply it to value, as we did in the Show component.
207
208
  end
208
209
  end
209
- # For each user, add three buttons show, edit, destroy. The method `with_button_defaults` applies its arguments to every `compony_button` call.
210
- # The option `format: :short` causes the button to call the target component's `label(:short) {...}` label function.
211
- Compony.with_button_defaults(label_opts: { format: :short }) do
212
- concat compony_button(:show, user) # Now equivalent to: `compony_button(:show, user, label_opts: { format: :short })`
213
- concat compony_button(:edit, user)
214
- concat compony_button(:destroy, user)
215
- end
210
+ # For each user, add three buttons show, edit, destroy.
211
+ concat render_intent(:show, user, button: { label: { format: :short }})
212
+ concat render_intent(:edit, user, button: { label: { format: :short }})
213
+ concat render_intent(:destroy, user, button: { label: { format: :short }})
216
214
  end
217
215
  end
218
216
  end
@@ -225,4 +223,6 @@ The result looks like this:
225
223
 
226
224
  ![Index component](/doc/imgs/intro-example-index.png)
227
225
 
228
- Note how the admin's delete button is disabled due to the feasibility framework. Pointing the mouse at it causes a tooltip saying: "Cannot destroy admins.", as specified in the model's prevention.
226
+ Note how the admin's delete button is disabled due to the feasibility framework. Pointing the mouse at it causes a tooltip saying: "Cannot destroy admins.", as specified in the model's prevention.
227
+
228
+ [Guide index](/README.md#guide--documentation)
@@ -1,4 +1,4 @@
1
- [Back to the guide](/README.md#guide)
1
+ [Back to the guide](/README.md#guide--documentation)
2
2
 
3
3
  # Feasibility
4
4
 
@@ -35,4 +35,6 @@ end
35
35
 
36
36
  Compony has a feature that auto-detects feasibility of some actions. In particular, it checks for `dependent` relations in the `has_one`/`has_many` relations and disables delete buttons that point to objects that have dependent objects that cannot automatically be destroyed.
37
37
 
38
- To disable auto detection, call `skip_autodetect_feasibilities` in your model.
38
+ To disable auto detection, call `skip_autodetect_feasibilities` in your model.
39
+
40
+ [Guide index](/README.md#guide--documentation)
@@ -1,4 +1,4 @@
1
- [Back to the guide](/README.md#guide)
1
+ [Back to the guide](/README.md#guide--documentation)
2
2
 
3
3
  # Rails Generators provided by Compony
4
4
 
@@ -10,4 +10,6 @@ To make your life easier and coding faster, Compony comes with two generators:
10
10
 
11
11
  ### Support for custom base components
12
12
 
13
- Generators will automatically detect your `BaseComponents` (see [Inheritance: best practice](./doc/guide/inheritance.md#best-practice)).
13
+ Generators will automatically detect your `BaseComponents` (see [Inheritance: best practice](./doc/guide/inheritance.md#best-practice)).
14
+
15
+ [Guide index](/README.md#guide--documentation)
@@ -1,4 +1,4 @@
1
- [Back to the guide](/README.md#guide)
1
+ [Back to the guide](/README.md#guide--documentation)
2
2
 
3
3
  # Inheritance
4
4
 
@@ -59,4 +59,6 @@ Compony has the following convention:
59
59
  - implement a custom base component in the directory `app/compony/base_components/your_component.rb`
60
60
  - name the class `BaseComponents::YourComponent` where `BaseComponents` is typically a module simple meant for namespacing
61
61
 
62
- When respecting these conventions, compony's generators will automatically make generated classes inherit from the suitable base component if one is available. In the example above, `rails g component Users::Index` will automatically make the generated class inherit from `BaseComponent::Index`.
62
+ When respecting these conventions, Compony's [generators](/doc/guide/generators.md) will automatically make generated classes inherit from the suitable base component if one is available. In the example above, `rails g component Users::Index` will automatically make the generated class inherit from `BaseComponent::Index`.
63
+
64
+ [Guide index](/README.md#guide--documentation)
@@ -1,4 +1,4 @@
1
- [Back to the guide](/README.md#guide)
1
+ [Back to the guide](/README.md#guide--documentation)
2
2
 
3
3
  # Installation
4
4
 
@@ -42,4 +42,6 @@ To take advantage of the anchormodel integration, follow the installation instru
42
42
 
43
43
  ## Optional: installing `active_type`
44
44
 
45
- To take advantage of [virtual models](./virtual_models.md) through the `active_type` integration, follow the instructions under [https://github.com/makandra/active_type](https://github.com/makandra/active_type)
45
+ To take advantage of [virtual models](./virtual_models.md) through the `active_type` integration, follow the instructions under [https://github.com/makandra/active_type](https://github.com/makandra/active_type)
46
+
47
+ [Guide index](/README.md#guide--documentation)