trmnl-liquid 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 71c903fca7e32e8b95b094e74dc73fcda3321abb23304adb0ed0f2df2873a24c
4
+ data.tar.gz: d2da61eec30c53e924dce31ec7a8a021a531b7318738005f656f84a25568925e
5
+ SHA512:
6
+ metadata.gz: c97a0eefc2eb7cfba1438b3c862bf17709ec953228ac2ba96e273b0d4298d767a358c95ad4b62a986559fb4719dc4305c3670ffcd414ae7df5d75180b0b5a19e
7
+ data.tar.gz: 77f741d77b3cbeeae0c20e15124b5075c2d302b208f628152bfd2fedc2b702832e42775c7c741a7ae853280d92329548725e5a988dfada2baceae7741a063b5d
@@ -0,0 +1,108 @@
1
+ require 'action_view'
2
+ require 'date'
3
+ require 'redcarpet'
4
+ require 'tzinfo'
5
+
6
+ begin
7
+ require 'i18n'
8
+ rescue LoadError
9
+ nil
10
+ end
11
+
12
+ module TRMNL
13
+ module Liquid
14
+ module Filters
15
+ def append_random(var)
16
+ "#{var}#{SecureRandom.hex(2)}"
17
+ end
18
+
19
+ def days_ago(num, tz = 'Etc/UTC')
20
+ tzinfo = TZInfo::Timezone.get(tz)
21
+ tzinfo.now.to_date - num.to_i
22
+ end
23
+
24
+ def group_by(collection, key)
25
+ collection.group_by { |obj| obj[key] }
26
+ end
27
+
28
+ def find_by(collection, key, value, fallback = nil)
29
+ collection.find { |obj| obj[key] == value } || fallback
30
+ end
31
+
32
+ def markdown_to_html(markdown)
33
+ markdown ||= ''
34
+ renderer = Redcarpet::Render::HTML.new(_render_options = {})
35
+ service = Redcarpet::Markdown.new(renderer, _extensions = {})
36
+ service.render(markdown)
37
+ end
38
+
39
+ def number_with_delimiter(number, delimiter = ',', separator = ',')
40
+ helpers.number_with_delimiter(number, delimiter: delimiter, separator: separator)
41
+ end
42
+
43
+ def number_to_currency(number, unit_or_locale = '$', delimiter = ',', separator = '.')
44
+ cur_switcher = with_i18n(:unit) do |i18n|
45
+ i18n.available_locales.include?(unit_or_locale.to_sym) ? :locale : :unit
46
+ end
47
+ opts = { delimiter:, separator: }.merge(cur_switcher => unit_or_locale)
48
+ helpers.number_to_currency(number, **opts)
49
+ end
50
+
51
+ def l_word(word, locale)
52
+ with_i18n("custom_plugins.#{word}") do |i18n|
53
+ i18n.t("custom_plugins.#{word}", locale: locale)
54
+ end
55
+ end
56
+
57
+ def l_date(date, format, locale = 'en')
58
+ with_i18n(date.to_s) do |i18n|
59
+ format = format.to_sym unless format.include?('%')
60
+ i18n.l(to_datetime(date), format: format, locale: locale)
61
+ end
62
+ end
63
+
64
+ def pluralize(singular, count)
65
+ helpers.pluralize(count, singular)
66
+ end
67
+
68
+ def json(obj)
69
+ JSON.generate(obj)
70
+ end
71
+
72
+ def sample(array) = array.sample
73
+
74
+ private
75
+
76
+ def with_i18n(fallback, &block)
77
+ if defined?(::I18n)
78
+ block.call(::I18n)
79
+ else
80
+ fallback
81
+ end
82
+ end
83
+
84
+ def to_datetime(obj)
85
+ case obj
86
+ when DateTime
87
+ obj
88
+ when Date
89
+ obj.to_datetime
90
+ when Time
91
+ DateTime.parse(obj.iso8601)
92
+ else
93
+ DateTime.parse(obj.to_s)
94
+ end
95
+ end
96
+
97
+ def helpers
98
+ @helpers ||= begin
99
+ mod = Module.new do
100
+ include ::ActionView::Helpers::NumberHelper
101
+ include ::ActionView::Helpers::TextHelper
102
+ end
103
+ Object.new.extend(mod)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,23 @@
1
+ module TRMNL
2
+ module Liquid
3
+ class Template < ::Liquid::Template
4
+ # This in-memory "file system" is the backing storage for custom templates defined {% template [name] %} tags.
5
+ class FileSystem < ::Liquid::BlankFileSystem
6
+ def initialize
7
+ super
8
+ @templates = {}
9
+ end
10
+
11
+ # called by Markup::LiquidTemplateTag to save users' custom shared templates via our custom {% template %} tag
12
+ def register(name, body)
13
+ @templates[name] = body
14
+ end
15
+
16
+ # called by ::Liquid::Template for {% render 'foo' %} when rendering screen markup
17
+ def read_template_file(name)
18
+ @templates[name] || raise(::Liquid::FileSystemError, "Template not found: #{name}")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module TRMNL
2
+ module Liquid
3
+ class Template < ::Liquid::Template
4
+ # The {% template [name] %} tag block is used in conjunction with InlineTemplatesFileSystem to allow users to define
5
+ # custom templates within the context of the current Liquid template. Generally speaking, they will define their own
6
+ # templates in the "shared" markup content, which is prepended to the individual screen templates before rendering.
7
+ class TemplateTag < ::Liquid::Block
8
+ NAME_REGEX = %r{\A[a-zA-Z0-9_/]+\z}
9
+
10
+ def initialize(tag_name, markup, options)
11
+ super
12
+ @name = markup.strip
13
+ end
14
+
15
+ def parse(tokens)
16
+ @body = ""
17
+ while (token = tokens.shift)
18
+ break if token.strip == "{% endtemplate %}"
19
+
20
+ @body << token
21
+ end
22
+ end
23
+
24
+ def render(context)
25
+ unless @name =~ NAME_REGEX
26
+ return "Liquid error: invalid template name #{@name.inspect} - template names must contain only letters, numbers, underscores, and slashes"
27
+ end
28
+
29
+ context.registers[:file_system].register(@name, @body.strip)
30
+ ''
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require 'liquid'
2
+
3
+ require_relative 'template/file_system'
4
+ require_relative 'template/template_tag'
5
+
6
+ module TRMNL
7
+ module Liquid
8
+ # A very thin wrapper around Liquid::Template with TRMNL-specific functionality.
9
+ class Template < ::Liquid::Template
10
+ def self.parse(*)
11
+ template = super
12
+
13
+ # set up a temporary in-memory file system for custom user templates, via the magic :file_system register
14
+ # which will override the default file system
15
+ template.registers[:file_system] = FileSystem.new
16
+
17
+ template
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+
2
+ # frozen_string_literal: true
3
+ module TRMNL
4
+ module Liquid
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trmnl/liquid/filters'
4
+ require 'trmnl/liquid/template'
5
+ require 'trmnl/liquid/version'
6
+
7
+ begin
8
+ require 'trmnl/i18n'
9
+ rescue LoadError
10
+ nil
11
+ end
12
+
13
+ if defined?(::TRMNL::I18n)
14
+ ::TRMNL::I18n.load_locales
15
+ end
16
+
17
+ if Gem.loaded_specs['rails-i18n']
18
+ ::I18n.load_path += Pathname.new(Gem.loaded_specs['rails-i18n'].full_gem_path).join('rails', 'locale').glob('*.yml')
19
+ end
20
+
21
+ module TRMNL
22
+ module Liquid
23
+ # empty
24
+ end
25
+ end
26
+
27
+ ::Liquid::Template.register_filter(TRMNL::Liquid::Filters)
28
+ ::Liquid::Template.register_tag('template', TRMNL::Liquid::Template::TemplateTag)
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/trmnl/liquid/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "trmnl-liquid"
7
+ spec.version = TRMNL::Liquid::VERSION
8
+ spec.authors = ["TRMNL"]
9
+ spec.email = ["engineering@usetrmnl.com"]
10
+ spec.homepage = "https://github.com/usetrmnl/trmnl-liquid"
11
+
12
+ spec.summary = "Liquid templating engine for TRMNL plugins"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 3.2.0"
15
+
16
+ spec.metadata = {
17
+ "bug_tracker_uri" => "https://github.com/usetrmnl/trmnl-liquid/issues",
18
+ "changelog_uri" => "https://github.com/usetrmnl/trmnl-liquid/tags",
19
+ "homepage_uri" => "https://github.com/usetrmnl/trmnl-liquid",
20
+ "label" => "TRMNL Liquid",
21
+ "rubygems_mfa_required" => "true",
22
+ "source_code_uri" => "https://github.com/usetrmnl/trmnl-liquid"
23
+ }
24
+
25
+ # Specify which files should be added to the gem when it is released.
26
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
+ spec.files = Dir["*.gemspec", "lib/**/*"]
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "actionview", "~> 8.0"
31
+ spec.add_dependency "liquid", "~> 5.5"
32
+ spec.add_dependency "redcarpet", "~> 3.6"
33
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trmnl-liquid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - TRMNL
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-08-19 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: actionview
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '8.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '8.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: liquid
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.5'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '5.5'
40
+ - !ruby/object:Gem::Dependency
41
+ name: redcarpet
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.6'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.6'
54
+ email:
55
+ - engineering@usetrmnl.com
56
+ executables: []
57
+ extensions: []
58
+ extra_rdoc_files: []
59
+ files:
60
+ - lib/trmnl/liquid.rb
61
+ - lib/trmnl/liquid/filters.rb
62
+ - lib/trmnl/liquid/template.rb
63
+ - lib/trmnl/liquid/template/file_system.rb
64
+ - lib/trmnl/liquid/template/template_tag.rb
65
+ - lib/trmnl/liquid/version.rb
66
+ - trmnl-liquid.gemspec
67
+ homepage: https://github.com/usetrmnl/trmnl-liquid
68
+ licenses:
69
+ - MIT
70
+ metadata:
71
+ bug_tracker_uri: https://github.com/usetrmnl/trmnl-liquid/issues
72
+ changelog_uri: https://github.com/usetrmnl/trmnl-liquid/tags
73
+ homepage_uri: https://github.com/usetrmnl/trmnl-liquid
74
+ label: TRMNL Liquid
75
+ rubygems_mfa_required: 'true'
76
+ source_code_uri: https://github.com/usetrmnl/trmnl-liquid
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 3.2.0
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubygems_version: 3.6.2
92
+ specification_version: 4
93
+ summary: Liquid templating engine for TRMNL plugins
94
+ test_files: []