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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +5 -2
- data/Gemfile +5 -0
- data/Rakefile +2 -0
- data/app/assets/javascripts/comfy/admin/cms/application.js +40 -0
- data/app/assets/javascripts/comfy/admin/cms/base.js +46 -0
- data/app/assets/javascripts/comfy/admin/cms/categories.js +17 -0
- data/app/assets/javascripts/comfy/admin/cms/codemirror.js +31 -0
- data/app/assets/javascripts/comfy/admin/cms/custom.js +1 -0
- data/app/assets/javascripts/comfy/admin/cms/diff.js +10 -0
- data/app/assets/javascripts/comfy/admin/cms/file_link.js +67 -0
- data/app/assets/javascripts/comfy/admin/cms/file_upload.js +194 -0
- data/app/assets/javascripts/comfy/admin/cms/files_modal.js +40 -0
- data/app/assets/javascripts/comfy/admin/cms/page_fragments.js +22 -0
- data/app/assets/javascripts/comfy/admin/cms/slugify.js +34 -0
- data/app/assets/javascripts/comfy/admin/cms/sortable_list.js +40 -0
- data/app/assets/javascripts/comfy/admin/cms/timepicker.js +30 -0
- data/app/assets/javascripts/comfy/admin/cms/wysiwyg.js +65 -0
- data/app/assets/javascripts/comfy/vendor/redactor.js +12 -6
- data/app/assets/stylesheets/comfy/admin/cms/base.sass +32 -35
- data/app/controllers/application_controller.rb +2 -0
- data/app/controllers/comfy/admin/base_controller.rb +3 -1
- data/app/controllers/comfy/admin/cms/base_controller.rb +9 -1
- data/app/controllers/comfy/admin/cms/categories_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/files_controller.rb +3 -1
- data/app/controllers/comfy/admin/cms/layouts_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/pages_controller.rb +4 -1
- data/app/controllers/comfy/admin/cms/revisions/base_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/revisions/layout_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/revisions/page_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/revisions/snippet_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/revisions/translation_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/sites_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/snippets_controller.rb +2 -0
- data/app/controllers/comfy/admin/cms/translations_controller.rb +8 -0
- data/app/controllers/comfy/cms/assets_controller.rb +2 -0
- data/app/controllers/comfy/cms/base_controller.rb +4 -2
- data/app/controllers/comfy/cms/content_controller.rb +3 -1
- data/app/controllers/concerns/comfy/paginate.rb +2 -0
- data/app/controllers/concerns/comfy/reorder_action.rb +2 -0
- data/app/helpers/comfy/admin/cms_helper.rb +19 -0
- data/app/helpers/comfy/cms_helper.rb +4 -2
- data/app/models/comfy/cms/categorization.rb +2 -0
- data/app/models/comfy/cms/category.rb +2 -0
- data/app/models/comfy/cms/file.rb +2 -0
- data/app/models/comfy/cms/fragment.rb +3 -1
- data/app/models/comfy/cms/layout.rb +3 -1
- data/app/models/comfy/cms/page.rb +3 -1
- data/app/models/comfy/cms/revision.rb +2 -0
- data/app/models/comfy/cms/site.rb +5 -1
- data/app/models/comfy/cms/snippet.rb +2 -0
- data/app/models/comfy/cms/translation.rb +2 -0
- data/app/models/concerns/comfy/cms/with_categories.rb +2 -0
- data/app/models/concerns/comfy/cms/with_fragments.rb +2 -0
- data/app/views/comfy/admin/cms/categories/_index.html.haml +3 -3
- data/app/views/comfy/admin/cms/categories/create.js.erb +1 -1
- data/app/views/comfy/admin/cms/categories/destroy.js.erb +8 -3
- data/app/views/comfy/admin/cms/files/_file.html.haml +9 -10
- data/app/views/comfy/admin/cms/files/_modal.html.haml +1 -2
- data/app/views/comfy/admin/cms/files/destroy.js.erb +4 -0
- data/app/views/comfy/admin/cms/files/index.html.haml +10 -10
- data/app/views/comfy/admin/cms/fragments/_form_fragment_attachments.html.haml +15 -6
- data/app/views/comfy/admin/cms/fragments/_form_fragments.html.haml +17 -21
- data/app/views/comfy/admin/cms/pages/_form.html.haml +3 -2
- data/app/views/comfy/admin/cms/pages/toggle_branch.js.erb +3 -1
- data/app/views/comfy/admin/cms/translations/_form.html.haml +3 -2
- data/app/views/layouts/comfy/admin/cms.html.haml +0 -1
- data/app/views/layouts/comfy/admin/cms/_body.html.haml +1 -0
- data/app/views/layouts/comfy/admin/cms/_left.html.haml +1 -1
- data/comfortable_mexican_sofa.gemspec +3 -2
- data/config.ru +2 -0
- data/config/application.rb +2 -0
- data/config/boot.rb +2 -0
- data/config/cms_routes.rb +2 -0
- data/config/environment.rb +2 -0
- data/config/environments/development.rb +2 -0
- data/config/environments/test.rb +2 -0
- data/config/initializers/comfortable_mexican_sofa.rb +2 -0
- data/lib/comfortable_mexican_sofa.rb +2 -0
- data/lib/comfortable_mexican_sofa/access_control/admin_authentication.rb +2 -0
- data/lib/comfortable_mexican_sofa/access_control/admin_authorization.rb +2 -0
- data/lib/comfortable_mexican_sofa/access_control/public_authentication.rb +2 -0
- data/lib/comfortable_mexican_sofa/access_control/public_authorization.rb +2 -0
- data/lib/comfortable_mexican_sofa/configuration.rb +3 -0
- data/lib/comfortable_mexican_sofa/content.rb +3 -0
- data/lib/comfortable_mexican_sofa/content/block.rb +2 -0
- data/lib/comfortable_mexican_sofa/content/params_parser.rb +59 -41
- data/lib/comfortable_mexican_sofa/content/renderer.rb +18 -4
- data/lib/comfortable_mexican_sofa/content/tag.rb +20 -5
- data/lib/comfortable_mexican_sofa/content/tags/asset.rb +2 -0
- data/lib/comfortable_mexican_sofa/content/tags/checkbox.rb +10 -3
- data/lib/comfortable_mexican_sofa/content/tags/date.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/datetime.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/file.rb +21 -27
- data/lib/comfortable_mexican_sofa/content/tags/file_link.rb +23 -24
- data/lib/comfortable_mexican_sofa/content/tags/files.rb +11 -9
- data/lib/comfortable_mexican_sofa/content/tags/fragment.rb +11 -1
- data/lib/comfortable_mexican_sofa/content/tags/helper.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/markdown.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/mixins/file_content.rb +38 -0
- data/lib/comfortable_mexican_sofa/content/tags/number.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/page_file_link.rb +82 -0
- data/lib/comfortable_mexican_sofa/content/tags/partial.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/snippet.rb +2 -0
- data/lib/comfortable_mexican_sofa/content/tags/template.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/text.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/textarea.rb +3 -1
- data/lib/comfortable_mexican_sofa/content/tags/wysiwyg.rb +3 -1
- data/lib/comfortable_mexican_sofa/engine.rb +2 -1
- data/lib/comfortable_mexican_sofa/error.rb +2 -0
- data/lib/comfortable_mexican_sofa/extensions/acts_as_tree.rb +2 -0
- data/lib/comfortable_mexican_sofa/extensions/has_revisions.rb +2 -0
- data/lib/comfortable_mexican_sofa/form_builder.rb +24 -17
- data/lib/comfortable_mexican_sofa/render_methods.rb +2 -0
- data/lib/comfortable_mexican_sofa/routes/cms.rb +2 -0
- data/lib/comfortable_mexican_sofa/routes/cms_admin.rb +2 -0
- data/lib/comfortable_mexican_sofa/routing.rb +2 -0
- data/lib/comfortable_mexican_sofa/seeds.rb +3 -1
- data/lib/comfortable_mexican_sofa/seeds/file/exporter.rb +2 -0
- data/lib/comfortable_mexican_sofa/seeds/file/importer.rb +2 -0
- data/lib/comfortable_mexican_sofa/seeds/layout/exporter.rb +2 -0
- data/lib/comfortable_mexican_sofa/seeds/layout/importer.rb +2 -0
- data/lib/comfortable_mexican_sofa/seeds/page/exporter.rb +2 -0
- data/lib/comfortable_mexican_sofa/seeds/page/importer.rb +2 -0
- data/lib/comfortable_mexican_sofa/seeds/snippet/exporter.rb +2 -0
- data/lib/comfortable_mexican_sofa/seeds/snippet/importer.rb +2 -0
- data/lib/comfortable_mexican_sofa/version.rb +3 -1
- data/lib/comfortable_mexican_sofa/view_hooks.rb +2 -0
- data/lib/generators/comfy/cms/assets_generator.rb +2 -0
- data/lib/generators/comfy/cms/cms_generator.rb +6 -4
- data/lib/generators/comfy/cms/controllers_generator.rb +2 -0
- data/lib/generators/comfy/cms/models_generator.rb +2 -0
- data/lib/generators/comfy/cms/views_generator.rb +2 -0
- data/lib/generators/comfy/scaffold/scaffold_generator.rb +6 -2
- data/lib/tasks/cms_seeds.rake +2 -0
- metadata +20 -26
- data/app/assets/javascripts/comfy/admin/cms/application.js.coffee +0 -30
- data/app/assets/javascripts/comfy/admin/cms/base.js.coffee +0 -224
- data/app/assets/javascripts/comfy/admin/cms/custom.js.coffee +0 -1
- data/app/assets/javascripts/comfy/admin/cms/files.js.coffee +0 -29
- data/app/assets/javascripts/comfy/admin/cms/uploader.js.coffee +0 -140
- data/app/views/comfy/admin/cms/files/create.js.erb +0 -1
- data/app/views/comfy/admin/cms/files/destroy.js.coffee +0 -2
- data/app/views/comfy/admin/cms/pages/form_fragments.js.erb +0 -1
- data/app/views/comfy/admin/cms/translations/form_fragments.js.erb +0 -1
@@ -1,10 +1,6 @@
|
|
1
1
|
- begin
|
2
2
|
- nodes = record.fragment_nodes
|
3
|
-
|
4
|
-
// Grouping nodes by their namespace
|
5
|
-
- namespace = nodes.each_with_object({}) do |n, h|
|
6
|
-
- h[n.namespace] ||= []
|
7
|
-
- h[n.namespace] << n
|
3
|
+
- namespace = nodes.group_by(&:namespace)
|
8
4
|
|
9
5
|
#form-fragments
|
10
6
|
- if nodes.empty?
|
@@ -14,29 +10,29 @@
|
|
14
10
|
= t(".no_tags").html_safe
|
15
11
|
|
16
12
|
- else
|
17
|
-
|
13
|
+
.tabbable
|
14
|
+
- if namespace.size > 1
|
15
|
+
.row
|
16
|
+
.col-sm-2
|
17
|
+
.col-sm-10
|
18
|
+
%ul.nav.nav-tabs
|
19
|
+
- namespace.each_with_index do |(name, tags), index|
|
20
|
+
%li.nav-item
|
21
|
+
- active = index == 0 ? "active" : nil
|
22
|
+
- label = t("comfy.cms.content.namespace.#{name}", default: name.humanize)
|
23
|
+
= link_to label, "#ns-#{name}", class: "nav-link #{active}", data: {toggle: "tab"}
|
18
24
|
|
19
|
-
.
|
20
|
-
-
|
21
|
-
.row
|
22
|
-
.col-sm-2
|
23
|
-
.col-sm-10
|
24
|
-
%ul.nav.nav-tabs
|
25
|
-
- namespace.each_with_index do |(name, tags), index|
|
26
|
-
%li.nav-item
|
27
|
-
- active = index == 0 ? "active" : nil
|
28
|
-
- label = t("comfy.cms.content.namespace.#{name}", default: name.humanize)
|
29
|
-
= link_to label, "#ns-#{name}", class: "nav-link #{active}", data: {toggle: "tab"}
|
25
|
+
.tab-content
|
26
|
+
- frag_index = 0
|
30
27
|
|
31
|
-
|
32
|
-
|
28
|
+
- builder_opts = { builder: ComfortableMexicanSofa::FormBuilder, bootstrap: { layout: :horizontal }}
|
29
|
+
= fields scope, model: record, **builder_opts do |form|
|
33
30
|
- namespace.each_with_index do |(name, tags), index|
|
34
31
|
.tab-pane{id: "ns-#{name}", class: index == 0 ? "active" : nil}
|
35
32
|
- tags.each do |tag|
|
36
|
-
=
|
33
|
+
= form.fragment_field(tag, frag_index)
|
37
34
|
- frag_index += 1
|
38
35
|
|
39
|
-
|
40
36
|
- rescue ComfortableMexicanSofa::Content::Renderer::SyntaxError, ComfortableMexicanSofa::Content::Tag::Error => e
|
41
37
|
.alert.alert-danger
|
42
38
|
= e
|
@@ -13,7 +13,8 @@
|
|
13
13
|
|
14
14
|
= comfy_admin_partial "comfy/admin/cms/partials/page_form_inner", form: form
|
15
15
|
|
16
|
-
|
16
|
+
#form-fragments-container
|
17
|
+
= render "comfy/admin/cms/fragments/form_fragments", record: @page, scope: :page
|
17
18
|
|
18
19
|
= render "comfy/admin/cms/categories/form", form: form
|
19
20
|
|
@@ -25,6 +26,6 @@
|
|
25
26
|
= comfy_admin_partial "comfy/admin/cms/partials/page_form_after", form: form
|
26
27
|
|
27
28
|
= form.form_actions do
|
28
|
-
= submit_tag t(".preview"), name: "preview", id: nil, class: "btn btn-secondary", data: {disable_with: false}
|
29
|
+
= submit_tag t(".preview"), name: "preview", formtarget: "comfy-cms-preview", id: nil, class: "btn btn-secondary", data: {disable_with: false}
|
29
30
|
= submit_tag t(@page.new_record?? ".create" : ".update"), class: "btn btn-primary ml-sm-1", data: {disable_with: false}
|
30
31
|
= link_to t(".cancel"), comfy_admin_cms_site_pages_path, class: "btn btn-link"
|
@@ -1,10 +1,12 @@
|
|
1
|
+
// TODO: Extract this so the server only renders the HTML.
|
1
2
|
var li = $('li#comfy_cms_page_<%=@page.id%>');
|
2
3
|
li.find('.item .toggle').first().toggleClass('open');
|
3
4
|
|
4
5
|
<% if session[:cms_page_tree].member?(@page.id.to_s) %>
|
5
6
|
if(!li.find('ul.children')[0]) {
|
6
7
|
li.append('<ul class="children sortable pl-md-3"><%= escape_javascript(render partial: "index_branch", collection: @page.children) %></ul>');
|
7
|
-
CMS.
|
8
|
+
CMS.sortableList.destroy();
|
9
|
+
CMS.sortableList.init();
|
8
10
|
}
|
9
11
|
<% else %>
|
10
12
|
li.find('ul.children').remove();
|
@@ -7,13 +7,14 @@
|
|
7
7
|
- if (options = ::Comfy::Cms::Layout.options_for_select(@site)).present?
|
8
8
|
= form.select :layout_id, options, {}, {data: {url: form_fragments_comfy_admin_cms_site_page_translation_path(@site, @page, @translation.id.to_i)}, id: "fragments-toggle"}
|
9
9
|
|
10
|
-
|
10
|
+
#form-fragments-container
|
11
|
+
= render "comfy/admin/cms/fragments/form_fragments", record: @translation, scope: :translation
|
11
12
|
|
12
13
|
= form.check_box :is_published
|
13
14
|
|
14
15
|
= comfy_admin_partial "comfy/admin/cms/partials/translation_form_after", form: form
|
15
16
|
|
16
17
|
= form.form_actions do
|
17
|
-
= submit_tag t(".preview"), name: "preview", id: nil, class: "btn btn-secondary", data: {disable_with: false}
|
18
|
+
= submit_tag t(".preview"), name: "preview", formtarget: "comfy-cms-preview", id: nil, class: "btn btn-secondary", data: {disable_with: false}
|
18
19
|
= submit_tag t(@translation.new_record? ? ".create" : ".update"), class: "btn btn-primary", data: {disable_with: false}
|
19
20
|
= link_to t(".cancel"), edit_comfy_admin_cms_site_page_path(@site, @page), class: "btn btn-link"
|
@@ -23,7 +23,7 @@
|
|
23
23
|
= t('comfy.admin.cms.base.snippets')
|
24
24
|
%li.nav-item
|
25
25
|
- unless is_active_link?(comfy_admin_cms_site_files_path(@site))
|
26
|
-
%a.cms-files-open-modal{href:
|
26
|
+
%a.cms-files-open-modal{href: comfy_admin_cms_site_files_path(@site), title: "Open library"}
|
27
27
|
%i.fas.fa-bars
|
28
28
|
= active_link_to comfy_admin_cms_site_files_path(@site), class: "nav-link" do
|
29
29
|
= t('comfy.admin.cms.base.files')
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
2
4
|
require "comfortable_mexican_sofa/version"
|
3
5
|
|
@@ -15,10 +17,9 @@ Gem::Specification.new do |s|
|
|
15
17
|
f.match(%r{^(test|doc)/})
|
16
18
|
end
|
17
19
|
|
18
|
-
s.required_ruby_version = ">= 2.
|
20
|
+
s.required_ruby_version = ">= 2.3.0"
|
19
21
|
|
20
22
|
s.add_dependency "active_link_to", ">= 1.0.0"
|
21
|
-
s.add_dependency "coffee-rails", ">= 4.2.0"
|
22
23
|
s.add_dependency "comfy_bootstrap_form", ">= 4.0.0"
|
23
24
|
s.add_dependency "haml-rails", ">= 1.0.0"
|
24
25
|
s.add_dependency "jquery-rails", ">= 4.3.1"
|
data/config.ru
CHANGED
data/config/application.rb
CHANGED
data/config/boot.rb
CHANGED
data/config/cms_routes.rb
CHANGED
data/config/environment.rb
CHANGED
data/config/environments/test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class ComfortableMexicanSofa::Configuration
|
2
4
|
|
3
5
|
# Don't like ComfortableMexicanSofa? Set it to whatever you like. :(
|
@@ -45,6 +47,7 @@ class ComfortableMexicanSofa::Configuration
|
|
45
47
|
attr_accessor :admin_cache_sweeper
|
46
48
|
|
47
49
|
# Not allowing erb code to be run inside page content. False by default.
|
50
|
+
# @return [Boolean]
|
48
51
|
attr_accessor :allow_erb
|
49
52
|
|
50
53
|
# Whitelist of all helper methods that can be used via {{cms:helper}} tag. By default
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ComfortableMexicanSofa::Content
|
2
4
|
# ...
|
3
5
|
end
|
@@ -23,6 +25,7 @@ require_relative "content/tags/files"
|
|
23
25
|
require_relative "content/tags/snippet"
|
24
26
|
require_relative "content/tags/asset"
|
25
27
|
require_relative "content/tags/file_link"
|
28
|
+
require_relative "content/tags/page_file_link"
|
26
29
|
require_relative "content/tags/helper"
|
27
30
|
require_relative "content/tags/partial"
|
28
31
|
require_relative "content/tags/template"
|
@@ -1,54 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "strscan"
|
4
|
+
|
1
5
|
module ComfortableMexicanSofa::Content::ParamsParser
|
2
6
|
|
3
7
|
class Error < StandardError; end
|
4
8
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
COMMA = %r{,}
|
9
|
+
STRING_LITERAL = %r{'[^']*'|"[^"]*"}
|
10
|
+
IDENTIFIER = %r{[a-z0-9][\w\-/.]*}i
|
11
|
+
COLON = %r{:}
|
12
|
+
COMMA = %r{,}
|
10
13
|
|
14
|
+
# @param [String] text
|
15
|
+
# @return [Array<String, {String => String}>]
|
16
|
+
# @raise [Error] if the given `text` is malformed.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# parse("happy greeting name:Joe show:true")
|
20
|
+
# #=> ['happy', 'greeting', {'name' => 'Joe', 'show' => 'true'}]
|
11
21
|
def self.parse(text)
|
12
|
-
|
22
|
+
parse_token_groups(split_on_commas(tokenize(text.to_s)))
|
13
23
|
end
|
14
24
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
25
|
+
# @param [Enumerable<Array<(Symbol, String)>>] token_groups
|
26
|
+
# @return [Array<String, {String => String}>]
|
27
|
+
def self.parse_token_groups(token_groups)
|
28
|
+
token_groups.each_with_object([]) do |tokens, params|
|
29
|
+
case tokens.count
|
30
|
+
when 1
|
31
|
+
params << parse_string_param(tokens[0])
|
32
|
+
when 3
|
33
|
+
param = parse_key_value_param(tokens)
|
34
|
+
if params.last.is_a?(Hash)
|
35
|
+
params.last.update(param)
|
36
|
+
else
|
37
|
+
params << param
|
38
|
+
end
|
22
39
|
else
|
23
40
|
raise Error, "Unexpected tokens found: #{tokens}"
|
24
41
|
end
|
25
42
|
end
|
26
|
-
params
|
27
43
|
end
|
28
44
|
|
29
|
-
|
45
|
+
# @param [(:string, String)] token
|
46
|
+
# @return [String]
|
47
|
+
# @raise [Error] if `token[0] != :string`.
|
48
|
+
def self.parse_string_param(token)
|
30
49
|
type, value = token
|
31
50
|
raise Error, "Unexpected token: #{token}" unless type == :string
|
32
|
-
|
51
|
+
value
|
33
52
|
end
|
34
53
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
unless key_type == :string && col_type == :
|
54
|
+
# @param [((:string, String), (:colon, String), (:string, String))] tokens
|
55
|
+
# @return [{String => String}]
|
56
|
+
# @raise [Error] if `tokens[0][0] != :string`, or `tokens[1][0] != :colon`,
|
57
|
+
# or `tokens[2][0] != :string`.
|
58
|
+
def self.parse_key_value_param(tokens)
|
59
|
+
(key_type, key_value), (col_type, _col_value), (val_type, val_value) = tokens
|
60
|
+
unless key_type == :string && col_type == :colon && val_type == :string
|
42
61
|
raise Error, "Unexpected tokens: #{tokens}"
|
43
62
|
end
|
44
|
-
|
45
|
-
hash = params.last.is_a?(Hash) ? params.pop : {}
|
46
|
-
hash[key_value] = val_value
|
47
|
-
params << hash
|
63
|
+
{ key_value => val_value }
|
48
64
|
end
|
49
65
|
|
50
|
-
#
|
51
|
-
|
66
|
+
# Splits tokens on commas. The result contains no `:comma` tokens.
|
67
|
+
#
|
68
|
+
# @param [Enumerable<(Symbol, String)>] tokens
|
69
|
+
# @return [Enumerable<Array<(Symbol, String)>>] Token groups.
|
70
|
+
def self.split_on_commas(tokens)
|
52
71
|
slices = tokens.slice_after do |token|
|
53
72
|
token[0] == :comma
|
54
73
|
end
|
@@ -59,25 +78,24 @@ module ComfortableMexicanSofa::Content::ParamsParser
|
|
59
78
|
|
60
79
|
# Tokenizing input string into a list of touples
|
61
80
|
# Also args_string is stripped of "smart" quotes coming from wysiwyg
|
81
|
+
#
|
82
|
+
# @param [String] args_string
|
83
|
+
# @return [Array<String>] tokens
|
62
84
|
def self.tokenize(args_string)
|
63
|
-
args_string.
|
64
|
-
args_string.gsub!(%r{[‘’]}, "'")
|
65
|
-
|
66
|
-
tokens = []
|
85
|
+
args_string = args_string.tr("“”‘’", %q(""''))
|
67
86
|
ss = StringScanner.new(args_string)
|
68
|
-
|
87
|
+
tokens = []
|
88
|
+
loop do
|
69
89
|
ss.skip(%r{\s*})
|
70
90
|
break if ss.eos?
|
71
|
-
|
72
|
-
if (t = ss.scan(
|
73
|
-
elsif (t = ss.scan(
|
74
|
-
elsif (t = ss.scan(
|
75
|
-
elsif (t = ss.scan(
|
76
|
-
elsif (t = ss.scan(COMMA)) then [:comma, t]
|
91
|
+
tokens <<
|
92
|
+
if (t = ss.scan(STRING_LITERAL)) then [:string, t[1...-1]]
|
93
|
+
elsif (t = ss.scan(IDENTIFIER)) then [:string, t]
|
94
|
+
elsif (t = ss.scan(COLON)) then [:colon, t]
|
95
|
+
elsif (t = ss.scan(COMMA)) then [:comma, t]
|
77
96
|
else
|
78
97
|
raise Error, "Unexpected char: #{ss.getch}"
|
79
98
|
end
|
80
|
-
tokens << token
|
81
99
|
end
|
82
100
|
tokens
|
83
101
|
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "strscan"
|
4
|
+
|
1
5
|
# Processing content follows these stages:
|
2
6
|
#
|
3
7
|
# string - Text with tags. like this: "some {{cms:fragment content}} text"
|
@@ -22,16 +26,20 @@ class ComfortableMexicanSofa::Content::Renderer
|
|
22
26
|
|
23
27
|
class << self
|
24
28
|
|
29
|
+
# @return [Hash<String, Class<ComfortableMexicanSofa::Content::Tag>>]
|
25
30
|
def tags
|
26
31
|
@tags ||= {}
|
27
32
|
end
|
28
33
|
|
34
|
+
# @param [String] name
|
35
|
+
# @param [Class<ComfortableMexicanSofa::Content::Tag>] klass
|
29
36
|
def register_tag(name, klass)
|
30
37
|
tags[name.to_s] = klass
|
31
38
|
end
|
32
39
|
|
33
40
|
end
|
34
41
|
|
42
|
+
# @param [Comfy::Cms::WithFragments, nil] context
|
35
43
|
def initialize(context)
|
36
44
|
@context = context
|
37
45
|
@depth = 0
|
@@ -39,6 +47,8 @@ class ComfortableMexicanSofa::Content::Renderer
|
|
39
47
|
|
40
48
|
# This is how we render content out. Takes context (cms page) and content
|
41
49
|
# nodes
|
50
|
+
# @param [Array<String, ComfortableMexicanSofa::Content::Tag>]
|
51
|
+
# @param [Boolean] allow_erb
|
42
52
|
def render(nodes, allow_erb = ComfortableMexicanSofa.config.allow_erb)
|
43
53
|
if (@depth += 1) > MAX_DEPTH
|
44
54
|
raise Error, "Deep tag nesting or recursive nesting detected"
|
@@ -51,7 +61,7 @@ class ComfortableMexicanSofa::Content::Renderer
|
|
51
61
|
else
|
52
62
|
tokens = tokenize(node.render)
|
53
63
|
nodes = nodes(tokens)
|
54
|
-
render(nodes, allow_erb || node.allow_erb)
|
64
|
+
render(nodes, allow_erb || node.allow_erb?)
|
55
65
|
end
|
56
66
|
end.flatten.join
|
57
67
|
end
|
@@ -65,6 +75,7 @@ class ComfortableMexicanSofa::Content::Renderer
|
|
65
75
|
end
|
66
76
|
|
67
77
|
# Splitting text with tags into tokens we can process down the line
|
78
|
+
# @return [Array<String, {Symbol => String}>]
|
68
79
|
def tokenize(string)
|
69
80
|
tokens = []
|
70
81
|
ss = StringScanner.new(string.to_s)
|
@@ -85,6 +96,8 @@ class ComfortableMexicanSofa::Content::Renderer
|
|
85
96
|
# Constructing node tree for content. It's a list of strings and tags with
|
86
97
|
# their own `nodes` method that has array of strings and tags with their own
|
87
98
|
# `nodes` method that... you get the idea.
|
99
|
+
# @param [Array<String, {Symbol => String}>] tokens
|
100
|
+
# @return [Array<String, ComfortableMexicanSofa::Content::Tag>]
|
88
101
|
def nodes(tokens)
|
89
102
|
nodes = [[]]
|
90
103
|
tokens.each do |token|
|
@@ -102,10 +115,11 @@ class ComfortableMexicanSofa::Content::Renderer
|
|
102
115
|
nodes.pop
|
103
116
|
|
104
117
|
else
|
105
|
-
|
106
|
-
|
107
|
-
|
118
|
+
# @type [Class<ComfortableMexicanSofa::Content::Tag>]
|
119
|
+
klass = self.class.tags[tag_class] ||
|
120
|
+
raise(SyntaxError, "Unrecognized tag: #{token[:source]}")
|
108
121
|
|
122
|
+
# @type [ComfortableMexicanSofa::Content::Tag]
|
109
123
|
tag = klass.new(
|
110
124
|
context: @context,
|
111
125
|
params: ComfortableMexicanSofa::Content::ParamsParser.parse(token[:tag_params]),
|