agile_rails 0.0.0.1

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 (259) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +285 -0
  5. data/Rakefile +39 -0
  6. data/agile_rails.gemspec +36 -0
  7. data/app/assets/fonts/ibm-plex-sans-300.woff2 +0 -0
  8. data/app/assets/fonts/ibm-plex-sans-400.woff2 +0 -0
  9. data/app/assets/fonts/ibm-plex-sans-500.woff2 +0 -0
  10. data/app/assets/fonts/ibm-plex-sans-600.woff2 +0 -0
  11. data/app/assets/fonts/ibm-plex-sans-700.woff2 +0 -0
  12. data/app/assets/fonts/ibm-plex-sans-italic.woff2 +0 -0
  13. data/app/assets/images/32px.png +0 -0
  14. data/app/assets/images/throbber.gif +0 -0
  15. data/app/assets/javascripts/agile/agile.js +1489 -0
  16. data/app/assets/javascripts/agile/jquery-migrate.js +702 -0
  17. data/app/assets/javascripts/agile/jquery.bpopup.js +372 -0
  18. data/app/assets/javascripts/agile/jquery.datetimepicker.js +1353 -0
  19. data/app/assets/javascripts/agile/jstree.min.js +6 -0
  20. data/app/assets/javascripts/agile/select-multiple.js +459 -0
  21. data/app/assets/javascripts/agile/some_scripts.js +33 -0
  22. data/app/assets/javascripts/agile.js +22 -0
  23. data/app/assets/javascripts/agile_application.js +22 -0
  24. data/app/assets/javascripts/agile_editor.js +22 -0
  25. data/app/assets/stylesheets/agile/agile.css +1882 -0
  26. data/app/assets/stylesheets/agile/agile_apps.css +149 -0
  27. data/app/assets/stylesheets/agile/jquery.datetimepicker.css +304 -0
  28. data/app/assets/stylesheets/agile/jstree.css +1107 -0
  29. data/app/assets/stylesheets/agile/select-multiple.css +110 -0
  30. data/app/assets/stylesheets/agile/th-bg.png +0 -0
  31. data/app/assets/stylesheets/agile/theme.css +49 -0
  32. data/app/assets/stylesheets/agile.css +21 -0
  33. data/app/assets/stylesheets/agile_application.css +20 -0
  34. data/app/assets/stylesheets/agile_editor.css +19 -0
  35. data/app/controllers/agile_application_controller.rb +735 -0
  36. data/app/controllers/agile_common_controller.rb +345 -0
  37. data/app/controllers/agile_controller.rb +977 -0
  38. data/app/controllers/agile_main_controller.rb +36 -0
  39. data/app/controls/agile_control.rb +120 -0
  40. data/app/controls/agile_report.rb +364 -0
  41. data/app/controls/ar_category_control.rb +39 -0
  42. data/app/controls/ar_help_control.rb +139 -0
  43. data/app/controls/ar_image_control.rb +180 -0
  44. data/app/controls/ar_journal_control.rb +47 -0
  45. data/app/controls/ar_menu_item_control.rb +55 -0
  46. data/app/controls/ar_page_control.rb +64 -0
  47. data/app/controls/ar_poll_result_control.rb +84 -0
  48. data/app/controls/ar_setup_control.rb +62 -0
  49. data/app/controls/belongs_to_control.rb +61 -0
  50. data/app/controls/browse_models_control.rb +98 -0
  51. data/app/controls/settings_form_control.rb +137 -0
  52. data/app/forms/agile_help.yml +112 -0
  53. data/app/forms/agile_menu.yml +140 -0
  54. data/app/forms/agile_report_defaults.yml +39 -0
  55. data/app/forms/all_options.yml +810 -0
  56. data/app/forms/ar_ad.yml +121 -0
  57. data/app/forms/ar_big_table.yml +60 -0
  58. data/app/forms/ar_big_table_value.yml +52 -0
  59. data/app/forms/ar_browse_fields.yml +35 -0
  60. data/app/forms/ar_browse_models.yml +48 -0
  61. data/app/forms/ar_category.yml +73 -0
  62. data/app/forms/ar_category_as_tree.yml +31 -0
  63. data/app/forms/ar_design.yml +75 -0
  64. data/app/forms/ar_filter.yml +52 -0
  65. data/app/forms/ar_folder_permission.yml +56 -0
  66. data/app/forms/ar_folder_rule.yml +48 -0
  67. data/app/forms/ar_gallery.yml +55 -0
  68. data/app/forms/ar_image.yml +126 -0
  69. data/app/forms/ar_image_search.yml +83 -0
  70. data/app/forms/ar_journal.yml +76 -0
  71. data/app/forms/ar_json_ld.yml +56 -0
  72. data/app/forms/ar_key_value.yml +33 -0
  73. data/app/forms/ar_key_value_store.yml +33 -0
  74. data/app/forms/ar_link.yml +60 -0
  75. data/app/forms/ar_menu.yml +67 -0
  76. data/app/forms/ar_menu_item.yml +141 -0
  77. data/app/forms/ar_page.yml +187 -0
  78. data/app/forms/ar_part.yml +91 -0
  79. data/app/forms/ar_permission.yml +52 -0
  80. data/app/forms/ar_permission_rule.yml +40 -0
  81. data/app/forms/ar_piece.yml +106 -0
  82. data/app/forms/ar_policy.yml +64 -0
  83. data/app/forms/ar_policy_rule.yml +42 -0
  84. data/app/forms/ar_policy_rule_nocms.yml +40 -0
  85. data/app/forms/ar_poll.yml +118 -0
  86. data/app/forms/ar_poll_item.yml +78 -0
  87. data/app/forms/ar_poll_result.yml +88 -0
  88. data/app/forms/ar_poll_result_export.yml +35 -0
  89. data/app/forms/ar_removed_url.yml +41 -0
  90. data/app/forms/ar_role.yml +43 -0
  91. data/app/forms/ar_seo.yml +32 -0
  92. data/app/forms/ar_setup.yml +45 -0
  93. data/app/forms/ar_site.yml +149 -0
  94. data/app/forms/ar_steps_template.yml +51 -0
  95. data/app/forms/ar_user.yml +140 -0
  96. data/app/forms/ar_user_role.yml +57 -0
  97. data/app/forms/help/dc_category_as_tree.en +4 -0
  98. data/app/forms/help/dc_category_as_tree.sl +5 -0
  99. data/app/forms/json_ld_schema.yml +168 -0
  100. data/app/helpers/agile_application_helper.rb +1162 -0
  101. data/app/helpers/agile_category_helper.rb +128 -0
  102. data/app/helpers/agile_common_helper.rb +308 -0
  103. data/app/helpers/agile_edit_helper.rb +645 -0
  104. data/app/helpers/agile_helper.rb +509 -0
  105. data/app/helpers/agile_index_helper.rb +677 -0
  106. data/app/helpers/ar_image_helper.rb +128 -0
  107. data/app/models/agile_form_fields/action.rb +61 -0
  108. data/app/models/agile_form_fields/agile_form_field.rb +322 -0
  109. data/app/models/agile_form_fields/belongs_to.rb +112 -0
  110. data/app/models/agile_form_fields/check_box.rb +73 -0
  111. data/app/models/agile_form_fields/comment.rb +62 -0
  112. data/app/models/agile_form_fields/date_picker.rb +104 -0
  113. data/app/models/agile_form_fields/date_select.rb +68 -0
  114. data/app/models/agile_form_fields/datetime_picker.rb +88 -0
  115. data/app/models/agile_form_fields/datetime_select.rb +73 -0
  116. data/app/models/agile_form_fields/file_field.rb +52 -0
  117. data/app/models/agile_form_fields/file_select.rb +69 -0
  118. data/app/models/agile_form_fields/hidden_field.rb +51 -0
  119. data/app/models/agile_form_fields/html_field.rb +69 -0
  120. data/app/models/agile_form_fields/journal_diff.rb +62 -0
  121. data/app/models/agile_form_fields/link_to.rb +69 -0
  122. data/app/models/agile_form_fields/method.rb +66 -0
  123. data/app/models/agile_form_fields/multitext_autocomplete.rb +215 -0
  124. data/app/models/agile_form_fields/number_field.rb +92 -0
  125. data/app/models/agile_form_fields/password_field.rb +63 -0
  126. data/app/models/agile_form_fields/radio_button.rb +95 -0
  127. data/app/models/agile_form_fields/readonly.rb +77 -0
  128. data/app/models/agile_form_fields/select.rb +281 -0
  129. data/app/models/agile_form_fields/submit_tag.rb +58 -0
  130. data/app/models/agile_form_fields/text_area.rb +61 -0
  131. data/app/models/agile_form_fields/text_autocomplete.rb +171 -0
  132. data/app/models/agile_form_fields/text_field.rb +55 -0
  133. data/app/models/agile_form_fields/text_with_select.rb +94 -0
  134. data/app/models/agile_form_fields/tree_select.rb +170 -0
  135. data/app/models/ar_big_table.rb +82 -0
  136. data/app/models/ar_big_table_value.rb +53 -0
  137. data/app/models/ar_category.rb +109 -0
  138. data/app/models/ar_design.rb +116 -0
  139. data/app/models/ar_filter.rb +200 -0
  140. data/app/models/ar_folder_permission.rb +50 -0
  141. data/app/models/ar_folder_rule.rb +47 -0
  142. data/app/models/ar_gallery.rb +53 -0
  143. data/app/models/ar_image.rb +198 -0
  144. data/app/models/ar_internals.rb +60 -0
  145. data/app/models/ar_journal.rb +46 -0
  146. data/app/models/ar_json_ld.rb +131 -0
  147. data/app/models/ar_key_value_store.rb +128 -0
  148. data/app/models/ar_link.rb +48 -0
  149. data/app/models/ar_memory.rb +172 -0
  150. data/app/models/ar_menu.rb +144 -0
  151. data/app/models/ar_menu_item.rb +106 -0
  152. data/app/models/ar_page.rb +74 -0
  153. data/app/models/ar_part.rb +66 -0
  154. data/app/models/ar_permission.rb +180 -0
  155. data/app/models/ar_permission_rule.rb +65 -0
  156. data/app/models/ar_policy.rb +78 -0
  157. data/app/models/ar_policy_rule.rb +65 -0
  158. data/app/models/ar_poll.rb +74 -0
  159. data/app/models/ar_poll_item.rb +47 -0
  160. data/app/models/ar_poll_result.rb +38 -0
  161. data/app/models/ar_removed_url.rb +42 -0
  162. data/app/models/ar_role.rb +84 -0
  163. data/app/models/ar_setup.rb +115 -0
  164. data/app/models/ar_site.rb +68 -0
  165. data/app/models/ar_temp.rb +150 -0
  166. data/app/models/ar_user.rb +72 -0
  167. data/app/models/ar_user_group.rb +38 -0
  168. data/app/models/ar_user_role.rb +54 -0
  169. data/app/models/ar_visit.rb +41 -0
  170. data/app/models/concerns/ar_page_concern.rb +128 -0
  171. data/app/models/concerns/ar_part_concern.rb +48 -0
  172. data/app/models/concerns/ar_piece_concern.rb +48 -0
  173. data/app/models/concerns/ar_policy_rule_concern.rb +87 -0
  174. data/app/models/concerns/ar_seo_concern.rb +66 -0
  175. data/app/models/concerns/ar_site_concern.rb +103 -0
  176. data/app/models/concerns/ar_user_concern.rb +195 -0
  177. data/app/renderers/agile_common_renderer.rb +93 -0
  178. data/app/renderers/agile_renderer.rb +59 -0
  179. data/app/renderers/ar_ad_renderer.rb +219 -0
  180. data/app/renderers/ar_captcha_renderer.rb +113 -0
  181. data/app/renderers/ar_common_renderer.rb +90 -0
  182. data/app/renderers/ar_gallery_renderer.rb +107 -0
  183. data/app/renderers/ar_menu_renderer.rb +195 -0
  184. data/app/renderers/ar_page_renderer.rb +147 -0
  185. data/app/renderers/ar_part_renderer.rb +235 -0
  186. data/app/renderers/ar_piece_renderer.rb +119 -0
  187. data/app/renderers/ar_poll_renderer.rb +272 -0
  188. data/app/views/agile/_edit_stuff.html.erb +57 -0
  189. data/app/views/agile/_form.html.erb +24 -0
  190. data/app/views/agile/_result.html.erb +28 -0
  191. data/app/views/agile/edit.html.erb +13 -0
  192. data/app/views/agile/error.html.erb +2 -0
  193. data/app/views/agile/index.html.erb +14 -0
  194. data/app/views/agile/login.html.erb +19 -0
  195. data/app/views/agile/new.html.erb +12 -0
  196. data/app/views/agile_common/_help.html.erb +18 -0
  197. data/app/views/agile_common/_iframe_edit.html.erb +2 -0
  198. data/app/views/agile_common/paste_clipboard.html.erb +17 -0
  199. data/app/views/layouts/agile.html.erb +17 -0
  200. data/app/views/layouts/content.html.erb +20 -0
  201. data/app/views/models/dump_models.html.erb +47 -0
  202. data/config/initializers/kaminari_patch.rb +56 -0
  203. data/config/locales/agile_de.yml +138 -0
  204. data/config/locales/agile_en.yml +162 -0
  205. data/config/locales/agile_sl.yml +163 -0
  206. data/config/locales/datetimepicker.yml +19 -0
  207. data/config/locales/de.yml +231 -0
  208. data/config/locales/en.yml +13 -0
  209. data/config/locales/kaminari.yml +26 -0
  210. data/config/locales/models_en.yml +1032 -0
  211. data/config/locales/models_sl.yml +1065 -0
  212. data/config/locales/sl.yml +211 -0
  213. data/db/migrate/20240120160001_add_sessions_table.rb +12 -0
  214. data/db/migrate/20240120160002_ar_big_table.rb +17 -0
  215. data/db/migrate/20240120160003_ar_big_table_value.rb +18 -0
  216. data/db/migrate/20240120160004_ar_category.rb +22 -0
  217. data/db/migrate/20240120160005_ar_design.rb +20 -0
  218. data/db/migrate/20240120160006_ar_filter.rb +17 -0
  219. data/db/migrate/20240120160007_ar_gallery.rb +21 -0
  220. data/db/migrate/20240120160008_ar_journal.rb +19 -0
  221. data/db/migrate/20240120160009_ar_key_value_store.rb +11 -0
  222. data/db/migrate/20240120160010_ar_link.rb +19 -0
  223. data/db/migrate/20240120160011_ar_memory.rb +8 -0
  224. data/db/migrate/20240120160012_ar_menu.rb +21 -0
  225. data/db/migrate/20240120160013_ar_menu_item.rb +28 -0
  226. data/db/migrate/20240120160014_ar_page.rb +50 -0
  227. data/db/migrate/20240120160015_ar_part.rb +33 -0
  228. data/db/migrate/20240120160016_ar_permission.rb +16 -0
  229. data/db/migrate/20240120160017_ar_permission_rule.rb +17 -0
  230. data/db/migrate/20240120160018_ar_piece.rb +28 -0
  231. data/db/migrate/20240120160019_ar_policy.rb +21 -0
  232. data/db/migrate/20240120160020_ar_policy_rule.rb +18 -0
  233. data/db/migrate/20240120160021_ar_poll.rb +27 -0
  234. data/db/migrate/20240120160022_ar_poll_item.rb +23 -0
  235. data/db/migrate/20240120160023_ar_poll_result.rb +14 -0
  236. data/db/migrate/20240120160024_ar_removed_url.rb +16 -0
  237. data/db/migrate/20240120160025_ar_role.rb +17 -0
  238. data/db/migrate/20240120160026_ar_site.rb +37 -0
  239. data/db/migrate/20240120160027_ar_temp.rb +11 -0
  240. data/db/migrate/20240120160028_ar_user.rb +42 -0
  241. data/db/migrate/20240120160029_ar_user_group.rb +12 -0
  242. data/db/migrate/20240120160030_ar_user_role.rb +18 -0
  243. data/db/migrate/20240120160031_ar_visit.rb +15 -0
  244. data/db/migrate/20240703016001_ar_setup.rb +16 -0
  245. data/db/migrate/20240703016002_ar_folder_permission.rb +15 -0
  246. data/db/migrate/20240703016003_ar_folder_rule.rb +14 -0
  247. data/db/migrate/20250115000001_ar_image.rb +25 -0
  248. data/lib/agile/configuration.rb +43 -0
  249. data/lib/agile/engine.rb +29 -0
  250. data/lib/agile/version.rb +27 -0
  251. data/lib/agile.rb +282 -0
  252. data/lib/agile_rails.rb +1 -0
  253. data/lib/generators/agile/USAGE +11 -0
  254. data/lib/generators/agile/new_form_generator.rb +369 -0
  255. data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
  256. data/lib/tasks/agile_db_clone.rake +132 -0
  257. data/lib/tasks/agile_db_export_to_yaml.rake +37 -0
  258. data/lib/tasks/agile_db_migrate.rake +35 -0
  259. metadata +414 -0
@@ -0,0 +1,195 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ ########################################################################
25
+ # Default menu renderer from ar_menus table. Renderer produces output for
26
+ # rendering menu with (theoretically) infinite level of sub menus. In practice
27
+ # reasonable maximum level of 4 is advised.
28
+ #
29
+ # Example (as used in design):
30
+ # agile_render(:ar_menu, name: 'my_menu')
31
+ # # when :name option is omitted it will use site document's field menu_name.
32
+ # agile_render(:ar_menu)
33
+ ########################################################################
34
+ class ArMenuRenderer
35
+
36
+ include AgileApplicationHelper
37
+ include AgileCommonHelper
38
+
39
+ ########################################################################
40
+ # Object initialization. Will also prepare menu record.
41
+ ########################################################################
42
+ def initialize( env, opts ) #:nodoc:
43
+ @env = env
44
+ @menu = opts[:name] ? ArMenu.find_by(name: opts[:name].to_s) : ArMenu.find(@env.site.menu_id)
45
+ @opts = opts
46
+ self
47
+ end
48
+
49
+ ########################################################################
50
+ # Return selected topmenu level.
51
+ ########################################################################
52
+ def find_selected
53
+ if @env.page.menu_id
54
+ top_menu_id = @env.page.menu_id
55
+ top_menu_id = @env.page.menu_id.split(';')[1] if @env.page.menu_id.match(';')
56
+ ret = @menu.ar_menu_items.find(top_menu_id)
57
+ end
58
+ # return first if not found (something is wrong)
59
+ ret || @menu.ar_menu_items[0]
60
+ end
61
+
62
+ ########################################################################
63
+ # Creates edit link if in edit mode.
64
+ ########################################################################
65
+ def link_for_edit(opts) #:nodoc:
66
+ return '' unless @opts[:edit_mode] > 1
67
+
68
+ opts.merge!( { controller: :agile, action: :edit } )
69
+ title = "#{t('agile.edit')}: "
70
+ opts[:title] = "#{title} #{opts[:title]}"
71
+
72
+ "<li>#{agile_link_for_edit(opts)}</li>\n"
73
+ end
74
+
75
+ ########################################################################
76
+ # Returns html code required to create single link in a menu. Subroutine of do_menu_level.
77
+ ########################################################################
78
+ def link_4menu(item, prepend)
79
+ link = if item.link_to.present?
80
+ item.link_to
81
+ else
82
+ '/' + (prepend + [item.link.delete_prefix('/')]).join('/')
83
+ end
84
+ target = item.target.blank? ? nil : item.target
85
+ # - in first place won't write caption text
86
+ caption = item.caption[0] == '-' ? '' : @env.t(item.caption)
87
+ img_title = item.caption.to_s.sub('-', '')
88
+ # add picture if picture is not blank
89
+ html = ''
90
+ if item.picture.present?
91
+ if item.picture[0, 3] == 'mi-'
92
+ # position is delimited with comma
93
+ icon, position = item.picture.split(',')
94
+ caption = if position.to_s == 'right'
95
+ caption + @env.mi_icon(icon[3..])
96
+ else
97
+ @env.mi_icon(icon[3..]) + caption
98
+ end
99
+ else
100
+ return @env.link_to( @env.image_tag(item.picture), link, { title: img_title, target: target } ) rescue 'ERROR!'
101
+ end
102
+ end
103
+ html = html + @env.link_to(caption.html_safe, link, { target: target} ) if caption.present?
104
+ html
105
+ end
106
+
107
+ ########################################################################
108
+ # Creates HTML code required for submenu on single level. Subroutine of default.
109
+ ########################################################################
110
+ def submenu_do(items, env, prepend)
111
+ html = '<ul>'
112
+ items.sort_by(&:order).each do |item|
113
+ next if item.hidden
114
+
115
+ can_view, msg = agile_user_can_view(@env, item)
116
+ next unless can_view
117
+
118
+ if @opts[:edit_mode] > 1
119
+ options = { table: 'ar_menu;ar_menu_item', form_name: :ar_menu_item, id: item.id, ids: "#{@menu.id};#{env.id}" }
120
+ html += link_for_edit(options)
121
+ end
122
+
123
+ prepend_path = item.prepend_path ? prepend + [env.link] : []
124
+ html += %(<li>#{link_4menu(item, prepend_path)}\n)
125
+ if sub_menus = @menu_items[item.id]
126
+ html += submenu_do(sub_menus, item, prepend_path)
127
+ end
128
+ html += '</li>'
129
+ end
130
+ html += '</ul>'
131
+ end
132
+
133
+ ########################################################################
134
+ # Creates HTML code required for submenu on single level. Subroutine of default.
135
+ ########################################################################
136
+ def menu_do
137
+ html = '<ul>'
138
+ if @opts[:edit_mode] > 1
139
+ options = { table: :ar_menu, title: @menu.name, id: @menu.id }
140
+ html += link_for_edit(options)
141
+ end
142
+ # read menu into hash
143
+ @menu_items = {}
144
+ ArMenuItem.where(ar_menu_id: @menu.id, active: :true).each do |item|
145
+ @menu_items[item.parent_id] ||= []
146
+ @menu_items[item.parent_id] << item
147
+ end
148
+ return '' if @menu_items.size == 0
149
+
150
+ @menu_items[0].sort_by(&:order).each do |item|
151
+ next if item.hidden
152
+
153
+ # menu can be hidden from user
154
+ can_view, msg = agile_user_can_view(@env, item)
155
+ next unless can_view
156
+
157
+ selected = 'selected' if @opts[:path]&.first == item.link
158
+ html += %(<li class="#{selected}">#{link_4menu(item, [])}\n)
159
+
160
+ # SUBMENUS
161
+ if sub_menus = @menu_items[item.id]
162
+ html += submenu_do(sub_menus, item, [])
163
+ end
164
+ html += '</li>'
165
+ end
166
+ html += '</ul>'
167
+ end
168
+
169
+ ########################################################################
170
+ # Creates default menu.
171
+ ########################################################################
172
+ def default
173
+ return "(#{@opts[:name]}) menu not found!" if @menu.nil?
174
+
175
+ #@selected = find_selected
176
+ div_name = @menu.div_name.blank? ? 'ar-menu' : @menu.div_name
177
+ %(<nav class="#{div_name}">\n#{menu_do()}\n</nav>)
178
+ end
179
+
180
+ ########################################################################
181
+ # Renderer dispatcher. Method returns HTML part of code.
182
+ ########################################################################
183
+ def render_html
184
+ method = @opts[:method] || 'default'
185
+ respond_to?(method) ? send(method) : "Error ArMenu: Method #{method} doesn't exist!"
186
+ end
187
+
188
+ ########################################################################
189
+ # Return CSS part of code.
190
+ ########################################################################
191
+ def render_css
192
+ @menu.css if @menu
193
+ end
194
+
195
+ end
@@ -0,0 +1,147 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ ########################################################################
25
+ # Page renderer renders data from ar_page collection documents. This renderer will
26
+ # almost certainly be replaced by your own renderer so example here shows just basic code
27
+ # which just checks if user is allowed to view data and if so returns document body content
28
+ # otherwise returns error message defined in site policy.
29
+ #
30
+ # Example:
31
+ # <div id="page">
32
+ # <%= agile_render(:ar_page, div_class: 'my-pages') %>
33
+ # </div>
34
+ #
35
+ ########################################################################
36
+ class ArPageRenderer
37
+
38
+ include AgileApplicationHelper
39
+ include AgileCommonHelper
40
+
41
+ ########################################################################
42
+ # Object initialization.
43
+ ########################################################################
44
+ def initialize( env, opts={} ) #:nodoc:
45
+ @env = env
46
+ @opts = opts
47
+ @page = @env.page
48
+ @css = ''
49
+ end
50
+
51
+ #########################################################################
52
+ # Render IFrame part if defined on page
53
+ #
54
+ # Parameters forwarded to iframe are defined in if_params field as yaml as:
55
+ # param_name:
56
+ # object: internal object name (params, session, site, page)
57
+ # method: method name (variable) holding the value of parameter
58
+ #
59
+ # example: Forward id parameter to iframe
60
+ # id:
61
+ # object: params
62
+ # method: id
63
+ #
64
+ # example: Forward user id and edit_mode to iframe
65
+ # user_id:
66
+ # object: session
67
+ # method: user_id
68
+ # edit:
69
+ # object: session
70
+ # method: edit_mode
71
+ #
72
+ #########################################################################
73
+ def iframe
74
+ html = "\n<iframe"
75
+ html += " id=\"#{@page.if_id}\"" if @page.if_id.present?
76
+ html += " class=\"#{@page.if_class}\"" if @page.if_class.present?
77
+ html += " border=\"#{@page.if_border}\""
78
+ html += " height=\"#{@page.if_height}\"" if @page.if_height.present?
79
+ html += " width=\"#{@page.if_width}\"" if @page.if_width.present?
80
+ html += " scrolling=\"#{@page.if_scroll}\""
81
+ # Parameters
82
+ parameters = @page.if_url.match(/\?/) ? '' : '?'
83
+ params = YAML.load(@page.if_params) rescue {}
84
+ params = {} unless params.class == Hash
85
+ params.each do |key, value|
86
+ val = @env.ar_internal_var(value['object'], value['method'])
87
+ parameters += "&#{key}=#{val}" if val # only when not nil
88
+ end
89
+ url = @page.if_url + (parameters.size > 1 ? parameters : '')
90
+ html += "src=\"#{url}\" ></iframe>\n"
91
+ html
92
+ end
93
+
94
+ #########################################################################
95
+ #
96
+ #########################################################################
97
+ def poll
98
+ opts = @opts.merge(poll_id: @page.ar_poll_id, return_to: @env.request.url, method: nil)
99
+ poll = ArPollRenderer.new(@env, opts)
100
+ @css += "\n#{poll.render_css}"
101
+ "<div class='wrap row'>#{poll.render_html}</div>"
102
+ end
103
+
104
+ #########################################################################
105
+ #
106
+ #########################################################################
107
+ def gallery
108
+ opts = @opts.merge(doc_id: @page.id, doc_type: @page.class.to_s.underscore, method: nil)
109
+ gall = ArGalleryRenderer.new(@env, opts)
110
+ @css += "\n#{gall.render_css}"
111
+ "<div class='wrap row'>#{gall.render_html}</div>"
112
+ end
113
+
114
+ #########################################################################
115
+ # Default ArPage render method
116
+ #########################################################################
117
+ def default
118
+ can_view, msg = agile_user_can_view(@env, @page)
119
+ return msg unless can_view
120
+
121
+ @env.page_title = @page.title.blank? ? @page.subject : @page.title
122
+ html = "<div class=\"#{@page.div_class} #{@opts[:div_class]}\">"
123
+ html += agile_page_edit_menu() if @opts[:edit_mode] > 1
124
+ html += @page.body
125
+
126
+ html += poll() if @page.ar_poll_id.to_i > 0
127
+ html += gallery() if @page.gallery
128
+ html += iframe() if @page.if_url.present?
129
+ html += '</div>'
130
+ end
131
+
132
+ #########################################################################
133
+ # Renderer dispatcher. Method returns HTML part of code.
134
+ ########################################################################
135
+ def render_html
136
+ method = @opts[:method] || 'default'
137
+ respond_to?(method) ? send(method) : "Error ArPage: Method #{method} doesn't exist!"
138
+ end
139
+
140
+ ########################################################################
141
+ # Return CSS part of code.
142
+ ########################################################################
143
+ def render_css
144
+ @css
145
+ end
146
+
147
+ end
@@ -0,0 +1,235 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ ########################################################################
25
+ # Renders one or multiple parts grouped by div_id field.
26
+ # Parts are scoped from design, page and ar_pieces documents.
27
+ #
28
+ # Example (as used in design):
29
+ # <div id='div-main'>
30
+ # <div id='div-left'> <%= agile_render(:ar_part, position: 'left') %></div>
31
+ # <div id='page'> <%= agile_render(:ar_page) %></div>
32
+ # <div id='div-right'>
33
+ # <%= agile_render(:ar_part, method: 'in_page', name: 'welcome')
34
+ # <%= agile_render(:ar_part, position: 'right')</div>
35
+ # </div>
36
+ # </div>
37
+ #
38
+ # Main page division in example is divided into 3 divisions. div-left, page and div-right.
39
+ # div-left and div-right are populated with parts containing 'left' and 'right' div_id value.
40
+ # In addition part with name 'welcome' is located above 'right' parts.
41
+ ########################################################################
42
+ class ArPartRenderer
43
+
44
+ include AgileApplicationHelper
45
+ include AgileCommonHelper
46
+
47
+ ########################################################################
48
+ # Object initialization.
49
+ ########################################################################
50
+ def initialize( env, opts={} ) #:nodoc:
51
+ @env = env
52
+ @opts = opts
53
+ @part_css = ''
54
+ self
55
+ end
56
+
57
+ ########################################################################
58
+ # Method returns output from single part(icle). It checks if policy allows part to
59
+ # be viewed on page and ads links for editing when in edit mode.
60
+ ########################################################################
61
+ def render_particle(particle, opts)
62
+ # Check if policy allows to view page
63
+ can_view, msg = agile_user_can_view(@env, particle)
64
+ return msg unless can_view
65
+ html = ''
66
+ if @opts[:edit_mode] > 1
67
+ opts[:edit_params].merge!(title: "#{t('agile.edit')}: #{particle.name}", controller: :agile)
68
+ html += agile_link_for_edit( opts[:edit_params] )
69
+ end
70
+ #
71
+ =begin
72
+ if particle.piece_id
73
+ opts[:id] = particle.piece_id
74
+ piece = ArPieceRenderer.new(@env, opts)
75
+ html += piece.render_html
76
+ @part_css += piece.render_css
77
+ else
78
+ html += particle.body
79
+ @part_css += particle.css.to_s
80
+ end
81
+ =end
82
+ @part_css += particle.css.to_s
83
+ html += particle.body
84
+ end
85
+
86
+ ########################################################################
87
+ # Load all parts defined in design, page or piece collection into memory.
88
+ # Subroutine of default method.
89
+ ########################################################################
90
+ def load_parts #:nodoc:
91
+ @env.parts = []
92
+ # Start with parts in design. Collect to array and add values needed for editing
93
+ if @env.design
94
+ @env.design.ar_parts.where(active: true).each do |part|
95
+ type = decamelize_type(part._type) || 'ar_part'
96
+ @env.parts += [part, @env.design.id, type, "ar_design;#{type}"]
97
+ end
98
+ end
99
+ # add parts in page
100
+ @env.page.ar_parts.where(active: true).each do |part|
101
+ type = decamelize_type(part._type) || 'ar_part'
102
+ @env.parts += [part, @env.page.id, type, "#{@env.site.page_class.underscore};#{type}"]
103
+ end
104
+ # add parts in site
105
+ @env.site.ar_parts.where(active: true).each do |part|
106
+ type = decamelize_type(part._type) || 'ar_part'
107
+ @env.parts += [part, @env.site.id, type, "ar_site;#{type}"]
108
+ end
109
+ # add parts belonging to site, defined in ar_pieces
110
+ ArPiece.where(site_id: @env.site.id, active: true).each do |part|
111
+ @env.parts += [part, part.id, 'ar_piece', 'ar_piece']
112
+ end
113
+ end
114
+
115
+ ########################################################################
116
+ # Default method collects all parts with the div_id field value defined by position option.
117
+ # If more then one parts have same div_id they will be sorted by order field. Method
118
+ # also loads all parts from design, page and pieces collections and cache them for
119
+ # consecutive calls.
120
+ #
121
+ # Options:
122
+ # [position] String. Position (value of div_id) where parts will be rendered.
123
+ #
124
+ # Example (as used in design):
125
+ # <div id='div-right'>
126
+ # <%= agile_render(:ar_part, position: 'right')
127
+ # </div>
128
+ ########################################################################
129
+ def default
130
+ html = "<div class=\"#{@opts[:div_class]}\">"
131
+ # Load all parts only once per call
132
+ load_parts if @env.parts.nil?
133
+ ar_deprecate ' ArPart: Parameter location will be deprecated! Please use position keyword.' if @opts['location']
134
+
135
+ @opts[:position] ||= @opts['position'] # symbols are not strings. Ensure that it works.
136
+ # Select parts
137
+ parts = []
138
+ @env.parts.each { |v| parts << v if v[0].div_id == @opts[:position] }
139
+ # Edit link
140
+ @opts[:edit_params].merge!( { controller: :agile, action: 'edit' } )
141
+ if parts.size > 0
142
+ parts.sort! {|a,b| a[0].order <=> b[0].order }
143
+
144
+ parts.each do |part|
145
+ @opts[:edit_params].merge!( id: part[0], ids: "#{part[1]}", form_name: part[2], table: part[3] )
146
+ html += render_particle(part[0], @opts)
147
+ end
148
+ end
149
+ html += "</div>"
150
+ end
151
+
152
+ ########################################################################
153
+ # This method will search and render single part defined in pages file. Part may
154
+ # be defined in current page document or in any page document found in pages file. Parameters
155
+ # are send through options hash.
156
+ #
157
+ # Options:
158
+ # [name] String. ar_parts name.
159
+ # [page_id] String. Page document id where part document is saved. Defaults to current page.
160
+ # [page_link] String. Page may alternatively be found by link field.
161
+ ########################################################################
162
+ def in_page
163
+ # Part is in page with id
164
+ page = if @opts[:page_id]
165
+ pageclass = @env.site.page_klass
166
+ pageclass.find(@opts[:page_id])
167
+ # Part is in page with subject link
168
+ elsif @opts[:page_link]
169
+ pageclass = @env.site.page_klass
170
+ @page = pageclass.find_by(ar_site_id: @env.site.id, link: @opts[:page_link])
171
+ # Part is in current page
172
+ else
173
+ @env.page
174
+ end
175
+ return "Error ArPart: Page not found!" if page.nil?
176
+
177
+ if part = page.ar_parts.find_by(name: @opts[:name])
178
+ @opts[:edit_params].merge!(id: part, ids: page.id, form_name: 'ar_part', table: "#{@env.site.page_class.underscore};ar_part" )
179
+ render_particle(part, @opts)
180
+ else
181
+ "Part with name #{@opts[:name]} not found in page!"
182
+ end
183
+ end
184
+
185
+ ########################################################################
186
+ # Renderer for single datapage kind of sites.
187
+ ########################################################################
188
+ def single_sitedoc
189
+ # if div_id option specified search for part with this div_id.
190
+ # This can be used to render footer or header of site.
191
+ part = if @opts[:div_id]
192
+ @env.parts.find_by(div_id: @opts[:div_id])
193
+ else
194
+ @env.part
195
+ end
196
+ # part not found. Render error message.
197
+ return "Part #{@opts[:div_id]} not found!" if part.nil?
198
+ # prepare edit parameters
199
+ @opts[:edit_params].merge!(id: part, ids: @env.site.id, form_name: 'ar_part',
200
+ table: "ar_site;ar_part", record_div_id: 'document' )
201
+ render_particle(part, @opts)
202
+ end
203
+
204
+ ########################################################################
205
+ # Render menu for single datapage kind of sites.
206
+ ########################################################################
207
+ def single_sitedoc_menu
208
+ # prepare div markup
209
+ menu_div = @opts[:menu_div] ? "id=#{@opts[:menu_div]}" : ''
210
+ html = "<div #{menu_div}><ul>\n"
211
+ # collect all ar_part documents which make menu
212
+ @env.parts.where(div_id: 'document').order(:order).each do |part|
213
+ # mark selected item
214
+ selected = (part == @env.part) ? 'class="menu-selected"' : ''
215
+ html += "<li #{selected}>#{ @env.link_to(part.name, part.link ) }</li>\n"
216
+ end
217
+ html += "</ul></div>\n"
218
+ end
219
+
220
+ ########################################################################
221
+ # Renderer dispatcher. Method returns HTML part of code.
222
+ ########################################################################
223
+ def render_html
224
+ method = @opts[:method] || 'default'
225
+ respond_to?(method) ? send(method) : "Error ArPart: Method #{method} doesn't exist!"
226
+ end
227
+
228
+ ########################################################################
229
+ # Return CSS part of code.
230
+ ########################################################################
231
+ def render_css
232
+ @part_css
233
+ end
234
+
235
+ end
@@ -0,0 +1,119 @@
1
+ #--
2
+ # Copyright (c) 2024+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #+
23
+
24
+ ########################################################################
25
+ # Piece renderer renders data from ar_piece table.
26
+ #
27
+ # Example:
28
+ # <div id="page">
29
+ # <%= agile_render(:ar_piece, :name => 'some_piece') %>
30
+ # </div>
31
+ #
32
+ ########################################################################
33
+ class ArPieceRenderer
34
+
35
+ include AgileApplicationHelper
36
+ include AgileCommonHelper
37
+ ########################################################################
38
+ # Object initialization. It also loads requested ar_piece document.
39
+ ########################################################################
40
+ def initialize( env, opts = {} ) #:nodoc:
41
+ @env = env
42
+ @opts = opts
43
+ @piece = ArPiece.find(opts[:id]) if opts[:id]
44
+ if @piece.nil? # alternatively find by name
45
+ name = opts[:name] || opts[:id]
46
+ @piece = if @opts[:site]
47
+ ArPiece.find_by(name: name, site_id: agile_get_site.id)
48
+ else
49
+ ArPiece.find_by(name: name)
50
+ end
51
+ end
52
+ end
53
+
54
+ #########################################################################
55
+ # Return link code for editing this piece.
56
+ ########################################################################
57
+ def link_4edit()
58
+ html = ''
59
+ return html if @opts[:edit_mode] < 2
60
+ @opts[:edit_params].merge!( { table: 'ar_piece',
61
+ form_name: 'ar_piece',
62
+ controller: :agile,
63
+ action: 'edit',
64
+ id: @piece.id,
65
+ title: "#{t('agile.edit')}: #{@piece.name}" } )
66
+ html += agile_link_for_edit( @opts[:edit_params] )
67
+ end
68
+
69
+ ########################################################################
70
+ # Script renderer method expects rails erb code (view) in the script field.
71
+ # Used for designs with common code which can be shared and one part which is different.
72
+ # It's functionality can be replaced with ar_replace_in_design method with 'piece' option
73
+ # specified.
74
+ #
75
+ # Example: As used in design. Backslashing < and % is important \<\%
76
+ # <% part = "<div class='some-class'>\<\%= agile_render(:my_renderer, method: 'render_method') \%\></div>" %>
77
+ # <%= agile_render(:ar_piece, id: 'common', method: 'script', replace: '[main]', with: part) %>
78
+ #
79
+ # Want to replace more than one part. Use array.
80
+ # <%= agile_render(:ar_piece, id: 'common', method: 'script', replace: ['[part1]','[part2]'], with: [part1, part2]) %>
81
+ ########################################################################
82
+ def script
83
+ s = @piece.script
84
+ if @opts[:replace]
85
+ # replace more than one part of code
86
+ if @opts[:replace].class == Array
87
+ 0.upto(@opts[:replace].size - 1) {|i| s.sub!(@opts[:replace][i], @opts[:with][i])}
88
+ else
89
+ s.sub!(@opts[:replace], @opts[:with])
90
+ end
91
+ end
92
+ @env.render(inline: s, layout: @opts[:layout])
93
+ end
94
+
95
+ #########################################################################
96
+ # Default ArPiece render method.
97
+ ########################################################################
98
+ def default
99
+ html = link_4edit()
100
+ html += @piece.body
101
+ end
102
+
103
+ #########################################################################
104
+ # Renderer dispatcher. Method returns HTML part of code.
105
+ ########################################################################
106
+ def render_html
107
+ return " ArPiece #{@opts[:id]} #{@opts[:name]} not found!" unless @piece
108
+ method = @opts[:method] || 'default'
109
+ respond_to?(method) ? send(method) : "Error ArPiece: Method #{method} doesn't exist!"
110
+ end
111
+
112
+ ########################################################################
113
+ # Return CSS part of code.
114
+ ########################################################################
115
+ def render_css
116
+ @piece ? "#{@piece.css}" : ''
117
+ end
118
+
119
+ end