scribo 1.0.38
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +93 -0
- data/Rakefile +40 -0
- data/app/assets/config/scribo_manifest.js +2 -0
- data/app/assets/javascripts/scribo/scribo.js +1 -0
- data/app/assets/stylesheets/scribo/scribo.css +1 -0
- data/app/controllers/concerns/maintenance_standards.rb +24 -0
- data/app/controllers/scribo/admin/sites/contents_controller.rb +86 -0
- data/app/controllers/scribo/admin/sites_controller.rb +61 -0
- data/app/controllers/scribo/api/sites_controller.rb +23 -0
- data/app/controllers/scribo/application_admin_controller.rb +11 -0
- data/app/controllers/scribo/application_controller.rb +6 -0
- data/app/controllers/scribo/contents_controller.rb +20 -0
- data/app/drops/scribo/action_dispatch/request_drop.rb +15 -0
- data/app/drops/scribo/active_model/errors_drop.rb +16 -0
- data/app/drops/scribo/application_drop.rb +9 -0
- data/app/drops/scribo/array_drop.rb +13 -0
- data/app/drops/scribo/content_drop.rb +73 -0
- data/app/drops/scribo/data_drop.rb +35 -0
- data/app/drops/scribo/form_drop.rb +26 -0
- data/app/drops/scribo/include_drop.rb +13 -0
- data/app/drops/scribo/paginator_drop.rb +73 -0
- data/app/drops/scribo/site_drop.rb +83 -0
- data/app/helpers/scribo/application_helper.rb +13 -0
- data/app/jobs/scribo/application_job.rb +6 -0
- data/app/models/scribo/application_record.rb +11 -0
- data/app/models/scribo/content.rb +378 -0
- data/app/models/scribo/site.rb +161 -0
- data/app/services/scribo/application_service.rb +9 -0
- data/app/services/scribo/content_find_service.rb +69 -0
- data/app/services/scribo/content_render_service.rb +127 -0
- data/app/services/scribo/site_export_service.rb +41 -0
- data/app/services/scribo/site_find_service.rb +26 -0
- data/app/services/scribo/site_import_service.rb +96 -0
- data/app/views/layouts/scribo.html.slim +1 -0
- data/app/views/scribo/admin/sites/_create_sites.html.slim +22 -0
- data/app/views/scribo/admin/sites/_sites.html.slim +18 -0
- data/app/views/scribo/admin/sites/contents/_form.html.slim +17 -0
- data/app/views/scribo/admin/sites/contents/create.json.jbuilder +11 -0
- data/app/views/scribo/admin/sites/contents/edit.html.slim +2 -0
- data/app/views/scribo/admin/sites/contents/edit.json.jbuilder +9 -0
- data/app/views/scribo/admin/sites/contents/index.html.slim +1 -0
- data/app/views/scribo/admin/sites/contents/move.json.jbuilder +9 -0
- data/app/views/scribo/admin/sites/contents/rename.json.jbuilder +9 -0
- data/app/views/scribo/admin/sites/contents/upload.json.jbuilder +9 -0
- data/app/views/scribo/admin/sites/import.json.jbuilder +4 -0
- data/app/views/scribo/admin/sites/index.html.slim +7 -0
- data/app/views/scribo/shared/_entry.html.slim +17 -0
- data/app/views/scribo/shared/_ide.html.slim +14 -0
- data/app/views/scribo/shared/_tree-view.html.slim +32 -0
- data/config/locales/en.yml +39 -0
- data/config/routes.rb +35 -0
- data/db/migrate/20200123095630_initial_scribo.rb +34 -0
- data/db/migrate/20220919124119_add_ancestry_to_scribo_contents.rb +13 -0
- data/db/migrate/20220919124749_remove_parent_id_from_scribo_contents.rb +8 -0
- data/lib/scribo/action_controller_helpers.rb +51 -0
- data/lib/scribo/action_controller_renderers.rb +71 -0
- data/lib/scribo/action_view_helpers.rb +17 -0
- data/lib/scribo/active_record_helpers.rb +11 -0
- data/lib/scribo/configuration.rb +97 -0
- data/lib/scribo/engine.rb +24 -0
- data/lib/scribo/i18n_store.rb +100 -0
- data/lib/scribo/liquid/filters/jekyll_filters.rb +94 -0
- data/lib/scribo/liquid/filters/markdownify.rb +11 -0
- data/lib/scribo/liquid/filters/url_filters.rb +76 -0
- data/lib/scribo/liquid/parser.rb +32 -0
- data/lib/scribo/liquid/tags/application_assets_tag.rb +14 -0
- data/lib/scribo/liquid/tags/application_js_tag.rb +16 -0
- data/lib/scribo/liquid/tags/asset_tag.rb +56 -0
- data/lib/scribo/liquid/tags/button_tag.rb +24 -0
- data/lib/scribo/liquid/tags/check_box_tag.rb +31 -0
- data/lib/scribo/liquid/tags/csrf_meta_tags_tag.rb +16 -0
- data/lib/scribo/liquid/tags/date_field_tag.rb +23 -0
- data/lib/scribo/liquid/tags/editable_url_tag.rb +19 -0
- data/lib/scribo/liquid/tags/email_field_tag.rb +23 -0
- data/lib/scribo/liquid/tags/feed_meta_tag.rb +22 -0
- data/lib/scribo/liquid/tags/field_error_tag.rb +26 -0
- data/lib/scribo/liquid/tags/fields_for_tag.rb +82 -0
- data/lib/scribo/liquid/tags/form_tag.rb +57 -0
- data/lib/scribo/liquid/tags/google_analytics_javascript_tag.rb +30 -0
- data/lib/scribo/liquid/tags/google_tag_manager_javascript_tag.rb +28 -0
- data/lib/scribo/liquid/tags/hidden_field_tag.rb +23 -0
- data/lib/scribo/liquid/tags/highlight_tag.rb +106 -0
- data/lib/scribo/liquid/tags/include_tag.rb +28 -0
- data/lib/scribo/liquid/tags/label_tag.rb +24 -0
- data/lib/scribo/liquid/tags/number_field_tag.rb +23 -0
- data/lib/scribo/liquid/tags/options_for_select.rb +36 -0
- data/lib/scribo/liquid/tags/password_field_tag.rb +23 -0
- data/lib/scribo/liquid/tags/search_field_tag.rb +23 -0
- data/lib/scribo/liquid/tags/search_tag.rb +29 -0
- data/lib/scribo/liquid/tags/select_tag.rb +22 -0
- data/lib/scribo/liquid/tags/seo_tag.rb +35 -0
- data/lib/scribo/liquid/tags/set_session.rb +19 -0
- data/lib/scribo/liquid/tags/telephone_field_tag.rb +23 -0
- data/lib/scribo/liquid/tags/text_field_tag.rb +35 -0
- data/lib/scribo/liquid/tags/textarea_tag.rb +28 -0
- data/lib/scribo/liquid/tags/time_field_tag.rb +23 -0
- data/lib/scribo/liquid/tags/url_field_tag.rb +23 -0
- data/lib/scribo/preamble.rb +89 -0
- data/lib/scribo/sassc/importer.rb +72 -0
- data/lib/scribo/utility.rb +94 -0
- data/lib/scribo/version.rb +5 -0
- data/lib/scribo.rb +59 -0
- data/lib/tasks/scribo_tasks.rake +28 -0
- metadata +498 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Markdownify
|
|
4
|
+
def markdownify(input)
|
|
5
|
+
# Easiest way at the moment
|
|
6
|
+
Scribo::ContentRenderService.new(Scribo::Content.new(kind: 'text', data: input), {}, layout: false,
|
|
7
|
+
filter: 'markdown').call
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Liquid::Template.register_filter(Markdownify)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module URLFilters
|
|
4
|
+
# Produces an absolute URL based on site.url and site.baseurl.
|
|
5
|
+
#
|
|
6
|
+
# input - the URL to make absolute.
|
|
7
|
+
#
|
|
8
|
+
# Returns the absolute URL as a String.
|
|
9
|
+
def absolute_url(input)
|
|
10
|
+
cache = (@context.registers[:cached_absolute_urls] ||= {})
|
|
11
|
+
cache[input] ||= compute_absolute_url(input)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Produces a URL relative to the domain root based on site.baseurl
|
|
15
|
+
# unless it is already an absolute url with an authority (host).
|
|
16
|
+
#
|
|
17
|
+
# input - the URL to make relative to the domain root
|
|
18
|
+
#
|
|
19
|
+
# Returns a URL relative to the domain root as a String.
|
|
20
|
+
def relative_url(input)
|
|
21
|
+
cache = (@context.registers[:cached_relative_urls] ||= {})
|
|
22
|
+
cache[input] ||= compute_relative_url(input)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Strips trailing `/index.html` from URLs to create pretty permalinks
|
|
26
|
+
#
|
|
27
|
+
# input - the URL with a possible `/index.html`
|
|
28
|
+
#
|
|
29
|
+
# Returns a URL with the trailing `/index.html` removed
|
|
30
|
+
def strip_index(input)
|
|
31
|
+
return if input.nil? || input.to_s.empty?
|
|
32
|
+
|
|
33
|
+
input.sub(%r[/index\.html?$], '/')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def compute_absolute_url(input)
|
|
39
|
+
return if input.nil?
|
|
40
|
+
|
|
41
|
+
input = input.url if input.respond_to?(:url)
|
|
42
|
+
return input if Addressable::URI.parse(input.to_s).absolute?
|
|
43
|
+
|
|
44
|
+
site = @context.registers['content'].site
|
|
45
|
+
return relative_url(input) if site.properties['url'].nil?
|
|
46
|
+
|
|
47
|
+
Addressable::URI.parse(
|
|
48
|
+
site.properties['url'].to_s + relative_url(input)
|
|
49
|
+
).normalize.to_s
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def compute_relative_url(input)
|
|
53
|
+
return if input.nil?
|
|
54
|
+
|
|
55
|
+
input = input.url if input.respond_to?(:url)
|
|
56
|
+
return input if Addressable::URI.parse(input.to_s).absolute?
|
|
57
|
+
|
|
58
|
+
parts = [sanitized_baseurl, input]
|
|
59
|
+
Addressable::URI.parse(
|
|
60
|
+
parts.compact.map { |part| ensure_leading_slash(part.to_s) }.join
|
|
61
|
+
).normalize.to_s
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def sanitized_baseurl
|
|
65
|
+
site = @context.registers['content'].site
|
|
66
|
+
site.properties['baseurl'].to_s.chomp('/')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def ensure_leading_slash(input)
|
|
70
|
+
return input if input.nil? || input.empty? || input.start_with?('/')
|
|
71
|
+
|
|
72
|
+
"/#{input}"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
Liquid::Template.register_filter(URLFilters)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'parslet'
|
|
2
|
+
|
|
3
|
+
module Scribo
|
|
4
|
+
class LiquidParser < Parslet::Parser
|
|
5
|
+
rule(:liquid) { (str('}}').absent? >> any).repeat }
|
|
6
|
+
|
|
7
|
+
rule(:space) { match('\s').repeat(1) }
|
|
8
|
+
rule(:space?) { space.maybe }
|
|
9
|
+
|
|
10
|
+
rule(:squote) { str("'").repeat(1) }
|
|
11
|
+
rule(:dquote) { str('"').repeat(1) }
|
|
12
|
+
|
|
13
|
+
rule(:pipe) { str('|').repeat(1) }
|
|
14
|
+
|
|
15
|
+
rule(:nsqvalue) { match["^'"] }
|
|
16
|
+
rule(:ndqvalue) { match['^"'] }
|
|
17
|
+
|
|
18
|
+
rule(:squoted_value) { squote >> nsqvalue.repeat.as(:value) >> squote }
|
|
19
|
+
rule(:dquoted_value) { dquote >> ndqvalue.repeat.as(:value) >> dquote }
|
|
20
|
+
rule(:quoted_value) { squoted_value | dquoted_value }
|
|
21
|
+
|
|
22
|
+
rule(:translation_key) { quoted_value >> space? >> pipe >> liquid.as(:filter) >> space? >> liquid }
|
|
23
|
+
|
|
24
|
+
rule(:liquid_code) { translation_key | liquid }
|
|
25
|
+
|
|
26
|
+
rule(:liquid_with_brackets) { str('{{') >> liquid_code >> str('}}') }
|
|
27
|
+
rule(:text) { (str('{{').absent? >> any).repeat(1) }
|
|
28
|
+
|
|
29
|
+
rule(:text_with_liquid) { (text | liquid_with_brackets).repeat }
|
|
30
|
+
root(:text_with_liquid)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# ApplicationAssets tag
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%application_assets%}
|
|
7
|
+
class ApplicationAssetsTag < LiquidumTag
|
|
8
|
+
def render(context)
|
|
9
|
+
super
|
|
10
|
+
lookup(context.registers, 'application_assets')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Liquid::Template.register_tag('application_assets', ApplicationAssetsTag)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# ApplicationAssets tag
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%application_js%}
|
|
7
|
+
class ApplicationJsTag < LiquidumTag
|
|
8
|
+
def render(context)
|
|
9
|
+
super
|
|
10
|
+
|
|
11
|
+
js = lookup(context.registers, 'application_js')
|
|
12
|
+
"<script>#{js}</script>" if js
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Liquid::Template.register_tag('application_js', ApplicationJsTag)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Add assets (by name) from the current Liquidum site
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%asset 'test.png'%}
|
|
7
|
+
#
|
|
8
|
+
# == Advanced usage:
|
|
9
|
+
# {%asset 'test.png' height="72px"%}
|
|
10
|
+
# {%asset 'test.png' style="height: 72px;"%}
|
|
11
|
+
#
|
|
12
|
+
# Note: It will only look at published assets
|
|
13
|
+
class AssetTag < LiquidumTag
|
|
14
|
+
include Rails.application.routes.url_helpers
|
|
15
|
+
|
|
16
|
+
def render(context)
|
|
17
|
+
super
|
|
18
|
+
|
|
19
|
+
current_content = context.registers['content']
|
|
20
|
+
|
|
21
|
+
content = current_content.site.contents.published.located(argv1, restricted: false).first
|
|
22
|
+
|
|
23
|
+
return "<!-- asset '#{argv1}' not found -->" unless content
|
|
24
|
+
|
|
25
|
+
full_path = content.full_path
|
|
26
|
+
if File.basename(full_path).include?('/_')
|
|
27
|
+
full_path = context.registers['controller'].helpers.scribo.content_path(content)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
case content&.media_type
|
|
31
|
+
when 'image'
|
|
32
|
+
%[<img] +
|
|
33
|
+
attr_str(:src, arg(:src), full_path) +
|
|
34
|
+
attr_str(:alt, content.properties['title'], content.properties['title']) +
|
|
35
|
+
attr_str(:title, content.properties['caption'], content.properties['caption']) +
|
|
36
|
+
attr_str(:width, arg(:width)) +
|
|
37
|
+
attr_str(:height, arg(:height)) +
|
|
38
|
+
attr_str(:style, arg(:style)) +
|
|
39
|
+
%[/>]
|
|
40
|
+
else
|
|
41
|
+
if content&.content_type == 'text/css'
|
|
42
|
+
%[<link rel="stylesheet" type="text/css"] +
|
|
43
|
+
attr_str(:href, arg(:href), full_path) +
|
|
44
|
+
%[/>]
|
|
45
|
+
elsif content&.content_type == 'application/javascript'
|
|
46
|
+
%[<script] +
|
|
47
|
+
attr_str(:src, arg(:src), full_path) +
|
|
48
|
+
%[/></script>]
|
|
49
|
+
else
|
|
50
|
+
"<!-- unknown asset: #{argv1} -->"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
Liquid::Template.register_tag('asset', AssetTag)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Adds a (by default submit) button
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%button name:'commit' value:'save'%}Save{%endbutton%}
|
|
7
|
+
#
|
|
8
|
+
# == Advanced usage:
|
|
9
|
+
# {%button button name:'commit' value:'save'%}Save{%endbutton%}
|
|
10
|
+
# {%button reset name:'commit' value:'save'%}Save{%endbutton%}
|
|
11
|
+
#
|
|
12
|
+
class ButtonTag < LiquidumBlock
|
|
13
|
+
def render(context)
|
|
14
|
+
super
|
|
15
|
+
|
|
16
|
+
%[<button] + attr_str(:type, argv1, 'submit') +
|
|
17
|
+
attr_str(:name, arg(:name), 'commit') +
|
|
18
|
+
attr_str(:value, arg(:value)) +
|
|
19
|
+
attr_str(:class, arg(:class)) +
|
|
20
|
+
%[>] + render_body + %[</button>]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
Liquid::Template.register_tag('button', ButtonTag)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Add a check-box, either specifying everything manually or using a model object on the form
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%check_box name:"name" value:"1"%}
|
|
7
|
+
#
|
|
8
|
+
# == Advanced usage:
|
|
9
|
+
# {%check_box name%}
|
|
10
|
+
#
|
|
11
|
+
# This last usage requires a model on the form
|
|
12
|
+
#
|
|
13
|
+
class CheckBoxTag < LiquidumTag
|
|
14
|
+
def render(context)
|
|
15
|
+
super
|
|
16
|
+
|
|
17
|
+
if @form_model
|
|
18
|
+
%[<input ] + attr_str(:name, arg(:name),
|
|
19
|
+
input(:name, argv1)) + %[value="0" type="hidden"/>]
|
|
20
|
+
else
|
|
21
|
+
|
|
22
|
+
%[<input ] + attr_str(:name, arg(:name), input(:name, argv1)) +
|
|
23
|
+
attr_str(:id, arg(:id), input(:id, argv1)) +
|
|
24
|
+
attr_str(:value, arg(:value), input(:value, argv1) ? 1 : 0) +
|
|
25
|
+
attr_str(:checked, arg(:checked), input(:checked, argv1)) +
|
|
26
|
+
attrs_str(:disabled, :maxlength, :placeholder, :class) + %[ type="checkbox"/>]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Liquid::Template.register_tag('check_box', CheckBoxTag)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Adds CSRF meta tags
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%csrf_meta_tags%}
|
|
7
|
+
#
|
|
8
|
+
class CsrfMetaTagsTag < LiquidumTag
|
|
9
|
+
def render(context)
|
|
10
|
+
super
|
|
11
|
+
|
|
12
|
+
context.registers['controller'].helpers.csrf_meta_tags
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Liquid::Template.register_tag('csrf_meta_tags', CsrfMetaTagsTag)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Add a date-field, either specifying everything manually or using a model object on the form
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%date_field name:"start_date" value:"2019-09-27"%}
|
|
7
|
+
#
|
|
8
|
+
# == Advanced usage:
|
|
9
|
+
# {%date_field start_date%}
|
|
10
|
+
#
|
|
11
|
+
# This last usage requires a model on the form
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
require_relative './text_field_tag'
|
|
15
|
+
|
|
16
|
+
class DateFieldTag < TextFieldTag
|
|
17
|
+
def initialize(tag, args, tokens)
|
|
18
|
+
super
|
|
19
|
+
@field_type = 'date'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Liquid::Template.register_tag('date_field', DateFieldTag)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Makes content available for editing, basically adds the right attributes
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# <div {%editable%} data-editable-id='fiets'></div>
|
|
7
|
+
#
|
|
8
|
+
class EditableUrlTag < LiquidumTag
|
|
9
|
+
def render(context)
|
|
10
|
+
super
|
|
11
|
+
|
|
12
|
+
content = context.registers['content']
|
|
13
|
+
|
|
14
|
+
# FIXME: Use url helpers
|
|
15
|
+
%[/scribo/sites/#{content.site.id}/contents/#{content.id}/parts]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
Liquid::Template.register_tag('editable_url', EditableUrlTag)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Add a email-field, either specifying everything manually or using a model object on the form
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%email_field name:"email" value:"1"%}
|
|
7
|
+
#
|
|
8
|
+
# == Advanced usage:
|
|
9
|
+
# {%email_field email%}
|
|
10
|
+
#
|
|
11
|
+
# This last usage requires a model on the form
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
require_relative './text_field_tag'
|
|
15
|
+
|
|
16
|
+
class EmailFieldTag < TextFieldTag
|
|
17
|
+
def initialize(tag, args, tokens)
|
|
18
|
+
super
|
|
19
|
+
@field_type = 'email'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Liquid::Template.register_tag('email_field', EmailFieldTag)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Adds Feed meta
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%feed_meta%}
|
|
7
|
+
#
|
|
8
|
+
class FeedMetaTag < LiquidumTag
|
|
9
|
+
def render(context)
|
|
10
|
+
super
|
|
11
|
+
|
|
12
|
+
content = context.registers['content']
|
|
13
|
+
site = content.site
|
|
14
|
+
request = context.registers['controller'].request
|
|
15
|
+
|
|
16
|
+
%[
|
|
17
|
+
<!-- Begin Scribo Feed Meta tag #{Scribo::VERSION} -->
|
|
18
|
+
]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
Liquid::Template.register_tag('feed_meta', FeedMetaTag)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Add errors for a specific form field, only works inside a form
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%field_error name%}
|
|
7
|
+
#
|
|
8
|
+
class FieldErrorTag < LiquidumTag
|
|
9
|
+
attr_accessor :field_type
|
|
10
|
+
|
|
11
|
+
def render(context)
|
|
12
|
+
super
|
|
13
|
+
|
|
14
|
+
error_messages = lookup(context, "form.errors.messages.#{argv1}")
|
|
15
|
+
|
|
16
|
+
if error_messages.present?
|
|
17
|
+
result = %[<span>] +
|
|
18
|
+
attr_str(:class, arg(:class), input(:class, argv1)) +
|
|
19
|
+
(error_messages || []).join(', ') + %[</span>]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
result
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Liquid::Template.register_tag('field_error', FieldErrorTag)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Exposes additional model objects, similar to form, but it doesn't create a form-tag.
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%fields_for location%}
|
|
7
|
+
# {%text_field city%}
|
|
8
|
+
# {%endform%}
|
|
9
|
+
#
|
|
10
|
+
# It will automatically build the association if need be. For polymorphic it needs a hint:
|
|
11
|
+
# {%fields_for scribable Domain%}
|
|
12
|
+
# {%text_field city%}
|
|
13
|
+
# {%endform%}
|
|
14
|
+
#
|
|
15
|
+
# == Available variables:
|
|
16
|
+
#
|
|
17
|
+
# form.model:: model specified
|
|
18
|
+
# form.class_name:: class name of the model specified (original name, not the drop)
|
|
19
|
+
# form.errors:: errors of the exposed object
|
|
20
|
+
#
|
|
21
|
+
# require_relative '../drops/form_drop'
|
|
22
|
+
|
|
23
|
+
class FieldsForTag < LiquidumBlock
|
|
24
|
+
def render(context)
|
|
25
|
+
super
|
|
26
|
+
|
|
27
|
+
result = ''
|
|
28
|
+
|
|
29
|
+
context.stack do
|
|
30
|
+
context['form'] = Scribo::FormDrop.new(new_model, argv1)
|
|
31
|
+
result += render_body
|
|
32
|
+
|
|
33
|
+
if context['form.model.id']
|
|
34
|
+
result += %[<input] +
|
|
35
|
+
attr_str(:id, arg(:id), input(:id, 'id')) +
|
|
36
|
+
attr_str(:name, arg(:name), input(:name, 'id')) +
|
|
37
|
+
attr_str(:value, arg(:value), input(:value, 'id')) +
|
|
38
|
+
%[type="hidden"/>]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
result
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def new_model
|
|
48
|
+
new_model = begin
|
|
49
|
+
@context["form.model.#{argv1}"]
|
|
50
|
+
rescue StandardError
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
unless new_model
|
|
54
|
+
|
|
55
|
+
association_name = (Regexp.last_match(0) if argv1.match(/([^\[\]])+/))
|
|
56
|
+
|
|
57
|
+
new_model = begin
|
|
58
|
+
reflection = real_object_from_drop(@context['form.model']).class.reflect_on_association(association_name)
|
|
59
|
+
if reflection.polymorphic?
|
|
60
|
+
# If it's polymorphic we need hints on what to do
|
|
61
|
+
sargs.first.to_s.safe_constantize.new(attr_args)
|
|
62
|
+
elsif reflection.is_a?(ActiveRecord::Reflection::HasManyReflection) && reflection.constructable?
|
|
63
|
+
# Do model.association.new
|
|
64
|
+
real_object_from_drop(@context['form.model']).send(association_name.to_sym).new(attr_args)
|
|
65
|
+
elsif reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) && reflection.constructable?
|
|
66
|
+
# Do model.build_association
|
|
67
|
+
real_object_from_drop(@context['form.model']).send("build_#{association_name}".to_sym, attr_args)
|
|
68
|
+
else
|
|
69
|
+
# Just call new on the class
|
|
70
|
+
reflection.klass.new(attr_args)
|
|
71
|
+
end
|
|
72
|
+
rescue ArgumentError
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
new_model
|
|
77
|
+
end
|
|
78
|
+
new_model
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
Liquid::Template.register_tag('fields_for', FieldsForTag)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Form adds a form tag, when you specify a model it will use and expose that to nested fields.
|
|
4
|
+
# Exposing a model will ease the creation of nested fields.
|
|
5
|
+
#
|
|
6
|
+
# == Basic usage:
|
|
7
|
+
# {%form%}
|
|
8
|
+
# {%text_field name:"name" value:"Pencil"%}
|
|
9
|
+
# {%endform%}
|
|
10
|
+
#
|
|
11
|
+
# == Advanced usage:
|
|
12
|
+
# {%form product%}
|
|
13
|
+
# {%text_field name%}
|
|
14
|
+
# {%endform%}
|
|
15
|
+
#
|
|
16
|
+
# == Available variables:
|
|
17
|
+
#
|
|
18
|
+
# form.model:: model specified
|
|
19
|
+
# form.class_name:: class name of the model specified (original name, not the drop)
|
|
20
|
+
# form.errors:: errors of the exposed object
|
|
21
|
+
#
|
|
22
|
+
# require_relative '../drops/form_drop'
|
|
23
|
+
|
|
24
|
+
class FormTag < LiquidumBlock
|
|
25
|
+
def render(context)
|
|
26
|
+
super
|
|
27
|
+
|
|
28
|
+
method = arg(:method).to_s.downcase
|
|
29
|
+
method = argv1.instance_variable_get('@object').persisted? ? 'patch' : 'post' if method.blank? && argv1
|
|
30
|
+
|
|
31
|
+
rails_method = nil
|
|
32
|
+
if %w[get post].exclude? method
|
|
33
|
+
rails_method = method
|
|
34
|
+
method = 'post'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
result = %[<form] +
|
|
38
|
+
attr_str(:action, arg(:action)) +
|
|
39
|
+
attr_str(:method, method) +
|
|
40
|
+
attrs_str(reject: %[action method]) +
|
|
41
|
+
%[>]
|
|
42
|
+
|
|
43
|
+
if context.registers['controller']
|
|
44
|
+
result += %[<input name="_method" type="hidden" value="#{rails_method}"/>] if rails_method
|
|
45
|
+
result += %[<input name="authenticity_token" type="hidden" value="#{context.registers['controller'].helpers.form_authenticity_token}"/>]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context.stack do
|
|
49
|
+
context['form'] = Scribo::FormDrop.new(argv1)
|
|
50
|
+
result += render_body
|
|
51
|
+
end
|
|
52
|
+
result += %[</form>]
|
|
53
|
+
result
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
Liquid::Template.register_tag('form', FormTag)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Adds a Google Analytics Javascript block
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%google_analytics_javascript 'UA-000000-01'%}
|
|
7
|
+
#
|
|
8
|
+
# == Advanced usage:
|
|
9
|
+
# {%google_analytics_javascript retailer.code%}
|
|
10
|
+
#
|
|
11
|
+
# Where 'UA-000000-01' is your analytics id
|
|
12
|
+
class GoogleAnalyticsJavascriptTag < LiquidumTag
|
|
13
|
+
def render(context)
|
|
14
|
+
super
|
|
15
|
+
|
|
16
|
+
return unless Rails.env == 'production'
|
|
17
|
+
return unless argv1
|
|
18
|
+
|
|
19
|
+
Scribo.config.logger.warn "Inserting google analytics with code: #{argv1}"
|
|
20
|
+
%(<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
21
|
+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
22
|
+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
23
|
+
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
24
|
+
|
|
25
|
+
ga('create', '#{argv1}', 'auto');
|
|
26
|
+
ga('send', 'pageview');</script>)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
Liquid::Template.register_tag('google_analytics_javascript', GoogleAnalyticsJavascriptTag)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Adds a Google Tag Manager Javascript block
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%google_tag_manager_javascript 'GTM-XXXXXXX'%}
|
|
7
|
+
#
|
|
8
|
+
# == Advanced usage:
|
|
9
|
+
# {%google_tag_manager_javascript retailer.code%}
|
|
10
|
+
#
|
|
11
|
+
# Where 'GTM-XXXXXXX' is your container id
|
|
12
|
+
class GoogleTagManagerJavascriptTag < LiquidumTag
|
|
13
|
+
def render(context)
|
|
14
|
+
super
|
|
15
|
+
|
|
16
|
+
return unless Rails.env == 'production'
|
|
17
|
+
return unless argv1
|
|
18
|
+
|
|
19
|
+
Scribo.config.logger.warn "Inserting google tag manager with code: #{argv1}"
|
|
20
|
+
%(<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
21
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
22
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
23
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
24
|
+
})(window,document,'script','dataLayer','#{argv1}');</script>)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Liquid::Template.register_tag('google_tag_manager_javascript', GoogleTagManagerJavascriptTag)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Add a text-field, either specifying everything manually or using a model object on the form
|
|
4
|
+
#
|
|
5
|
+
# == Basic usage:
|
|
6
|
+
# {%hidden_field name:"name" value:"Pencil"%}
|
|
7
|
+
#
|
|
8
|
+
# == Advanced usage:
|
|
9
|
+
# {%hidden_field name%}
|
|
10
|
+
#
|
|
11
|
+
# This last usage requires a model on the form
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
require_relative './text_field_tag'
|
|
15
|
+
|
|
16
|
+
class HiddenFieldTag < TextFieldTag
|
|
17
|
+
def initialize(tag, args, tokens)
|
|
18
|
+
super
|
|
19
|
+
@field_type = 'hidden'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Liquid::Template.register_tag('hidden_field', HiddenFieldTag)
|