rblade 1.0.5 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7334cbd159959066834b8d7407b4b8e0eb8af1aa57501fd3a3ea352b1a043058
4
- data.tar.gz: 104b6b0f7abbf9aee1f35c6ca74ffedc0c771b5d0cfe32796e593ddc55730828
3
+ metadata.gz: edaa1af6299a8281520a73611def0838ef1017f2ec7bb3fd8a125bcd02e5c7ce
4
+ data.tar.gz: 6363e44a009a29e8771c50ecf4768b0d365b0d2147ba998db72805e9b05c0390
5
5
  SHA512:
6
- metadata.gz: a9956d9b662c3bf264bdd9228087fdaf72ff51972427ae21eb1d33c10358fefcf4e0fcd1a8aa362a6df237d3cee51a3bf8d1831750b0b9e55f6e20709dcefb85
7
- data.tar.gz: 6de71435e6f099b719b907ab9157eb117a6cd8cfd8c6854b657e533525e67d97b5e66b40ccb0aa97c91cc25fd3340897b0db75971383868e4eeaefd21ae3f44a
6
+ metadata.gz: 996e77805b56530e9f136c087753938c10c8dc71d45b1fbaec10e81e890878b9a0da00a10fa024a650cb2e463e155fe8da723fb16a6eb690f5811915ce4fe879
7
+ data.tar.gz: 5bbe562c01ec5fb12e77cb53aa2991cebfd83792dd831a41957497e3b04e29df442511c890d48fcb05bef78107cf5347019c49c7c8dc9e5d3f9ef0557a63f940
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  storage
2
2
  Gemfile.lock
3
+ *.gem
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.1.0 [2024-08-23]
2
+ - Add `@eachWithIndex` directive
3
+ - Fix attribute manager output of attributes with no value (#10)
4
+
1
5
  ## 1.0.5 [2024-08-14]
2
6
  - Allow use of variables in @method directive
3
7
 
data/README.md CHANGED
@@ -222,6 +222,16 @@ In addition to conditional statements, RBlade provides simple directives for wor
222
222
  <p>This is user {{ user.id }}</p>
223
223
  @endEach
224
224
 
225
+ {{-- Compiles to users.each_with_index do |user, index| ... --}}
226
+ @eachWithIndex (user, index in users)
227
+ <p>This is user {{ index }} {{ user.name }}</p>
228
+ @endEachWithIndex
229
+
230
+ {{-- eachWithIndex has a special case for Hashes: in this example, the result is "Item 1: a A" --}}
231
+ @eachWithIndex (key, value, index in {a: 'A'})
232
+ Item #{{ index + 1 }}: {{ key }} {{ value }}
233
+ @endEachWithIndex
234
+
225
235
  @forElse (name in [])
226
236
  <li>{{ name }}</li>
227
237
  @empty
@@ -234,6 +244,12 @@ In addition to conditional statements, RBlade provides simple directives for wor
234
244
  <p>No users</p>
235
245
  @endEachElse
236
246
 
247
+ @eachWithIndexElse (user, index in users)
248
+ <li>{{ index }}: {{ user.name }}</li>
249
+ @empty
250
+ <p>No users</p>
251
+ @endEachWithIndexElse
252
+
237
253
  @while (true)
238
254
  <p>I'm looping forever.</p>
239
255
  @endWhile
data/REFERENCE.md CHANGED
@@ -36,6 +36,7 @@ By default, RBlade will look for components in the `app/views/components` folder
36
36
  | `<x-name><x-slot::header><h1>Header</h1><//>Content<//>` | Pass a named block to a component |
37
37
  | `{{ header }}` | Output the contents of a named block |
38
38
  | `<div {{ header.attributes }}>` | Output the attributes passed into a named block |
39
+ | `@shouldRender(RUBY_EXPRESSION)` | Only renders the component if RUBY_EXPRESSION evaluates to true |
39
40
 
40
41
  <a name="quick-reference-attributes"></a>
41
42
  ## Attributes
@@ -75,19 +76,22 @@ The attributes variable is an instance of a class that manages attributes. As we
75
76
  <a name="quick-reference-loops"></a>
76
77
  ## Loops
77
78
 
78
- | Syntax | Description |
79
- |:------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------|
80
- | `@while( looping ) ... @endWhile` | Compiles to a Ruby while statement |
81
- | `@until( finished ) ... @endUntil` | Compiles to a Ruby until statement |
82
- | `@for( i in 1..10 ) ... @endFor` | Compiles to a Ruby for loop |
83
- | `@each( i in 1..10 ) ... @endEach` | Calls `each` on the given collection, with `\|i\|` as the block argument |
84
- | `@each( key, value in {a: 1} ) ... @endEach` | Calls `each` on the given Hash, with `\|key, value\|` as the block arguments |
85
- | `@forElse( i in 1..10 ) ... @empty ... @endForElse` | Compiles to a for loop as above, but the block after `@empty` is printed if the given collection is empty |
86
- | `@eachElse( i in 1..10 ) ... @empty ... @endEachElse` | Compiles to a each loop as above, but the block after `@empty` is printed if the given collection is empty |
87
- | `@break` | Break out of the current loop |
88
- | `@next` | Go to the next iteration in the current loop |
89
- | `@break( RUBY_EXPRESSION )` | Break out of the current loop if the expression evaluate to true |
90
- | `@next( RUBY_EXPRESSION )` | Go to the next iteration in the current loop if the expression evaluate to true |
79
+ | Syntax | Description |
80
+ |:-----------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------|
81
+ | `@while( looping ) ... @endWhile` | Compiles to a Ruby while statement |
82
+ | `@until( finished ) ... @endUntil` | Compiles to a Ruby until statement |
83
+ | `@for( i in 1..10 ) ... @endFor` | Compiles to a Ruby for loop |
84
+ | `@each( i in 1..10 ) ... @endEach` | Calls `each` on the given collection, with `\|i\|` as the block argument |
85
+ | `@each( key, value in {a: 1} ) ... @endEach` | Calls `each` on the given Hash, with `\|key, value\|` as the block arguments |
86
+ | `@eachWithIndex( value, index in ['a', 'b'] ) ... @endEachWithIndex` | Calls `each_with_index` on the given Array, with `\|value, index\|` as the block arguments |
87
+ | `@eachWithIndex( key, value, index in {a: 1} ) ... @endEachWithIndex` | Calls `each_with_index` on the given Hash, where `key` is the Hash key, `value` is the Hash value, and `index` is the index |
88
+ | `@forElse( i in 1..10 ) ... @empty ... @endForElse` | Compiles to a for loop as above, but the block after `@empty` is printed if the given collection is empty |
89
+ | `@eachElse( i in 1..10 ) ... @empty ... @endEachElse` | Compiles to a each loop as above, but the block after `@empty` is printed if the given collection is empty |
90
+ | `@eachWithIndexElse( value, index in 1..10 ) ... @empty ... @endEachWithIndexElse` | Compiles to a each_with_index loop as above, but the block after `@empty` is printed if the given collection is empty |
91
+ | `@break` | Break out of the current loop |
92
+ | `@next` | Go to the next iteration in the current loop |
93
+ | `@break( RUBY_EXPRESSION )` | Break out of the current loop if the expression evaluate to true |
94
+ | `@next( RUBY_EXPRESSION )` | Go to the next iteration in the current loop if the expression evaluate to true |
91
95
 
92
96
  <a name="quick-reference-forms"></a>
93
97
  ## Forms
@@ -81,6 +81,8 @@ module RBlade
81
81
  "elsif" => [CompilesConditionals, :compileElsif],
82
82
  "each" => [CompilesLoops, :compileEach],
83
83
  "eachelse" => [CompilesLoops, :compileEachElse],
84
+ "eachwithindex" => [CompilesLoops, :compileEachWithIndex],
85
+ "eachwithindexelse" => [CompilesLoops, :compileEachWithIndexElse],
84
86
  "empty" => [CompilesLoops, :compileEmpty],
85
87
  "empty?" => [CompilesConditionals, :compileEmpty],
86
88
  "end" => [CompilesStatements, :compileEnd],
@@ -19,27 +19,74 @@ module RBlade
19
19
 
20
20
  def compileEach args
21
21
  if args.nil? || args.count > 2
22
- raise StandardError.new "Each statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
22
+ raise StandardError.new "Each statement: wrong number of arguments (given #{args&.count || 0}, expecting 1 or 2)"
23
23
  end
24
- # Allow variables to be a key, value pair
25
- args = args.join ","
24
+ last_arg, collection = args.pop.split(" in ")
25
+ args.push(last_arg)
26
26
 
27
- variables, collection = args.split(" in ")
27
+ if collection.nil?
28
+ raise StandardError.new "Each statement: collection not found (expecting 'in')"
29
+ end
28
30
 
29
- "#{collection}.each do |#{variables}|;"
31
+ "#{collection}.each do |#{args.join(",")}|;"
32
+ end
33
+
34
+ def compileEachWithIndex args
35
+ if args.nil? || args.count > 3
36
+ raise StandardError.new "Each with index statement: wrong number of arguments (given #{args&.count || 0}, expecting 1 to 3)"
37
+ end
38
+ last_arg, collection = args.pop.split(" in ")
39
+ args.push(last_arg)
40
+
41
+ if collection.nil?
42
+ raise StandardError.new "Each with index statement: collection not found (expecting 'in')"
43
+ end
44
+
45
+ # Special case for 3 arguments: the first 2 arguments are the key/value pair in a Hash, and
46
+ # the third is the index
47
+ if args.count == 3
48
+ "#{collection}.each_with_index do |_ivar,#{args[2]}|;#{args[0]},#{args[1]}=_ivar;"
49
+ else
50
+ "#{collection}.each_with_index do |#{args.join(",")}|;"
51
+ end
30
52
  end
31
53
 
32
54
  def compileEachElse args
33
55
  if args.nil? || args.count > 2
34
56
  raise StandardError.new "Each else statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
35
57
  end
36
- # Allow variables to be a key, value pair
37
- args = args.join ","
58
+ last_arg, collection = args.pop.split(" in ")
59
+ args.push(last_arg)
60
+
61
+ if collection.nil?
62
+ raise StandardError.new "Each else statement: collection not found (expecting 'in')"
63
+ end
64
+
38
65
  @loop_else_counter += 1
39
66
 
40
- variables, collection = args.split(" in ")
67
+ "_looped_#{@loop_else_counter}=false;#{collection}.each do |#{args.join(",")}|;_looped_#{@loop_else_counter}=true;"
68
+ end
69
+
70
+ def compileEachWithIndexElse args
71
+ if args.nil? || args.count > 3
72
+ raise StandardError.new "Each with index statement: wrong number of arguments (given #{args&.count || 0}, expecting 1 to 3)"
73
+ end
74
+ last_arg, collection = args.pop.split(" in ")
75
+ args.push(last_arg)
76
+
77
+ if collection.nil?
78
+ raise StandardError.new "Each with index statement: collection not found (expecting 'in')"
79
+ end
80
+
81
+ @loop_else_counter += 1
41
82
 
42
- "_looped_#{@loop_else_counter}=false;#{collection}.each do |#{variables}|;_looped_#{@loop_else_counter}=true;"
83
+ # Special case for 3 arguments: the first 2 arguments are the key/value pair in a Hash, and
84
+ # the third is the index
85
+ if args.count == 3
86
+ "_looped_#{@loop_else_counter}=false;#{collection}.each_with_index do |_ivar,#{args[2]}|;#{args[0]},#{args[1]}=_ivar;_looped_#{@loop_else_counter}=true;"
87
+ else
88
+ "_looped_#{@loop_else_counter}=false;#{collection}.each_with_index do |#{args.join(",")}|;_looped_#{@loop_else_counter}=true;"
89
+ end
43
90
  end
44
91
 
45
92
  def compileFor args
@@ -37,7 +37,7 @@ module RBlade
37
37
  attributes ||= @attributes
38
38
 
39
39
  attributes.map do |key, value|
40
- "#{key}=\"#{(value == true) ? key : h(value)}\""
40
+ (value == true) ? key : "#{key}=\"#{h(value)}\""
41
41
  end.join " "
42
42
  end
43
43
 
data/rblade.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rblade"
3
- s.version = "1.0.5"
3
+ s.version = "1.1.0"
4
4
  s.summary = "A component-first templating engine for Rails"
5
5
  s.description = "RBlade is a simple, yet powerful templating engine for Ruby on Rails, inspired by Laravel Blade."
6
6
  s.authors = ["Simon J"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rblade
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon J
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-14 00:00:00.000000000 Z
11
+ date: 2024-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
142
  requirements: []
143
- rubygems_version: 3.0.3.1
143
+ rubygems_version: 3.3.5
144
144
  signing_key:
145
145
  specification_version: 4
146
146
  summary: A component-first templating engine for Rails