sibu 0.8.1 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -20
  3. data/README.md +38 -38
  4. data/Rakefile +36 -36
  5. data/app/assets/config/sibu_manifest.js +2 -2
  6. data/app/assets/fonts/sibu/Sibu.eot +0 -0
  7. data/app/assets/fonts/sibu/Sibu.svg +13 -13
  8. data/app/assets/fonts/sibu/Sibu.ttf +0 -0
  9. data/app/assets/fonts/sibu/Sibu.woff +0 -0
  10. data/app/assets/javascripts/cropper/cropper.js +3694 -3694
  11. data/app/assets/javascripts/quill/quill.js +11401 -11401
  12. data/app/assets/javascripts/sibu/common.js +6 -6
  13. data/app/assets/javascripts/sibu/sibu.js.erb +156 -155
  14. data/app/assets/javascripts/tabs/van11y-accessible-tab-panel-aria.js +465 -465
  15. data/app/assets/stylesheets/cropper/cropper.css +304 -304
  16. data/app/assets/stylesheets/quill/quill.snow.css +945 -945
  17. data/app/assets/stylesheets/sibu/defaults.scss +317 -336
  18. data/app/assets/stylesheets/sibu/icons.scss +40 -40
  19. data/app/assets/stylesheets/sibu/sibu.css +131 -131
  20. data/app/controllers/sibu/application_controller.rb +14 -14
  21. data/app/controllers/sibu/documents_controller.rb +35 -35
  22. data/app/controllers/sibu/images_controller.rb +78 -78
  23. data/app/controllers/sibu/pages_controller.rb +197 -197
  24. data/app/controllers/sibu/sites_controller.rb +81 -81
  25. data/app/helpers/sibu/application_helper.rb +11 -11
  26. data/app/helpers/sibu/documents_helper.rb +4 -4
  27. data/app/helpers/sibu/images_helper.rb +4 -4
  28. data/app/helpers/sibu/pages_helper.rb +217 -194
  29. data/app/helpers/sibu/sites_helper.rb +23 -23
  30. data/app/jobs/sibu/application_job.rb +4 -4
  31. data/app/mailers/sibu/application_mailer.rb +6 -6
  32. data/app/models/concerns/sibu/document_uploader.rb +8 -8
  33. data/app/models/concerns/sibu/image_uploader.rb +31 -31
  34. data/app/models/concerns/sibu/sections_concern.rb +134 -134
  35. data/app/models/concerns/sibu/style_uploader.rb +1 -1
  36. data/app/models/concerns/sibu/user_concern.rb +9 -8
  37. data/app/models/sibu/application_record.rb +5 -5
  38. data/app/models/sibu/document.rb +16 -16
  39. data/app/models/sibu/dynamic_style.rb +76 -76
  40. data/app/models/sibu/image.rb +10 -19
  41. data/app/models/sibu/page.rb +66 -66
  42. data/app/models/sibu/site.rb +97 -97
  43. data/app/models/sibu/site_template.rb +22 -22
  44. data/app/views/layouts/sibu/application.html.erb +23 -23
  45. data/app/views/layouts/sibu/edit_content.html.erb +262 -262
  46. data/app/views/layouts/sibu/site.html.erb +45 -45
  47. data/app/views/sibu/documents/_form.html.erb +14 -14
  48. data/app/views/sibu/documents/index.html.erb +37 -37
  49. data/app/views/sibu/documents/new.html.erb +12 -12
  50. data/app/views/sibu/images/_edit_form.html.erb +23 -23
  51. data/app/views/sibu/images/_form.html.erb +34 -34
  52. data/app/views/sibu/images/edit.js.erb +2 -2
  53. data/app/views/sibu/images/index.html.erb +31 -13
  54. data/app/views/sibu/images/new.html.erb +12 -12
  55. data/app/views/sibu/images/show.html.erb +2 -2
  56. data/app/views/sibu/pages/_code_edit_panel.html.erb +17 -17
  57. data/app/views/sibu/pages/_element_actions.html.erb +4 -4
  58. data/app/views/sibu/pages/_error_panel.html.erb +4 -4
  59. data/app/views/sibu/pages/_form.html.erb +62 -62
  60. data/app/views/sibu/pages/_group_edit_panel.html.erb +3 -3
  61. data/app/views/sibu/pages/_link_edit_panel.html.erb +50 -50
  62. data/app/views/sibu/pages/_map_edit_panel.html.erb +27 -27
  63. data/app/views/sibu/pages/_media_edit_panel.html.erb +63 -46
  64. data/app/views/sibu/pages/_new_section_panel.html.erb +43 -43
  65. data/app/views/sibu/pages/_paragraph_edit_panel.html.erb +18 -18
  66. data/app/views/sibu/pages/_text_edit_panel.html.erb +19 -19
  67. data/app/views/sibu/pages/child_element.js.erb +6 -6
  68. data/app/views/sibu/pages/clone_element.js.erb +6 -6
  69. data/app/views/sibu/pages/create_section.js.erb +6 -6
  70. data/app/views/sibu/pages/delete_element.js.erb +6 -6
  71. data/app/views/sibu/pages/delete_section.js.erb +6 -6
  72. data/app/views/sibu/pages/destroy.html.erb +2 -2
  73. data/app/views/sibu/pages/edit.html.erb +8 -8
  74. data/app/views/sibu/pages/edit_content.html.erb +3 -3
  75. data/app/views/sibu/pages/edit_element.js.erb +105 -100
  76. data/app/views/sibu/pages/edit_section.js.erb +7 -7
  77. data/app/views/sibu/pages/index.html.erb +40 -40
  78. data/app/views/sibu/pages/new.html.erb +8 -8
  79. data/app/views/sibu/pages/new_section.js.erb +19 -19
  80. data/app/views/sibu/pages/show.html.erb +3 -3
  81. data/app/views/sibu/pages/update.html.erb +2 -2
  82. data/app/views/sibu/pages/update_element.js.erb +5 -5
  83. data/app/views/sibu/pages/update_section.js.erb +5 -5
  84. data/app/views/sibu/sites/_form.html.erb +125 -125
  85. data/app/views/sibu/sites/destroy.html.erb +2 -2
  86. data/app/views/sibu/sites/edit.html.erb +9 -9
  87. data/app/views/sibu/sites/edit_styles.html.erb +8 -8
  88. data/app/views/sibu/sites/index.html.erb +41 -41
  89. data/app/views/sibu/sites/new.html.erb +18 -18
  90. data/app/views/sibu/sites/update.html.erb +2 -2
  91. data/config/initializers/constants.rb +2 -2
  92. data/config/initializers/shrine.rb +18 -18
  93. data/config/routes.rb +30 -30
  94. data/config/tinymce.yml +5 -5
  95. data/db/migrate/20180124095041_create_sibu_sites.rb +12 -12
  96. data/db/migrate/20180124095213_create_sibu_pages.rb +15 -15
  97. data/db/migrate/20180124145030_create_sibu_site_templates.rb +10 -10
  98. data/db/migrate/20180125231638_add_user_id_to_sites.rb +5 -5
  99. data/db/migrate/20180126114522_rename_url_to_path_in_pages.rb +5 -5
  100. data/db/migrate/20180126114628_add_domain_to_sites.rb +5 -5
  101. data/db/migrate/20180127211533_create_sibu_images.rb +11 -11
  102. data/db/migrate/20180208082317_rename_images_user_id_to_site_id.rb +5 -5
  103. data/db/migrate/20180208125024_rename_image_data_column.rb +5 -5
  104. data/db/migrate/20180210181644_add_defaults_to_site_templates.rb +6 -6
  105. data/db/migrate/20180214134653_add_fields_to_sites.rb +5 -5
  106. data/db/migrate/20180227151519_add_default_templates_to_site_templates.rb +5 -5
  107. data/db/migrate/20180301121902_add_style_data_to_sites.rb +5 -5
  108. data/db/migrate/20180301152101_add_default_styles_to_templates.rb +5 -5
  109. data/db/migrate/20180321144021_move_images_to_user_level.rb +7 -7
  110. data/db/migrate/20180321170310_add_version_to_sibu_sites.rb +7 -7
  111. data/db/migrate/20180405095448_create_sibu_documents.rb +10 -10
  112. data/db/migrate/20190110204854_add_custom_data_to_sibu_pages.rb +5 -5
  113. data/lib/sibu.rb +4 -4
  114. data/lib/sibu/engine.rb +19 -19
  115. data/lib/sibu/utils.rb +14 -14
  116. data/lib/sibu/version.rb +3 -3
  117. data/lib/tasks/sibu_tasks.rake +4 -4
  118. metadata +7 -7
@@ -1,11 +1,11 @@
1
- module Sibu
2
- module ApplicationHelper
3
- def conf
4
- Rails.application.config.sibu
5
- end
6
-
7
- def sibu_user
8
- send(Rails.application.config.sibu[:current_user])
9
- end
10
- end
11
- end
1
+ module Sibu
2
+ module ApplicationHelper
3
+ def conf
4
+ Rails.application.config.sibu
5
+ end
6
+
7
+ def sibu_user
8
+ send(Rails.application.config.sibu[:current_user])
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,4 @@
1
- module Sibu
2
- module DocumentsHelper
3
- end
4
- end
1
+ module Sibu
2
+ module DocumentsHelper
3
+ end
4
+ end
@@ -1,4 +1,4 @@
1
- module Sibu
2
- module ImagesHelper
3
- end
4
- end
1
+ module Sibu
2
+ module ImagesHelper
3
+ end
4
+ end
@@ -1,194 +1,217 @@
1
- module Sibu
2
- module PagesHelper
3
- include Sibu::Engine.routes.url_helpers
4
-
5
- def link_path(page_id)
6
- p = @site.page_by_id(page_id)
7
- p ? (request.host == conf[:host] ? site_page_path(@site.id, p.id) : (conf[:deployment_path] ? "/#{conf[:deployment_path]}/#{p.path}" : "/#{p.path}")) : "#"
8
- end
9
-
10
- def sections_templates
11
- @site.site_template.available_sections
12
- end
13
-
14
- def site_images
15
- ([Sibu::Image.empty] + Sibu::Image.for_user(sibu_user)).uniq
16
- end
17
-
18
- def available_links
19
- options_from_collection_for_select(@site.pages.order(:name), :id, :name, @element["value"])
20
- end
21
-
22
- def available_docs
23
- options_from_collection_for_select(Sibu::Document.for_user(sibu_user), :file_url, :file_name, @element["value"])
24
- end
25
-
26
- def link_type(val)
27
- if val.blank? || /^\d+$/.match(val.to_s)
28
- 'internal'
29
- elsif Sibu::Document.for_user(sibu_user).map {|d| d.file_url}.include?(val)
30
- 'document'
31
- elsif val.to_s.start_with?('http', '#', '/')
32
- 'external'
33
- else
34
- 'email'
35
- end
36
- end
37
-
38
- [:h1, :h2, :h3, :h4, :h5, :h6, :span].each do |t|
39
- define_method(t) do |elt, html_opts = {}|
40
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_TEXT}
41
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
42
- html_opts.merge!({data: {id: elt_id(elt), type: "text"}}) if action_name != 'show'
43
- content_tag(t, raw(content["text"]).html_safe, html_opts)
44
- end
45
- end
46
-
47
- def p(elt, opts = {})
48
- repeat = opts.delete(:repeat)
49
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_PARAGRAPH}
50
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
51
- opts.merge!({data: {id: elt_id(elt), repeat: repeat, type: "paragraph"}}) if action_name != 'show'
52
- content_tag(:div, content_tag(:p, raw(content["text"]).html_safe), opts)
53
- end
54
-
55
- def sb
56
- self
57
- end
58
-
59
- def select_element(id)
60
- @sb_entity.element(*@sb_section, id)
61
- end
62
-
63
- def elements(id = nil)
64
- items = id ? select_element(id)["elements"] : @sb_entity.find_or_init(*@sb_section)["elements"]
65
- items.blank? ? [{"id" => "el#{Time.current.to_i}"}] : items
66
- end
67
-
68
- def img(elt, opts = {})
69
- wrapper = opts.delete(:wrapper)
70
- repeat = opts.delete(:repeat)
71
- size = opts.delete(:size)
72
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "src" => DEFAULT_IMG}
73
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
74
- if action_name == 'show'
75
- content["src"] = ("/#{conf[:deployment_path]}" + content["src"]) if @online && conf[:deployment_path]
76
- else
77
- opts.merge!({data: {id: elt_id(elt), type: "media", repeat: repeat, size: size}})
78
- end
79
- wrapper ? content_tag(wrapper, content_tag(:img, nil, content.except("id")), opts)
80
- : content_tag(:img, nil, content.except("id").merge(opts.stringify_keys) {|k, old, new| k == 'class' ? [old, new].join(' ') : new})
81
- end
82
-
83
- def grp(elt, opts = {}, &block)
84
- wrapper = opts.delete(:wrapper) || :div
85
- repeat = opts.delete(:repeat)
86
- children = opts.delete(:children)
87
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt}
88
- opts = defaults.merge(opts)
89
- opts.merge!({data: {id: elt_id(elt), type: "group", repeat: repeat, children: children}}) if action_name != 'show'
90
- content_tag(wrapper, capture(*elts(elt), &block), opts)
91
- end
92
-
93
- def form_label(elt, html_opts = {}, &block)
94
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_TEXT}
95
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
96
- html_opts.merge!({data: {id: elt_id(elt), type: "text"}}) if action_name != 'show'
97
- content_tag(:label, raw(content["text"]).html_safe, html_opts)
98
- end
99
-
100
- def widget(elt, widget_type, opts = {}, &block)
101
- content = elt.is_a?(Hash) ? elt : (select_element(elt) || {})
102
- opts.merge!({data: {id: elt_id(elt), type: "widget_#{widget_type.to_s.split('::').last.underscore}"}}) if action_name != 'show'
103
- content_tag(:div, capture(widget_type.new(content), &block), opts)
104
- end
105
-
106
- def embed(elt, opts = {})
107
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "code" => '<p>Contenu HTML personnalisé (iframe, etc...)</p>'}
108
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
109
- opts.merge!({data: {id: elt_id(elt), type: "embed"}}) if action_name != 'show'
110
- content_tag(:div, content_tag(:p, raw(content["code"]).html_safe), opts)
111
- end
112
-
113
- # Note : see ActionView::OutputBuffer
114
- def sb_page
115
- @sb_entity = @page
116
- self
117
- end
118
-
119
- alias page sb_page
120
-
121
- def sb_site
122
- @sb_entity = @site
123
- self
124
- end
125
-
126
- alias site sb_site
127
-
128
- def section(id, tag, html_opts = {}, &block)
129
- @sb_section = [id]
130
- opts = action_name != 'show' ? html_opts.merge({"data-sb-id" => id, "data-sb-repeat" => @sb_entity != @site, "data-sb-entity" => @sb_entity == @site ? 'site' : 'page'}) : html_opts
131
- content_tag(tag, capture(self, &block), opts)
132
- end
133
-
134
- def sections(id, tag, html_opts = {}, &block)
135
- (@sb_entity.find_or_init(id)["elements"].map.with_index do |elt, i|
136
- @sb_section = [id, elt["id"]]
137
- opts = action_name != 'show' ? html_opts.merge({"data-sb-id" => @sb_section.join('|'), "data-sb-repeat" => true, "data-sb-entity" => @sb_entity == @site ? 'site' : 'page'}) : html_opts
138
- content_tag(tag, capture(self, i, &block), opts)
139
- end).join('').html_safe
140
- end
141
-
142
- def elts(id)
143
- items = []
144
- element_id = elt_id(id)
145
- elemnts = @sb_entity.elements(*(@sb_section + element_id.split("|")).uniq)
146
- if elemnts
147
- elemnts.each do |e|
148
- e["data-id"] = [element_id, e["id"]].join("|")
149
- items << e
150
- end
151
- end
152
- items.blank? ? [{"id" => element_id.split("|").last, "data-id" => [element_id, "#{element_id}0"].join("|")}] : items
153
- end
154
-
155
- def link(elt, html_opts = {}, &block)
156
- repeat = html_opts.delete(:repeat)
157
- children = html_opts.delete(:children)
158
- defaults = {"id" => elt_id(elt), "value" => "", "text" => DEFAULT_TEXT}
159
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
160
- val = content.delete("value") || ""
161
- text = content.delete("text")
162
- html_opts.merge!({data: {id: elt_id(elt), type: "link", repeat: repeat, children: children}}) if action_name != 'show'
163
- if val.to_s.start_with?('http')
164
- content["href"] = val
165
- elsif val.to_s.start_with?('#')
166
- content["href"] = val
167
- content.delete("target")
168
- elsif val.to_s.start_with?('/')
169
- content["href"] = val
170
- elsif val.to_s.include?('@')
171
- content["href"] = 'mailto:' + val
172
- else
173
- content["href"] = @links.keys.include?(val.to_s) ? (action_name == 'show' ? link_path(val) : site_page_edit_content_path(@site.id, val)) : '#'
174
- end
175
- # Note : sends elts in given order
176
- if block_given?
177
- content_tag(:a, capture(*([raw(text)] + elts(elt)), &block), content.merge(html_opts).except("elements"))
178
- else
179
- content_tag(:a, raw(text), content.merge(html_opts).except("elements"))
180
- end
181
- end
182
-
183
- def interactive_map(elt, html_opts = {})
184
- defaults = {"data-lat" => "45.68854", "data-lng" => "5.91587", "data-title" => DEFAULT_TEXT}
185
- content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {"id" => elt}))
186
- html_opts.merge!({data: {id: elt_id(elt), type: "map"}}) if action_name != 'show'
187
- content_tag(:div, nil, content.merge(html_opts))
188
- end
189
-
190
- def elt_id(elt)
191
- elt.is_a?(Hash) ? (elt["data-id"] || elt["id"]) : elt
192
- end
193
- end
194
- end
1
+ module Sibu
2
+ module PagesHelper
3
+ include Sibu::Engine.routes.url_helpers
4
+
5
+ def link_path(page_id)
6
+ p = @site.page_by_id(page_id)
7
+ p ? (request.host == conf[:host] ? site_page_path(@site.id, p.id) : (conf[:deployment_path] ? "/#{conf[:deployment_path]}/#{p.path}" : "/#{p.path}")) : "#"
8
+ end
9
+
10
+ def sections_templates
11
+ @site.site_template.available_sections
12
+ end
13
+
14
+ def site_images
15
+ Sibu::Image.for_user(sibu_user).uniq
16
+ end
17
+
18
+ def available_links
19
+ options_from_collection_for_select(@site.pages.order(:name), :id, :name, @element["value"])
20
+ end
21
+
22
+ def available_docs
23
+ options_from_collection_for_select(Sibu::Document.for_user(sibu_user), :file_url, :file_name, @element["value"])
24
+ end
25
+
26
+ def link_type(val)
27
+ if val.blank? || /^\d+$/.match(val.to_s)
28
+ 'internal'
29
+ elsif Sibu::Document.for_user(sibu_user).map {|d| d.file_url}.include?(val)
30
+ 'document'
31
+ elsif val.to_s.start_with?('http', '#', '/')
32
+ 'external'
33
+ else
34
+ 'email'
35
+ end
36
+ end
37
+
38
+ [:h1, :h2, :h3, :h4, :h5, :h6, :span].each do |t|
39
+ define_method(t) do |elt, html_opts = {}|
40
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_TEXT}
41
+ content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
42
+ html_opts.merge!({data: {id: elt_id(elt), type: "text"}}) if action_name != 'show'
43
+ content_tag(t, raw(content["text"]).html_safe, html_opts)
44
+ end
45
+ end
46
+
47
+ def p(elt, opts = {})
48
+ repeat = opts.delete(:repeat)
49
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_PARAGRAPH}
50
+ content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
51
+ opts.merge!({data: {id: elt_id(elt), repeat: repeat, type: "paragraph"}}) if action_name != 'show'
52
+ content_tag(:div, content_tag(:p, raw(content["text"]).html_safe), opts)
53
+ end
54
+
55
+ def sb
56
+ self
57
+ end
58
+
59
+ def select_element(id)
60
+ @sb_entity.element(*@sb_section, id)
61
+ end
62
+
63
+ def elements(id = nil)
64
+ items = id ? select_element(id)["elements"] : @sb_entity.find_or_init(*@sb_section)["elements"]
65
+ items.blank? ? [{"id" => "el#{Time.current.to_i}"}] : items
66
+ end
67
+
68
+ def img(elt, opts = {})
69
+ wrapper = opts.delete(:wrapper)
70
+ repeat = opts.delete(:repeat)
71
+ size = opts.delete(:size)
72
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "src" => DEFAULT_IMG}
73
+ content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
74
+ if action_name == 'show'
75
+ content["src"] = ("/#{conf[:deployment_path]}" + content["src"]) if @online && conf[:deployment_path]
76
+ else
77
+ opts.merge!({data: {id: elt_id(elt), type: "media", repeat: repeat, size: size}})
78
+ end
79
+ wrapper ? content_tag(wrapper, content_tag(:img, nil, content.except("id")), opts)
80
+ : content_tag(:img, nil, content.except("id").merge(opts.stringify_keys) {|k, old, new| k == 'class' ? [old, new].join(' ') : new})
81
+ end
82
+
83
+ def grp(elt, opts = {}, &block)
84
+ wrapper = opts.delete(:wrapper) || :div
85
+ repeat = opts.delete(:repeat)
86
+ children = opts.delete(:children)
87
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt}
88
+ opts = defaults.merge(opts)
89
+ opts.merge!({data: {id: elt_id(elt), type: "group", repeat: repeat, children: children}}) if action_name != 'show'
90
+ content_tag(wrapper, capture(*elts(elt), &block), opts)
91
+ end
92
+
93
+ def empty_tag(elt, tag, type, opts = {})
94
+ repeat = opts.delete(:repeat)
95
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt}.merge!(default_content(type))
96
+ opts = defaults.merge(opts)
97
+ opts.merge!({data: {id: elt_id(elt), type: type, repeat: repeat}}) if action_name != 'show'
98
+ content_tag(tag, nil, opts)
99
+ end
100
+
101
+ def form_label(elt, html_opts = {}, &block)
102
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => DEFAULT_TEXT}
103
+ content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
104
+ html_opts.merge!({data: {id: elt_id(elt), type: "text"}}) if action_name != 'show'
105
+ content_tag(:label, raw(content["text"]).html_safe, html_opts)
106
+ end
107
+
108
+ def widget(elt, widget_type, opts = {}, &block)
109
+ content = elt.is_a?(Hash) ? elt : (select_element(elt) || {})
110
+ opts.merge!({data: {id: elt_id(elt), type: "widget_#{widget_type.to_s.split('::').last.underscore}"}}) if action_name != 'show'
111
+ content_tag(:div, capture(widget_type.new(content), &block), opts)
112
+ end
113
+
114
+ def embed(elt, opts = {})
115
+ defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "code" => '<p>Contenu HTML personnalisé (iframe, etc...)</p>'}
116
+ content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
117
+ opts.merge!({data: {id: elt_id(elt), type: "embed"}}) if action_name != 'show'
118
+ content_tag(:div, content_tag(:p, raw(content["code"]).html_safe), opts)
119
+ end
120
+
121
+ # Note : see ActionView::OutputBuffer
122
+ def sb_page
123
+ @sb_entity = @page
124
+ self
125
+ end
126
+
127
+ alias page sb_page
128
+
129
+ def sb_site
130
+ @sb_entity = @site
131
+ self
132
+ end
133
+
134
+ alias site sb_site
135
+
136
+ def section(id, tag, html_opts = {}, &block)
137
+ @sb_section = [id]
138
+ opts = action_name != 'show' ? html_opts.merge({"data-sb-id" => id, "data-sb-repeat" => @sb_entity != @site, "data-sb-entity" => @sb_entity == @site ? 'site' : 'page'}) : html_opts
139
+ content_tag(tag, capture(self, &block), opts)
140
+ end
141
+
142
+ def sections(id, tag, html_opts = {}, &block)
143
+ (@sb_entity.find_or_init(id)["elements"].map.with_index do |elt, i|
144
+ @sb_section = [id, elt["id"]]
145
+ opts = action_name != 'show' ? html_opts.merge({"data-sb-id" => @sb_section.join('|'), "data-sb-repeat" => true, "data-sb-entity" => @sb_entity == @site ? 'site' : 'page'}) : html_opts
146
+ content_tag(tag, capture(self, i, &block), opts)
147
+ end).join('').html_safe
148
+ end
149
+
150
+ def elts(id)
151
+ items = []
152
+ element_id = elt_id(id)
153
+ elemnts = @sb_entity.elements(*(@sb_section + element_id.split("|")).uniq)
154
+ if elemnts
155
+ elemnts.each do |e|
156
+ e["data-id"] = [element_id, e["id"]].join("|")
157
+ items << e
158
+ end
159
+ end
160
+ items.blank? ? [{"id" => element_id.split("|").last, "data-id" => [element_id, "#{element_id}0"].join("|")}] : items
161
+ end
162
+
163
+ def link(elt, html_opts = {}, &block)
164
+ repeat = html_opts.delete(:repeat)
165
+ children = html_opts.delete(:children)
166
+ defaults = {"id" => elt_id(elt), "value" => "", "text" => DEFAULT_TEXT}
167
+ content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
168
+ val = content.delete("value") || ""
169
+ text = content.delete("text")
170
+ html_opts.merge!({data: {id: elt_id(elt), type: "link", repeat: repeat, children: children}}) if action_name != 'show'
171
+ if val.to_s.start_with?('http')
172
+ content["href"] = val
173
+ elsif val.to_s.start_with?('#')
174
+ content["href"] = val
175
+ content.delete("target")
176
+ elsif val.to_s.start_with?('/')
177
+ content["href"] = val
178
+ elsif val.to_s.include?('@')
179
+ content["href"] = 'mailto:' + val
180
+ else
181
+ content["href"] = @links.keys.include?(val.to_s) ? (action_name == 'show' ? link_path(val) : site_page_edit_content_path(@site.id, val)) : '#'
182
+ end
183
+ # Note : sends elts in given order
184
+ if block_given?
185
+ content_tag(:a, capture(*([raw(text)] + elts(elt)), &block), content.merge(html_opts).except("elements"))
186
+ else
187
+ content_tag(:a, raw(text), content.merge(html_opts).except("elements"))
188
+ end
189
+ end
190
+
191
+ def interactive_map(elt, html_opts = {})
192
+ defaults = {"data-lat" => "45.68854", "data-lng" => "5.91587", "data-title" => DEFAULT_TEXT}
193
+ content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {"id" => elt}))
194
+ html_opts.merge!({data: {id: elt_id(elt), type: "map"}}) if action_name != 'show'
195
+ content_tag(:div, nil, content.merge(html_opts))
196
+ end
197
+
198
+ def elt_id(elt)
199
+ elt.is_a?(Hash) ? (elt["data-id"] || elt["id"]) : elt
200
+ end
201
+
202
+ def default_content(type)
203
+ case type
204
+ when "text"
205
+ {"text" => DEFAULT_TEXT}
206
+ when "link"
207
+ {"value" => "", "text" => DEFAULT_TEXT}
208
+ when "paragraph"
209
+ {"text" => DEFAULT_PARAGRAPH}
210
+ when "media"
211
+ {"src" => DEFAULT_IMG}
212
+ when "embed"
213
+ {"code" => '<p>Contenu HTML personnalisé (iframe, etc...)</p>'}
214
+ end
215
+ end
216
+ end
217
+ end