comfortable_mexican_sofa 2.0.12 → 2.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +5 -2
  4. data/Gemfile +5 -0
  5. data/Rakefile +2 -0
  6. data/app/assets/javascripts/comfy/admin/cms/application.js +40 -0
  7. data/app/assets/javascripts/comfy/admin/cms/base.js +46 -0
  8. data/app/assets/javascripts/comfy/admin/cms/categories.js +17 -0
  9. data/app/assets/javascripts/comfy/admin/cms/codemirror.js +31 -0
  10. data/app/assets/javascripts/comfy/admin/cms/custom.js +1 -0
  11. data/app/assets/javascripts/comfy/admin/cms/diff.js +10 -0
  12. data/app/assets/javascripts/comfy/admin/cms/file_link.js +67 -0
  13. data/app/assets/javascripts/comfy/admin/cms/file_upload.js +194 -0
  14. data/app/assets/javascripts/comfy/admin/cms/files_modal.js +40 -0
  15. data/app/assets/javascripts/comfy/admin/cms/page_fragments.js +22 -0
  16. data/app/assets/javascripts/comfy/admin/cms/slugify.js +34 -0
  17. data/app/assets/javascripts/comfy/admin/cms/sortable_list.js +40 -0
  18. data/app/assets/javascripts/comfy/admin/cms/timepicker.js +30 -0
  19. data/app/assets/javascripts/comfy/admin/cms/wysiwyg.js +65 -0
  20. data/app/assets/javascripts/comfy/vendor/redactor.js +12 -6
  21. data/app/assets/stylesheets/comfy/admin/cms/base.sass +32 -35
  22. data/app/controllers/application_controller.rb +2 -0
  23. data/app/controllers/comfy/admin/base_controller.rb +3 -1
  24. data/app/controllers/comfy/admin/cms/base_controller.rb +9 -1
  25. data/app/controllers/comfy/admin/cms/categories_controller.rb +2 -0
  26. data/app/controllers/comfy/admin/cms/files_controller.rb +3 -1
  27. data/app/controllers/comfy/admin/cms/layouts_controller.rb +2 -0
  28. data/app/controllers/comfy/admin/cms/pages_controller.rb +4 -1
  29. data/app/controllers/comfy/admin/cms/revisions/base_controller.rb +2 -0
  30. data/app/controllers/comfy/admin/cms/revisions/layout_controller.rb +2 -0
  31. data/app/controllers/comfy/admin/cms/revisions/page_controller.rb +2 -0
  32. data/app/controllers/comfy/admin/cms/revisions/snippet_controller.rb +2 -0
  33. data/app/controllers/comfy/admin/cms/revisions/translation_controller.rb +2 -0
  34. data/app/controllers/comfy/admin/cms/sites_controller.rb +2 -0
  35. data/app/controllers/comfy/admin/cms/snippets_controller.rb +2 -0
  36. data/app/controllers/comfy/admin/cms/translations_controller.rb +8 -0
  37. data/app/controllers/comfy/cms/assets_controller.rb +2 -0
  38. data/app/controllers/comfy/cms/base_controller.rb +4 -2
  39. data/app/controllers/comfy/cms/content_controller.rb +3 -1
  40. data/app/controllers/concerns/comfy/paginate.rb +2 -0
  41. data/app/controllers/concerns/comfy/reorder_action.rb +2 -0
  42. data/app/helpers/comfy/admin/cms_helper.rb +19 -0
  43. data/app/helpers/comfy/cms_helper.rb +4 -2
  44. data/app/models/comfy/cms/categorization.rb +2 -0
  45. data/app/models/comfy/cms/category.rb +2 -0
  46. data/app/models/comfy/cms/file.rb +2 -0
  47. data/app/models/comfy/cms/fragment.rb +3 -1
  48. data/app/models/comfy/cms/layout.rb +3 -1
  49. data/app/models/comfy/cms/page.rb +3 -1
  50. data/app/models/comfy/cms/revision.rb +2 -0
  51. data/app/models/comfy/cms/site.rb +5 -1
  52. data/app/models/comfy/cms/snippet.rb +2 -0
  53. data/app/models/comfy/cms/translation.rb +2 -0
  54. data/app/models/concerns/comfy/cms/with_categories.rb +2 -0
  55. data/app/models/concerns/comfy/cms/with_fragments.rb +2 -0
  56. data/app/views/comfy/admin/cms/categories/_index.html.haml +3 -3
  57. data/app/views/comfy/admin/cms/categories/create.js.erb +1 -1
  58. data/app/views/comfy/admin/cms/categories/destroy.js.erb +8 -3
  59. data/app/views/comfy/admin/cms/files/_file.html.haml +9 -10
  60. data/app/views/comfy/admin/cms/files/_modal.html.haml +1 -2
  61. data/app/views/comfy/admin/cms/files/destroy.js.erb +4 -0
  62. data/app/views/comfy/admin/cms/files/index.html.haml +10 -10
  63. data/app/views/comfy/admin/cms/fragments/_form_fragment_attachments.html.haml +15 -6
  64. data/app/views/comfy/admin/cms/fragments/_form_fragments.html.haml +17 -21
  65. data/app/views/comfy/admin/cms/pages/_form.html.haml +3 -2
  66. data/app/views/comfy/admin/cms/pages/toggle_branch.js.erb +3 -1
  67. data/app/views/comfy/admin/cms/translations/_form.html.haml +3 -2
  68. data/app/views/layouts/comfy/admin/cms.html.haml +0 -1
  69. data/app/views/layouts/comfy/admin/cms/_body.html.haml +1 -0
  70. data/app/views/layouts/comfy/admin/cms/_left.html.haml +1 -1
  71. data/comfortable_mexican_sofa.gemspec +3 -2
  72. data/config.ru +2 -0
  73. data/config/application.rb +2 -0
  74. data/config/boot.rb +2 -0
  75. data/config/cms_routes.rb +2 -0
  76. data/config/environment.rb +2 -0
  77. data/config/environments/development.rb +2 -0
  78. data/config/environments/test.rb +2 -0
  79. data/config/initializers/comfortable_mexican_sofa.rb +2 -0
  80. data/lib/comfortable_mexican_sofa.rb +2 -0
  81. data/lib/comfortable_mexican_sofa/access_control/admin_authentication.rb +2 -0
  82. data/lib/comfortable_mexican_sofa/access_control/admin_authorization.rb +2 -0
  83. data/lib/comfortable_mexican_sofa/access_control/public_authentication.rb +2 -0
  84. data/lib/comfortable_mexican_sofa/access_control/public_authorization.rb +2 -0
  85. data/lib/comfortable_mexican_sofa/configuration.rb +3 -0
  86. data/lib/comfortable_mexican_sofa/content.rb +3 -0
  87. data/lib/comfortable_mexican_sofa/content/block.rb +2 -0
  88. data/lib/comfortable_mexican_sofa/content/params_parser.rb +59 -41
  89. data/lib/comfortable_mexican_sofa/content/renderer.rb +18 -4
  90. data/lib/comfortable_mexican_sofa/content/tag.rb +20 -5
  91. data/lib/comfortable_mexican_sofa/content/tags/asset.rb +2 -0
  92. data/lib/comfortable_mexican_sofa/content/tags/checkbox.rb +10 -3
  93. data/lib/comfortable_mexican_sofa/content/tags/date.rb +3 -1
  94. data/lib/comfortable_mexican_sofa/content/tags/datetime.rb +3 -1
  95. data/lib/comfortable_mexican_sofa/content/tags/file.rb +21 -27
  96. data/lib/comfortable_mexican_sofa/content/tags/file_link.rb +23 -24
  97. data/lib/comfortable_mexican_sofa/content/tags/files.rb +11 -9
  98. data/lib/comfortable_mexican_sofa/content/tags/fragment.rb +11 -1
  99. data/lib/comfortable_mexican_sofa/content/tags/helper.rb +3 -1
  100. data/lib/comfortable_mexican_sofa/content/tags/markdown.rb +3 -1
  101. data/lib/comfortable_mexican_sofa/content/tags/mixins/file_content.rb +38 -0
  102. data/lib/comfortable_mexican_sofa/content/tags/number.rb +3 -1
  103. data/lib/comfortable_mexican_sofa/content/tags/page_file_link.rb +82 -0
  104. data/lib/comfortable_mexican_sofa/content/tags/partial.rb +3 -1
  105. data/lib/comfortable_mexican_sofa/content/tags/snippet.rb +2 -0
  106. data/lib/comfortable_mexican_sofa/content/tags/template.rb +3 -1
  107. data/lib/comfortable_mexican_sofa/content/tags/text.rb +3 -1
  108. data/lib/comfortable_mexican_sofa/content/tags/textarea.rb +3 -1
  109. data/lib/comfortable_mexican_sofa/content/tags/wysiwyg.rb +3 -1
  110. data/lib/comfortable_mexican_sofa/engine.rb +2 -1
  111. data/lib/comfortable_mexican_sofa/error.rb +2 -0
  112. data/lib/comfortable_mexican_sofa/extensions/acts_as_tree.rb +2 -0
  113. data/lib/comfortable_mexican_sofa/extensions/has_revisions.rb +2 -0
  114. data/lib/comfortable_mexican_sofa/form_builder.rb +24 -17
  115. data/lib/comfortable_mexican_sofa/render_methods.rb +2 -0
  116. data/lib/comfortable_mexican_sofa/routes/cms.rb +2 -0
  117. data/lib/comfortable_mexican_sofa/routes/cms_admin.rb +2 -0
  118. data/lib/comfortable_mexican_sofa/routing.rb +2 -0
  119. data/lib/comfortable_mexican_sofa/seeds.rb +3 -1
  120. data/lib/comfortable_mexican_sofa/seeds/file/exporter.rb +2 -0
  121. data/lib/comfortable_mexican_sofa/seeds/file/importer.rb +2 -0
  122. data/lib/comfortable_mexican_sofa/seeds/layout/exporter.rb +2 -0
  123. data/lib/comfortable_mexican_sofa/seeds/layout/importer.rb +2 -0
  124. data/lib/comfortable_mexican_sofa/seeds/page/exporter.rb +2 -0
  125. data/lib/comfortable_mexican_sofa/seeds/page/importer.rb +2 -0
  126. data/lib/comfortable_mexican_sofa/seeds/snippet/exporter.rb +2 -0
  127. data/lib/comfortable_mexican_sofa/seeds/snippet/importer.rb +2 -0
  128. data/lib/comfortable_mexican_sofa/version.rb +3 -1
  129. data/lib/comfortable_mexican_sofa/view_hooks.rb +2 -0
  130. data/lib/generators/comfy/cms/assets_generator.rb +2 -0
  131. data/lib/generators/comfy/cms/cms_generator.rb +6 -4
  132. data/lib/generators/comfy/cms/controllers_generator.rb +2 -0
  133. data/lib/generators/comfy/cms/models_generator.rb +2 -0
  134. data/lib/generators/comfy/cms/views_generator.rb +2 -0
  135. data/lib/generators/comfy/scaffold/scaffold_generator.rb +6 -2
  136. data/lib/tasks/cms_seeds.rake +2 -0
  137. metadata +20 -26
  138. data/app/assets/javascripts/comfy/admin/cms/application.js.coffee +0 -30
  139. data/app/assets/javascripts/comfy/admin/cms/base.js.coffee +0 -224
  140. data/app/assets/javascripts/comfy/admin/cms/custom.js.coffee +0 -1
  141. data/app/assets/javascripts/comfy/admin/cms/files.js.coffee +0 -29
  142. data/app/assets/javascripts/comfy/admin/cms/uploader.js.coffee +0 -140
  143. data/app/views/comfy/admin/cms/files/create.js.erb +0 -1
  144. data/app/views/comfy/admin/cms/files/destroy.js.coffee +0 -2
  145. data/app/views/comfy/admin/cms/pages/form_fragments.js.erb +0 -1
  146. data/app/views/comfy/admin/cms/translations/form_fragments.js.erb +0 -1
@@ -1,9 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ComfortableMexicanSofa::Content::Tag
2
4
 
3
5
  class Error < StandardError; end
4
6
 
5
- attr_reader :context, :params, :source
7
+ # @type [Comfy::Cms::WithFragments]
8
+ attr_reader :context
9
+
10
+ # @type [Array<String, {String => String}>] params
11
+ attr_reader :params
12
+
13
+ # @type [String, nil] source
14
+ attr_reader :source
6
15
 
16
+ # @param [Comfy::Cms::WithFragments] context
17
+ # @param [Array<String, {String => String}>] params
18
+ # @param [String, nil] source
7
19
  def initialize(context:, params: [], source: nil)
8
20
  @context = context
9
21
  @params = params
@@ -12,22 +24,25 @@ class ComfortableMexicanSofa::Content::Tag
12
24
 
13
25
  # Making sure we don't leak erb from tags by accident.
14
26
  # Tag classes can override this, like partials/helpers tags.
15
- def allow_erb
16
- false || ComfortableMexicanSofa.config.allow_erb
27
+ def allow_erb?
28
+ ComfortableMexicanSofa.config.allow_erb
17
29
  end
18
30
 
19
- # Normally it's a string. However if tag content has tags, we need to expand
20
- # them and that produces potentually more stuff
31
+ # Normally it's a {(String)}. However, if tag content has tags,
32
+ # we need to expand them and that produces potentially more stuff.
33
+ # @return [Array<String, ComfortableMexicanSofa::Content::Tag>]
21
34
  def nodes
22
35
  template = ComfortableMexicanSofa::Content::Renderer.new(@context)
23
36
  tokens = template.tokenize(content)
24
37
  template.nodes(tokens)
25
38
  end
26
39
 
40
+ # @return [String]
27
41
  def content
28
42
  raise Error, "This is a base class. It holds no content"
29
43
  end
30
44
 
45
+ # @return [String]
31
46
  def render
32
47
  content
33
48
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This tag allows for linking of js and css content defined on the layout.
2
4
  # Looks something like this:
3
5
  # {{cms:asset layout_identifier, type: css, as: tag}}
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Tag for boolean content that is going to be rendered using checkbox
2
4
  # {{ cms:checkbox identifier }}
3
5
  #
@@ -9,10 +11,15 @@ class ComfortableMexicanSofa::Content::Tag::Checkbox < ComfortableMexicanSofa::C
9
11
 
10
12
  def form_field(object_name, view, index)
11
13
  name = "#{object_name}[fragments_attributes][#{index}][boolean]"
12
- checkbox_hidden = view.hidden_field_tag(name, "0", id: nil)
13
- checkbox_input = view.check_box_tag(name, "1", content.present?, id: nil)
14
14
 
15
- yield [checkbox_hidden, checkbox_input].join.html_safe
15
+ input = view.content_tag(:div, class: "form-check mt-2") do
16
+ view.concat view.hidden_field_tag(name, "0", id: nil)
17
+
18
+ options = { id: form_field_id, class: "form-check-input position-static" }
19
+ view.concat view.check_box_tag(name, "1", content.present?, options)
20
+ end
21
+
22
+ yield input
16
23
  end
17
24
 
18
25
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Tag for text content that is going to be rendered using text input with date widget
2
4
  # {{ cms:date identifier }}
3
5
  #
@@ -9,7 +11,7 @@ class ComfortableMexicanSofa::Content::Tag::Date < ComfortableMexicanSofa::Conte
9
11
 
10
12
  def form_field(object_name, view, index)
11
13
  name = "#{object_name}[fragments_attributes][#{index}][datetime]"
12
- options = { id: nil, class: "form-control", data: { "cms-date" => true } }
14
+ options = { id: form_field_id, class: "form-control", data: { "cms-date" => true } }
13
15
  value = content.present? ? content.to_s(:db) : ""
14
16
  input = view.send(:text_field_tag, name, value, options)
15
17
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Tag for text content that is going to be rendered using text input with datetime widget
2
4
  # {{ cms:datetime identifier }}
3
5
  #
@@ -9,7 +11,7 @@ class ComfortableMexicanSofa::Content::Tag::Datetime < ComfortableMexicanSofa::C
9
11
 
10
12
  def form_field(object_name, view, index)
11
13
  name = "#{object_name}[fragments_attributes][#{index}][datetime]"
12
- options = { id: nil, class: "form-control", data: { "cms-datetime" => true } }
14
+ options = { id: form_field_id, class: "form-control", data: { "cms-datetime" => true } }
13
15
  value = content.present? ? content.to_s(:db) : ""
14
16
  input = view.send(:text_field_tag, name, value, options)
15
17
 
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./mixins/file_content"
4
+
1
5
  # File tag allows attaching of file to the page. This controls how files are
2
6
  # uploaded and then displayed on the page. Example tag:
3
- # {{cms:file identifier, as: link, label: "My File"}}
7
+ # {{ cms:file identifier, as: link, label: "My File" }}
4
8
  #
5
9
  # `as` - url (default) | link | image - render out link or image tag
6
10
  # `label` - attach label attribute to link or image tag
@@ -10,10 +14,15 @@
10
14
  #
11
15
  class ComfortableMexicanSofa::Content::Tag::File < ComfortableMexicanSofa::Content::Tag::Fragment
12
16
 
13
- attr_reader :as, :variant_attrs
17
+ include ComfortableMexicanSofa::Content::Tag::Mixins::FileContent
14
18
 
15
- delegate :rails_blob_path, to: "Rails.application.routes.url_helpers"
19
+ # @type ["url", "link", "image"]
20
+ attr_reader :as
16
21
 
22
+ # @type [{String => String}]
23
+ attr_reader :variant_attrs
24
+
25
+ # @param (see ComfortableMexicanSofa::Content::Tag#initialize)
17
26
  def initialize(context:, params: [], source: nil)
18
27
  super
19
28
  @as = options["as"] || "url"
@@ -21,28 +30,9 @@ class ComfortableMexicanSofa::Content::Tag::File < ComfortableMexicanSofa::Conte
21
30
  @variant_attrs = options.slice("resize", "gravity", "crop")
22
31
  end
23
32
 
24
- def content(file = attachment)
25
- return "" unless file
26
-
27
- if @variant_attrs.present? && attachment.image?
28
- file = file.variant(@variant_attrs)
29
- end
30
-
31
- url = rails_blob_path(file, only_path: true)
32
-
33
- case @as
34
- when "link"
35
- "<a href='#{url}' target='_blank'>#{label}</a>"
36
- when "image"
37
- "<img src='#{url}' alt='#{label}'/>"
38
- else
39
- url
40
- end
41
- end
42
-
43
33
  def form_field(object_name, view, index)
44
34
  name = "#{object_name}[fragments_attributes][#{index}][files]"
45
- input = view.send(:file_field_tag, name, id: nil, class: "form-control")
35
+ input = view.send(:file_field_tag, name, id: form_field_id, class: "form-control")
46
36
 
47
37
  attachments_partial =
48
38
  if fragment.attachments
@@ -51,22 +41,26 @@ class ComfortableMexicanSofa::Content::Tag::File < ComfortableMexicanSofa::Conte
51
41
  locals: {
52
42
  object_name: object_name,
53
43
  index: index,
54
- attachments: fragment.attachments
44
+ attachments: fragment.attachments,
45
+ fragment_id: identifier,
46
+ multiple: false
55
47
  }
56
48
  )
57
49
  end
58
50
 
59
- yield [input, attachments_partial].join.html_safe
51
+ yield view.safe_join([input, attachments_partial], "")
60
52
  end
61
53
 
62
54
  protected
63
55
 
64
- def attachment
56
+ # @return [ActiveStorage::Blob]
57
+ def file
65
58
  fragment.attachments.first
66
59
  end
67
60
 
61
+ # @return [String]
68
62
  def label
69
- @label || attachment && attachment.filename
63
+ @label || file&.filename
70
64
  end
71
65
 
72
66
  end
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./mixins/file_content"
4
+
1
5
  # This is how you link previously uploaded file to anywhere. Good example may be
2
6
  # a header image you want to use on the layout level.
3
7
  # {{cms:file_link id, as: image}}
@@ -10,9 +14,16 @@
10
14
  #
11
15
  class ComfortableMexicanSofa::Content::Tag::FileLink < ComfortableMexicanSofa::Content::Tag
12
16
 
13
- attr_reader :identifier, :as, :variant_attrs
17
+ include ComfortableMexicanSofa::Content::Tag::Mixins::FileContent
18
+
19
+ # @return [String] A {Comfy::Cms::Site#files} ID.
20
+ attr_reader :identifier
21
+
22
+ # @type ["url", "link", "image"]
23
+ attr_reader :as
14
24
 
15
- delegate :rails_blob_path, to: "Rails.application.routes.url_helpers"
25
+ # @type [{String => String}]
26
+ attr_reader :variant_attrs
16
27
 
17
28
  def initialize(context:, params: [], source: nil)
18
29
  super
@@ -27,32 +38,20 @@ class ComfortableMexicanSofa::Content::Tag::FileLink < ComfortableMexicanSofa::C
27
38
  end
28
39
  end
29
40
 
30
- def file
31
- @file ||= context.site.files.detect { |f| f.id == identifier.to_i }
41
+ # @return [Comfy::Cms::File]
42
+ def file_record
43
+ @file_record ||= context.site.files.detect { |f| f.id == identifier.to_i }
32
44
  end
33
45
 
34
- def label
35
- @file.label.present? ? @file.label : @file.attachment.filename
46
+ # @return [ActiveStorage::Blob]
47
+ def file
48
+ file_record&.attachment
36
49
  end
37
50
 
38
- def content
39
- return "" unless file && file.attachment
40
-
41
- attachment = file.attachment
42
- if @variant_attrs.present? && attachment.image?
43
- attachment = attachment.variant(@variant_attrs)
44
- end
45
-
46
- url = rails_blob_path(attachment, only_path: true)
47
-
48
- case @as
49
- when "link"
50
- "<a href='#{url}' target='_blank'>#{label}</a>"
51
- when "image"
52
- "<img src='#{url}' alt='#{label}'/>"
53
- else
54
- url
55
- end
51
+ # @return [String]
52
+ def label
53
+ return "" if file_record.nil?
54
+ file_record.label.presence || file.filename.to_s
56
55
  end
57
56
 
58
57
  end
@@ -1,23 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Same tag as File, only it handles multiple attachments.
2
- # Generally not a bad idea to handle rendering of this in a partial/helper
4
+ # Generally not a bad idea to handle rendering of this in a partial/helper.
5
+ # Example tag:
6
+ # {{ cms:files identifier }}
3
7
  #
4
8
  class ComfortableMexicanSofa::Content::Tag::Files < ComfortableMexicanSofa::Content::Tag::File
5
9
 
6
- def initialize(context:, params: [], source: nil)
7
- super
8
- end
9
-
10
10
  def content
11
11
  return "" if fragment.attachments.blank?
12
12
 
13
13
  fragment.attachments.collect do |attachment|
14
- super(attachment)
14
+ super(file: attachment, label: attachment.filename)
15
15
  end.join(" ")
16
16
  end
17
17
 
18
18
  def form_field(object_name, view, index)
19
19
  name = "#{object_name}[fragments_attributes][#{index}][files][]"
20
- input = view.send(:file_field_tag, name, id: nil, multiple: true, class: "form-control")
20
+ input = view.send(:file_field_tag, name, id: form_field_id, multiple: true, class: "form-control")
21
21
 
22
22
  attachments_partial =
23
23
  if fragment.attachments
@@ -26,12 +26,14 @@ class ComfortableMexicanSofa::Content::Tag::Files < ComfortableMexicanSofa::Cont
26
26
  locals: {
27
27
  object_name: object_name,
28
28
  index: index,
29
- attachments: fragment.attachments
29
+ attachments: fragment.attachments,
30
+ fragment_id: identifier,
31
+ multiple: true
30
32
  }
31
33
  )
32
34
  end
33
35
 
34
- yield [input, attachments_partial].join.html_safe
36
+ yield view.safe_join([input, attachments_partial], "")
35
37
  end
36
38
 
37
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Base Tag class that other fragment tags depend on.
2
4
  # Tag handles following options:
3
5
  # `render`: true (default) | false
@@ -8,7 +10,10 @@
8
10
  #
9
11
  class ComfortableMexicanSofa::Content::Tag::Fragment < ComfortableMexicanSofa::Content::Tag
10
12
 
11
- attr_reader :identifier, :renderable, :namespace, :options
13
+ attr_reader :identifier, :renderable, :namespace
14
+
15
+ # @type [{String => String}]
16
+ attr_reader :options
12
17
 
13
18
  def initialize(context:, params: [], source: nil)
14
19
  super
@@ -25,6 +30,7 @@ class ComfortableMexicanSofa::Content::Tag::Fragment < ComfortableMexicanSofa::C
25
30
  end
26
31
 
27
32
  # Grabs existing fragment record or spins up a new instance if there's none
33
+ # @return [Comfy::Cms::Fragment]
28
34
  def fragment
29
35
  context.fragments.detect { |f| f.identifier == identifier } ||
30
36
  context.fragments.build(identifier: identifier)
@@ -52,4 +58,8 @@ class ComfortableMexicanSofa::Content::Tag::Fragment < ComfortableMexicanSofa::C
52
58
  raise "Form field rendering not implemented for this Tag"
53
59
  end
54
60
 
61
+ def form_field_id
62
+ "fragment-#{@identifier}"
63
+ end
64
+
55
65
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Tag for injecting view helpers. Example tag:
2
4
  # {{cms:helper method_name, param_a, param_b, foo: bar}}
3
5
  # This expands into something like this:
@@ -21,7 +23,7 @@ class ComfortableMexicanSofa::Content::Tag::Helper < ComfortableMexicanSofa::Con
21
23
  end
22
24
 
23
25
  # we output erb into rest of the content
24
- def allow_erb
26
+ def allow_erb?
25
27
  true
26
28
  end
27
29
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Tag for text content that is going to be rendered using textarea with markdown
2
4
  # {{ cms:markdown identifier }}
3
5
  #
@@ -9,7 +11,7 @@ class ComfortableMexicanSofa::Content::Tag::Markdown < ComfortableMexicanSofa::C
9
11
 
10
12
  def form_field(object_name, view, index)
11
13
  name = "#{object_name}[fragments_attributes][#{index}][content]"
12
- options = { id: nil, data: { "cms-cm-mode" => "text/x-markdown" } }
14
+ options = { id: form_field_id, data: { "cms-cm-mode" => "text/x-markdown" } }
13
15
  input = view.send(:text_area_tag, name, content, options)
14
16
 
15
17
  yield input
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A mixin for tags that returns the file as their content.
4
+ module ComfortableMexicanSofa::Content::Tag::Mixins
5
+ module FileContent
6
+
7
+ # @param [ActiveStorage::Blob] file
8
+ # @param ["link", "image", "url"] as
9
+ # @param [{String => String}] variant_attrs ImageMagick variant attributes
10
+ # @param [String] label alt text for `as: "image"`, link text for `as: "link"`
11
+ # @return [String]
12
+ def content(file: self.file, as: self.as, variant_attrs: self.variant_attrs, label: self.label)
13
+ return "" unless file
14
+
15
+ if variant_attrs.present? && attachment.image?
16
+ file = file.variant(variant_attrs)
17
+ end
18
+
19
+ url = rails_blob_path(file)
20
+
21
+ case as
22
+ when "link"
23
+ "<a href='#{url}' target='_blank'>#{label}</a>"
24
+ when "image"
25
+ "<img src='#{url}' alt='#{label}'/>"
26
+ else
27
+ url
28
+ end
29
+ end
30
+
31
+ # @param [ActiveStorage::Blob]
32
+ # @return [String]
33
+ def rails_blob_path(blob)
34
+ Rails.application.routes.url_helpers.rails_blob_path(blob, only_path: true)
35
+ end
36
+
37
+ end
38
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Tag for text content that is going to be rendered using number input
2
4
  # {{ cms:number identifier }}
3
5
  #
@@ -5,7 +7,7 @@ class ComfortableMexicanSofa::Content::Tag::Number < ComfortableMexicanSofa::Con
5
7
 
6
8
  def form_field(object_name, view, index)
7
9
  name = "#{object_name}[fragments_attributes][#{index}][content]"
8
- options = { id: nil, class: "form-control" }
10
+ options = { id: form_field_id, class: "form-control" }
9
11
  input = view.send(:number_field_tag, name, content, options)
10
12
 
11
13
  yield input
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./mixins/file_content"
4
+
5
+ # This tag allows you to link page-level files from within the page content.
6
+ #
7
+ # E.g. if your layout has:
8
+ #
9
+ # {{ cms:file graphic, render: false }}
10
+ # {{ cms:files attachments, redner: false }}
11
+ #
12
+ # You can link to the files from an individual page (or snippet rendered in
13
+ # the context of the page) like so:
14
+ #
15
+ # {{ cms:page_file_link graphic }}
16
+ # {{ cms:page_file_link attachments, filename: "cat.jpg" }}
17
+ #
18
+ # `as` - url (default) | link | image - how file gets rendered out
19
+ # `label` - attach label attribute to link or image tag
20
+ # `resize` - imagemagick option. For example: "100x50>"
21
+ # `gravity` - imagemagick option. For example: "center"
22
+ # `crop` - imagemagick option. For example: "100x50+0+0"
23
+ #
24
+ class ComfortableMexicanSofa::Content::Tag::PageFileLink < ComfortableMexicanSofa::Content::Tag
25
+
26
+ include ComfortableMexicanSofa::Content::Tag::Mixins::FileContent
27
+
28
+ # @return [String] A `cms:file(s)` identifier.
29
+ attr_reader :identifier
30
+
31
+ # @type ["url", "link", "image"]
32
+ attr_reader :as
33
+
34
+ # @type [{String => String}]
35
+ attr_reader :variant_attrs
36
+
37
+ # @return [String] Used to refer to a file in a {{ cms:files }} tag.
38
+ attr_reader :filename
39
+
40
+ # @param (see ComfortableMexicanSofa::Content::Tag#initialize)
41
+ def initialize(context:, params: [], source: nil)
42
+ super
43
+
44
+ options = params.extract_options!
45
+ @identifier = params[0]
46
+ @as = options["as"] || "url"
47
+ @variant_attrs = options.slice("resize", "gravity", "crop")
48
+ @filename = options["filename"]
49
+
50
+ unless @identifier.present?
51
+ raise Error, "Missing identifier for page file link tag"
52
+ end
53
+ end
54
+
55
+ # @return [Comfy::Cms::Fragment]
56
+ def fragment
57
+ @fragment ||= context.fragments.detect { |f| f.identifier == identifier }
58
+ end
59
+
60
+ # @return [ActiveStorage::Blob]
61
+ def file
62
+ @file ||=
63
+ if fragment.nil?
64
+ nil
65
+ elsif filename.nil?
66
+ fragment.attachments.first
67
+ else
68
+ fragment.attachments.detect { |a| a.filename.to_s == filename }
69
+ end
70
+ end
71
+
72
+ # @return [String]
73
+ def label
74
+ return if file.nil?
75
+ file.filename.to_s
76
+ end
77
+
78
+ end
79
+
80
+ ComfortableMexicanSofa::Content::Renderer.register_tag(
81
+ :page_file_link, ComfortableMexicanSofa::Content::Tag::PageFileLink
82
+ )