twig_ruby 0.0.3 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de30e1d0f458a7c5e2683f725036d8cf37e0fd09238bf14b7921d17af9f08998
4
- data.tar.gz: bfdc53936b6dc8449c44269e5bb0b717c01e02597911266404550a805cbb34b8
3
+ metadata.gz: 4e727b10dc2226c2da43a9a2b8e1cd4a2e1b5a18ffb16eca116611b0d0f307cf
4
+ data.tar.gz: ef48d56a8bef43bd999cd17dc3def1371b58c12e4fba6c6bb143ba8b21dba6c4
5
5
  SHA512:
6
- metadata.gz: 6554b109c0e00241e6a5dac0dfd4f8c36e78b50dcc45edff041ff9907cf02609d2abd4b5cdc326ca1ee92b12217ed83a8ba420c60afc65f790bb34567fbc9af9
7
- data.tar.gz: 70bf08c22925adf25f6b469bc7afcad62bdd3b4ed45761dbca3cd4619b1a213dcf2a3d70c1595ae7958354b2527fde438b78763c72238281971dc35c2aeaba71
6
+ metadata.gz: 1cbec5dd395ca0c306ab6eee643aa5954e46cd3181985e55fac994a2eecbdc4473aaba91a344e9681ad1aa28be3e77980461da775a740e908ec2dbb2fdbf73dc
7
+ data.tar.gz: fa32c024631b8cb528fb35463422b09e8b461ed75c1ef440bc4ccd8268686d928bcad868a82b9f98d5621a1e99047b2c4949589d7d967de23bcdf4ebe2b192ad
data/README.md CHANGED
@@ -2,11 +2,105 @@
2
2
 
3
3
  Implementation of [Twig](https://twig.symfony.com/) in Ruby.
4
4
 
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Quick Start](#quick-start)
9
+ - [Template Features](#template-features)
10
+ - [Filters](#filters)
11
+ - [Functions](#functions)
12
+ - [Tests](#tests)
13
+ - [Tags](#tags)
14
+ - [Rails Integration](#rails-integration)
15
+ - [Advanced Features](#advanced-features)
16
+ - [Configuration](#configuration)
17
+ - Advanced Docs
18
+ - [Loaders](doc/loaders.md)
19
+ - [Extensions](doc/extensions.md)
20
+
21
+ ## Installation
22
+
5
23
  ```bash
6
- bundle add twig-ruby
24
+ bundle add twig_ruby
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ Here's a simple example to get you started:
30
+
31
+ ```ruby
32
+ require 'twig_ruby'
33
+
34
+ # Create a loader with your templates
35
+ loader = Twig::Loader::Hash.new({
36
+ 'hello.twig' => 'Hello {{ name }}!'
37
+ })
38
+
39
+ # Create environment and render
40
+ environment = Twig::Environment.new(loader)
41
+ template = environment.load('hello.twig')
42
+ puts template.render({ name: "World" })
43
+ # Output: Hello World!
44
+ ```
45
+
46
+ Or from your file system:
47
+
48
+ ```ruby
49
+ loader = Twig::Loader::Filesystem.new(__dir__, ['app/views'])
50
+ ```
51
+
52
+ ## Template Features
53
+
54
+ Twig has the notion of Filters, Functions, and Tests
55
+
56
+ ### Filters
57
+
58
+ Filters are used to modify variables.
59
+
60
+ ```twig
61
+ {{ "hello"|capitalize }} {# Hello #}
62
+ {{ ["Hello", "World"]|join(" ") }} {# Hello World #}
63
+ ```
64
+
65
+ ### Functions
66
+
67
+ Functions are used to generate content.
68
+
69
+ ```twig
70
+ {{ max([1, 2, 3]) }} {# 3 #}
71
+ {{ include("other.twig") }} {# contents of other.twig #}
7
72
  ```
8
73
 
9
- ## Rails
74
+ ### Tests
75
+
76
+ Tests are used to evaluate variables.
77
+
78
+ ```twig
79
+ {{ 2 is even ? 'yup' : 'nope' }} {# yup #}
80
+ {{ ([1, 2, 3] has some n => n % 2 == 0) ? 'yup' : 'nope' }} {# yup #}
81
+ ```
82
+
83
+ ### Tags
84
+
85
+ Tags are used to control the logic of the template.
86
+
87
+ ```twig
88
+ {% if n > 1 %}
89
+ Some
90
+ {% else %}
91
+ None
92
+ {% endif %}
93
+ ```
94
+
95
+ ```twig
96
+ <ul>
97
+ {% for i in [1, 2, 3] %}
98
+ <li>Item {{ i }}</li>
99
+ {% endfor %}
100
+ </ul>
101
+ ```
102
+
103
+ ## Rails Integration
10
104
 
11
105
  This gem includes a Railtie that will automatically add your views folder and
12
106
  register a `:twig` template handler. Just simply create your views such as
@@ -22,7 +116,14 @@ register a `:twig` template handler. Just simply create your views such as
22
116
  {% endblock %}
23
117
  ```
24
118
 
25
- You should add `layout false` in your `ApplicationController`
119
+ Since Twig supports layouts through template inheritance (which is more flexible than Rails layouts),
120
+ you'll typically want to use Twig's inheritance system instead of Rails layouts. This allows you to:
121
+
122
+ 1. Create a base template with common structure
123
+ 2. Override specific blocks in child templates
124
+ 3. Nest layouts for more complex page structures
125
+
126
+ To use Twig's inheritance instead of Rails layouts, disable Rails layouts in your controller:
26
127
 
27
128
  ```ruby
28
129
  class ApplicationController < ActionController::Base
@@ -30,20 +131,21 @@ class ApplicationController < ActionController::Base
30
131
  end
31
132
  ```
32
133
 
33
- ## Rails Configuration
134
+ ## Configuration
34
135
 
35
136
  These are all the defaults. You only need this configuration if you plan to change anything.
36
137
 
37
138
  ```ruby
38
139
  Rails.application.configure do
39
- config.twig.root = ::Rails.root, # Used for default Filesystem Loader
40
- config.twig.paths = %w[/ app/views/], # Used for default Filesystem Loader
41
- config.twig.debug = ::Rails.env.development?,
42
- config.twig.allow_helper_methods = true,
43
- config.twig.cache = ::Rails.root.join('tmp/cache/twig').to_s,
44
- config.twig.charset = 'UTF-8',
45
- config.twig.strict_variables = true,
46
- config.twig.auto_reload = nil,
140
+ config.twig.root = ::Rails.root # Used for default Filesystem Loader
141
+ config.twig.paths = %w[/ app/views/] # Used for default Filesystem Loader
142
+ config.twig.debug = ::Rails.env.development?
143
+ config.twig.allow_helper_methods = true
144
+ config.twig.cache = ::Rails.root.join('tmp/cache/twig').to_s
145
+ config.twig.charset = 'UTF-8'
146
+ config.twig.strict_variables = true
147
+ config.twig.autoescape = :name
148
+ config.twig.auto_reload = nil
47
149
  config.twig.loader = lambda do
48
150
  ::Twig::Loader::Filesystem.new(
49
151
  current.root,
@@ -66,7 +168,7 @@ end
66
168
  If you plan to create your own loader that loads templates from another source like the database, you can provide
67
169
  a different lamba in the config for initializing it.
68
170
 
69
- ## Additions
171
+ ## Advanced Features
70
172
 
71
173
  Twig Ruby supports symbols as Ruby does and can be used in places strings can as
72
174
  hash keys, arguments, etc.
@@ -85,6 +187,14 @@ can be used with helpers like `form_with`
85
187
  {{ f.email_field(:email) }}
86
188
  {% endyield %}
87
189
  ```
190
+
191
+ Rails helpers can also be called. Parenthesis is only required when passing arguments:
192
+
193
+ ```twig
194
+ {{ stylesheet_link_tag(:app, "data-turbo-track": "reload") }}
195
+ {{ javascript_importmap_tags }}
196
+ ```
197
+
88
198
  ### Cache Tag
89
199
 
90
200
  The way the `cache` tag works in Rails is that it captures output from the buffer that
@@ -96,7 +206,7 @@ Using `{% yield cache() do %}` WILL NOT WORK CORRECTLY.
96
206
  ```twig
97
207
  {% cache(product) %}
98
208
  ...
99
- {% endyield %}
209
+ {% endcache %}
100
210
  ```
101
211
 
102
212
  Macros can also use Ruby notation for default values:
@@ -150,7 +150,7 @@ class TwigFixture
150
150
  replace(template, replacements[:fixture]) + (' ' * index)
151
151
  end
152
152
 
153
- loader = ::Twig::Loader::Array.new(gsub_templates)
153
+ loader = ::Twig::Loader::Hash.new(gsub_templates)
154
154
  environment = ::Twig::Environment.new(loader, {
155
155
  cache: false,
156
156
  strict_variables: true,
@@ -137,7 +137,7 @@ module Twig
137
137
  end
138
138
 
139
139
  chain_loader = Loader::Chain.new([
140
- Loader::Array.new({ name => template }),
140
+ Loader::Hash.new({ name => template }),
141
141
  current = loader,
142
142
  ])
143
143
 
@@ -997,7 +997,7 @@ module Twig
997
997
  (object.respond_to?(:empty?) && object.empty?) ||
998
998
  (object.respond_to?(:length) && (object.length&.== 0)) || # rubocop:disable Style/ZeroLengthPredicate
999
999
  (object.respond_to?(:size) && (object.size&.== 0)) || # rubocop:disable Style/ZeroLengthPredicate
1000
- (object.respond_to?(:to_s) && (object.to_s&.== ''))
1000
+ (object.respond_to?(:to_s) && (object.to_s == ''))
1001
1001
  end
1002
1002
 
1003
1003
  # @param [Environment] environment
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Twig
4
4
  module Loader
5
- class Array < Loader::Base
5
+ class Hash < Loader::Base
6
6
  # @param [Hash<String>] templates
7
7
  def initialize(templates)
8
8
  super()
@@ -30,13 +30,8 @@ module Twig
30
30
 
31
31
  compiler.add_debug_info(self)
32
32
 
33
- if attributes[:name][0] == '@'
34
- check = "context.call_context.instance_variable_defined?('#{name}')"
35
- get = "context.call_context.instance_variable_get('#{name}')"
36
- else
37
- check = "context.key?(:#{name})"
38
- get = "context[:#{name}]"
39
- end
33
+ check = "context.has?(:#{name})"
34
+ get = "context.get(:#{name})"
40
35
 
41
36
  if define_test_enabled?
42
37
  if attributes[:always_defined] || SPECIAL_VARS.key?(name)
@@ -52,6 +52,24 @@ module Twig
52
52
  self.class.new(other, call_context:, output_buffer:)
53
53
  end
54
54
 
55
+ def has?(name)
56
+ if name[0] == '@'
57
+ call_context.instance_variable_defined?(name)
58
+ else
59
+ key?(name) || call_context.respond_to?(name)
60
+ end
61
+ end
62
+
63
+ def get(name)
64
+ if name[0] == '@'
65
+ call_context.instance_variable_get(name)
66
+ elsif key?(name)
67
+ self[name]
68
+ elsif call_context.respond_to?(name)
69
+ call_context.send(name)
70
+ end
71
+ end
72
+
55
73
  def push_stack
56
74
  stack.push({ remove: [], replace: {} })
57
75
  end
@@ -27,6 +27,16 @@ module Twig
27
27
  body = parser.subparse(method(:decide_yield_end), drop_needle: true)
28
28
  stream.expect(Token::BLOCK_END_TYPE)
29
29
 
30
+ # If it's a context variable, turn it into a helper method
31
+ # ex: {% yield turbo_frame_tag do %}
32
+ if expr.is_a?(Node::Expression::Variable::Context)
33
+ expr = Node::Expression::HelperMethod.new(
34
+ expr.attributes[:name],
35
+ Node::Nodes.new({}),
36
+ lineno
37
+ )
38
+ end
39
+
30
40
  Node::Yield.new(expr, body, arguments, lineno)
31
41
  end
32
42
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twig_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Craig Blanchette
8
8
  - Fabian Potencier
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-23 00:00:00.000000000 Z
11
+ date: 2025-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -84,10 +84,10 @@ files:
84
84
  - lib/twig/extension_set.rb
85
85
  - lib/twig/file_extension_escaping_strategy.rb
86
86
  - lib/twig/lexer.rb
87
- - lib/twig/loader/array.rb
88
87
  - lib/twig/loader/base.rb
89
88
  - lib/twig/loader/chain.rb
90
89
  - lib/twig/loader/filesystem.rb
90
+ - lib/twig/loader/hash.rb
91
91
  - lib/twig/node/auto_escape.rb
92
92
  - lib/twig/node/base.rb
93
93
  - lib/twig/node/block.rb
@@ -220,7 +220,7 @@ files:
220
220
  - lib/twig_ruby.rb
221
221
  homepage: https://rubygems.org/gems/twig-ruby
222
222
  licenses:
223
- - MIT
223
+ - BSD-3-Clause
224
224
  metadata:
225
225
  allowed_push_host: https://rubygems.org
226
226
  rubygems_mfa_required: 'true'