rblade 0.6.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/README.md +94 -62
- data/REFERENCE.md +138 -0
- data/examples/README.md +3 -0
- data/examples/application/home.rblade +23 -0
- data/examples/components/content/alert.rblade +6 -0
- data/examples/components/content/hero.rblade +14 -0
- data/examples/components/h1.rblade +6 -0
- data/examples/components/p.rblade +14 -0
- data/examples/layouts/app.rblade +16 -0
- data/lib/rblade/compiler/compiles_components.rb +2 -2
- data/lib/rblade/compiler/{compiles_echos.rb → compiles_prints.rb} +11 -10
- data/lib/rblade/compiler/compiles_statements.rb +3 -4
- data/lib/rblade/compiler/statements/{compiles_props.rb → compiles_component_helpers.rb} +29 -10
- data/lib/rblade/compiler/statements/compiles_conditionals.rb +5 -13
- data/lib/rblade/compiler/statements/compiles_form.rb +13 -13
- data/lib/rblade/compiler/statements/compiles_loops.rb +8 -4
- data/lib/rblade/compiler/statements/compiles_once.rb +6 -6
- data/lib/rblade/compiler/statements/compiles_stacks.rb +10 -10
- data/lib/rblade/compiler/tokenizes_statements.rb +1 -1
- data/lib/rblade/compiler.rb +3 -3
- data/lib/rblade/helpers/attributes_manager.rb +7 -11
- data/lib/rblade/helpers/slot_manager.rb +5 -2
- data/rblade.gemspec +1 -1
- metadata +12 -4
data/REFERENCE.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
<a name="quick-reference"></a>
|
2
|
+
# Quick Reference
|
3
|
+
|
4
|
+
A table below provides a quick overview of RBlade syntax and directives. The [readme](README.md) has a more in depth look at RBlade's capabilities.
|
5
|
+
|
6
|
+
| Syntax | Description |
|
7
|
+
|:--------------------------------------------------------|:------------------------------------------------------------------------------------------|
|
8
|
+
| `{{ RUBY_EXPRESSION }}`<br/>`<%= RUBY_EXPRESSION %>` | Print the string value of the ruby expression, escaping HTML special characters |
|
9
|
+
| `{!! RUBY_EXPRESSION !!}`<br/>`<%== RUBY_EXPRESSION %>` | Print the string value of the ruby expression, _without_ escaping HTML special characters |
|
10
|
+
| `@ruby( RUBY_EXPRESSION )` | Execute an inline ruby expression |
|
11
|
+
| `@ruby ... @endRuby` | Execute a block of ruby code |
|
12
|
+
| `{{-- ... --}}`<br/>`<%# ... %>` | Comments, removed from the compiled template with no performance cost |
|
13
|
+
| `@verbatim ... @endVerbatim` | Print the given content without parsing RBlade directives |
|
14
|
+
|
15
|
+
<a name="quick-reference-components"></a>
|
16
|
+
## Components
|
17
|
+
|
18
|
+
By default, RBlade will look for components in the `app/views/components` folder. Additionally, components in the `layout` namespace are found in the `app/views/layouts` folder, and components in the `view` namespace are found in the `app/views` folder.
|
19
|
+
|
20
|
+
| Syntax | Description |
|
21
|
+
|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------|
|
22
|
+
| `<x-component.name/>` | Render the component found at `app/views/components/name{.rblade,.html.rblade}` or `app/views/components/name/index{.rblade,.html.rblade}` |
|
23
|
+
| `<x-layout::name/>` | Render the "name" component found in the "layout" namespace folder |
|
24
|
+
| `<x-component.name>...</x-component.name>` | Render the component with the given slot content |
|
25
|
+
| `<x-component.name>...<//>` | Short closing tag syntax (note: this bypasses some sanity checking during compilation) |
|
26
|
+
| `<x-name attribute="STRING"/>` | Pass a string value to a component |
|
27
|
+
| `<x-name :attribute="RUBY_EXPRESSION"/>` | Pass a ruby expression, executed in the local scope, to a component |
|
28
|
+
| `<x-name :attribute/>` | Pass the `attribute` local variable into a component |
|
29
|
+
| `<x-name @class({'bg-red-600': is_error})/>` | Conditionally pass classes to a component |
|
30
|
+
| `<x-name @style({'bg-red-600': is_error})/>` | Conditionally pass styles to a component |
|
31
|
+
| `<x-name attribute/>` | Pass an attribute to a component with value `true` |
|
32
|
+
| `<x-name {{ attributes }}/>` | Pass attributes to a child component |
|
33
|
+
| `@props({header: "Header"})` | Remove `header` from the attributes Hash and introduce it as a local variable, using the specified value as a default |
|
34
|
+
| `@props({header: required})` | Remove `header` from the attributes Hash and introduce it as a local variable, raising an error if it is not set |
|
35
|
+
| `{{ slot }}` | Output the block content passed into the current component |
|
36
|
+
| `<x-name><x-slot::header><h1>Header</h1><//>Content<//>` | Pass a named block to a component |
|
37
|
+
| `{{ header }}` | Output the contents of a named block |
|
38
|
+
| `<div {{ header.attributes }}>` | Output the attributes passed into a named block |
|
39
|
+
|
40
|
+
<a name="quick-reference-attributes"></a>
|
41
|
+
## Attributes
|
42
|
+
|
43
|
+
The attributes variable is an instance of a class that manages attributes. As well as the methods used in the examples below, you can use any method belonging to the Hash class.
|
44
|
+
|
45
|
+
| Syntax | Description |
|
46
|
+
|:-------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------|
|
47
|
+
| `<div {{ attributes }}>` | Print the contents of attributes as HTML attributes |
|
48
|
+
| `<div {{ attributes.merge({class: "text-black", type: "button"}) }}>` | Merge in additional attributes, combining the `:class` and `:style`, and setting defaults for other values |
|
49
|
+
| `<div {{ attributes.except(['type']) }}>` | Output the attributes array excluding the given keys |
|
50
|
+
| `<div {{ attributes.only(['type']) }}>` | Output only the given keys of the attributes array |
|
51
|
+
| `<div {{ attributes.filter { \|key, value\| key.start_with? "on:" } }}>` | Output the attributes for which the block returns true |
|
52
|
+
| `<div @class({'bg-red-600': is_error})>` | Conditionally print classes in an HTML class attribute |
|
53
|
+
| `<div @style({'bg-red-600': is_error})>` | Conditionally print styles in an HTML style attribute |
|
54
|
+
|
55
|
+
<a name="quick-reference-conditions"></a>
|
56
|
+
## Conditions
|
57
|
+
|
58
|
+
| Syntax | Description |
|
59
|
+
|:----------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------|
|
60
|
+
| `@if( RUBY_EXPRESSION ) ... @endIf` | Compiles to a Ruby if statement |
|
61
|
+
| `@if( RUBY_EXPRESSION ) ... @else ... @endIf` | Compiles to a Ruby if/else statement |
|
62
|
+
| `@if( RUBY_EXPRESSION ) ... @elsif( RUBY_EXPRESSION ) ... @endIf` | Compiles to a Ruby if/elsif statement |
|
63
|
+
| `@unless( RUBY_EXPRESSION ) ... @endunless` | Compiles to a Ruby unless statement |
|
64
|
+
| `@case( RUBY_EXPRESSION ) @when(1) ... @when(2) ... @else ... @endIf` | Compiles to a Ruby case statement |
|
65
|
+
| `@blank?( RUBY_EXPRESSION ) ... @endBlank?` | Compiles to a Ruby if statement that calls `blank?` method on the given expression |
|
66
|
+
| `@defined?( RUBY_EXPRESSION ) ... @endDefined?` | Compiles to a Ruby if statement that calls `defined?` function on the given expression |
|
67
|
+
| `@empty?( RUBY_EXPRESSION ) ... @endEmpty?` | Compiles to a Ruby if statement that calls `empty?` method on the given expression |
|
68
|
+
| `@nil?( RUBY_EXPRESSION ) ... @endNil?` | Compiles to a Ruby if statement that calls `nil?` method on the given expression |
|
69
|
+
| `@present?( RUBY_EXPRESSION ) ... @endPresent?` | Compiles to a Ruby if statement that calls `present?` method on the given expression |
|
70
|
+
| `@env(['development', 'test']) ... @endEnv` | Compiles to a Ruby if statement that checks if the current Rails environment matches any of the given environments |
|
71
|
+
| `@production ... @endProduction` | Shortcut for `@env('production')` |
|
72
|
+
| `@once ... @endOnce` | Render the given block the first time it appears in the template |
|
73
|
+
| `@once('unique key') ... @endOnce` | Render the given block the first time "unique key" is used in the template |
|
74
|
+
|
75
|
+
<a name="quick-reference-loops"></a>
|
76
|
+
## Loops
|
77
|
+
|
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 |
|
91
|
+
|
92
|
+
<a name="quick-reference-forms"></a>
|
93
|
+
## Forms
|
94
|
+
|
95
|
+
| Syntax | Description |
|
96
|
+
|:---------------------------------|:-----------------------------------------------------------------------------------------------------------------|
|
97
|
+
| `@old(:email, user[:email])` | Fetches `:email` from the params Hash, defaulting to the user's email if it doesn't exist |
|
98
|
+
| `@method('PATCH')` | Prints a hidden input setting the HTTP request type to the given value using the Rails MethodOverride middleware |
|
99
|
+
| `@DELETE` | Shortcut for `@method('DELETE')` |
|
100
|
+
| `@PATCH` | Shortcut for `@method('PATCH')` |
|
101
|
+
| `@PUT` | Shortcut for `@method('PUT')` |
|
102
|
+
| `@checked( RUBY_EXPRESSION )` | Prints "checked" if the ruby expression evaluates to true |
|
103
|
+
| `@disabled( RUBY_EXPRESSION )` | Prints "disabled" if the ruby expression evaluates to true |
|
104
|
+
| `@readonly( RUBY_EXPRESSION )` | Prints "readonly" if the ruby expression evaluates to true |
|
105
|
+
| `@required( RUBY_EXPRESSION )` | Prints "required" if the ruby expression evaluates to true |
|
106
|
+
| `@selected( RUBY_EXPRESSION )` | Prints "selected" if the ruby expression evaluates to true |
|
107
|
+
|
108
|
+
<a name="quick-reference-stacks"></a>
|
109
|
+
## Stacks
|
110
|
+
|
111
|
+
Stacks are a way of rendering content outside of the usual document order. For example, you could define a "sidebar" stack, then you'd be able to add content to that sidebar from anywhere else in the site.
|
112
|
+
|
113
|
+
Note that the stack is printed once the current view or component finishes.
|
114
|
+
|
115
|
+
| Syntax | Description |
|
116
|
+
|:------------------------------------------------------------|:--------------------------------------------------------------------------------------------|
|
117
|
+
| `@stack('scripts')` | Start a stack with the name 'scripts'. Stacks can be pushed to elsewhere in the code. |
|
118
|
+
| `@push('scripts') ... @endPush` | Add block content to the 'scripts' stack |
|
119
|
+
| `@prepend('scripts') ... @endPrepend` | Add block content to the start of the 'scripts' stack |
|
120
|
+
| `@pushIf(RUBY_EXPRESSION, 'scripts') ... @endPushIf` | Add block content to the 'scripts' stack if the expression evaluate to true |
|
121
|
+
| `@prependIf(RUBY_EXPRESSION, 'scripts') ... @endprependIf` | Add block content to the start of the 'scripts' stack if the expression evaluate to true |
|
122
|
+
| `@pushOnce('scripts') ... @endPushOnce` | Add block content to the 'scripts' stack only once |
|
123
|
+
| `@prependOnce('scripts') ... @endPrependOnce` | Add block content to the start of the 'scripts' stack only once |
|
124
|
+
| `@pushOnce('scripts', 'unique key') ... @endPushOnce` | Add block content to the 'scripts' stack the first time "unique key" is pushed |
|
125
|
+
| `@prependOnce('scripts', 'unique key') ... @endPrependOnce` | Add block content to the start of the 'scripts' stack the first time "unique key" is pushed |
|
126
|
+
|
127
|
+
## Tips
|
128
|
+
|
129
|
+
* Except for `@push`, `@prepend` and their variants, all end directives can simply be replaced with `@end` if preferred:
|
130
|
+
- `@nil?(...) ... @endnil?`
|
131
|
+
- `@nil?(...) ... @endnil`
|
132
|
+
- `@nil?(...) ... @end`
|
133
|
+
* Except for `@ruby` and `@verbatim`, directives are case insensitive and can contain underscores. The following are identical:
|
134
|
+
- `@pushonce`
|
135
|
+
- `@pushOnce`
|
136
|
+
- `@PushOnce`
|
137
|
+
- `@push_once`
|
138
|
+
- `@PUSHONCE`
|
data/examples/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
@ruby
|
2
|
+
# Typically these values would be set in the controller
|
3
|
+
banner_image = 'banner.png'
|
4
|
+
alert = nil
|
5
|
+
@endruby
|
6
|
+
<x-layout::app title="Home page">
|
7
|
+
<x-content.alert :alert/>
|
8
|
+
<x-content.alert alert="This is an alert"/>
|
9
|
+
<x-h1 blue>Welcome to the home page!</x-h1>
|
10
|
+
|
11
|
+
<x-p class="mt-2">
|
12
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Alias amet architecto, at commodi consectetur ipsa itaque magni minus neque nostrum pariatur possimus recusandae sunt! Est explicabo praesentium quidem vero voluptatum!
|
13
|
+
</x-p>
|
14
|
+
|
15
|
+
@if (banner_image)
|
16
|
+
<x-content.hero class="mt-4">
|
17
|
+
<x-slot::heading class="text-blue-600">
|
18
|
+
Beatae placeat porro quibusdam repudiandae sunt?
|
19
|
+
</x-slot::heading>
|
20
|
+
Adipisci blanditiis, dolor dolorem, ea iste laudantium minima natus nesciunt nostrum odio perferendis praesentium quae, similique.
|
21
|
+
</x-content.hero>
|
22
|
+
@endif
|
23
|
+
</x-layout::app>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
@props({heading: nil})
|
2
|
+
@pushOnce('scripts')
|
3
|
+
<script src="/js/hero.js"></script>
|
4
|
+
@endPushOnce
|
5
|
+
<div class="bg-blue-50 p-16">
|
6
|
+
<div class="max-w-96">
|
7
|
+
@if (heading)
|
8
|
+
<h2 {{ heading.attributes.merge({class: "text-lg font-bold"}) }}>
|
9
|
+
{{ heading }}
|
10
|
+
</h2>
|
11
|
+
@end
|
12
|
+
<p class="mt-4">{{ slot }}</p>
|
13
|
+
</div>
|
14
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<p {{ attributes.merge({
|
2
|
+
class: "
|
3
|
+
text-base font-normal
|
4
|
+
{{--
|
5
|
+
The tailwindcss-unimportant plugin works well with component design:
|
6
|
+
the "-:" prefix allows the consumer of the component to easily override
|
7
|
+
the component classes and extend the component.
|
8
|
+
See: https://www.npmjs.com/package/tailwindcss-unimportant
|
9
|
+
--}}
|
10
|
+
-:mt-1
|
11
|
+
"
|
12
|
+
}) }}>
|
13
|
+
{{ slot }}
|
14
|
+
</p>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
@props({title: required})
|
2
|
+
<!DOCTYPE html>
|
3
|
+
<html lang="en">
|
4
|
+
<head>
|
5
|
+
<meta charset="UTF-8">
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
8
|
+
<title>{{ title }}</title>
|
9
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
10
|
+
@stack('scripts')
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<div {{ attributes.merge({class: "max-w-prose mt-8 mx-auto flex flex-col gap-4"}) }}>
|
14
|
+
{{ slot }}
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -51,11 +51,11 @@ module RBlade
|
|
51
51
|
|
52
52
|
namespace = nil
|
53
53
|
name = component[:name]
|
54
|
-
if name.match
|
54
|
+
if name.match? "::"
|
55
55
|
namespace, name = component[:name].split("::")
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
if namespace == "slot"
|
59
59
|
compile_slot_end name, component
|
60
60
|
else
|
61
61
|
compile_component_end component
|
@@ -1,22 +1,23 @@
|
|
1
1
|
module RBlade
|
2
|
-
class
|
2
|
+
class CompilesPrints
|
3
3
|
def compile!(tokens)
|
4
|
-
|
5
|
-
|
4
|
+
compile_unsafe_prints!(tokens)
|
5
|
+
compile_regular_prints!(tokens)
|
6
6
|
end
|
7
7
|
|
8
8
|
private
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
10
|
+
def compile_regular_prints!(tokens)
|
11
|
+
compile_prints! tokens, "{{", "}}", "RBlade.e"
|
12
|
+
compile_prints! tokens, "<%=", "%>", "RBlade.e"
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
15
|
+
def compile_unsafe_prints!(tokens)
|
16
|
+
compile_prints! tokens, "{!!", "!!}"
|
17
|
+
compile_prints! tokens, "<%==", "%>"
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
+
def compile_prints!(tokens, start_token, end_token, wrapper_function = nil)
|
20
21
|
tokens.map! do |token|
|
21
22
|
next(token) if token.type != :unprocessed
|
22
23
|
|
@@ -41,7 +42,7 @@ module RBlade
|
|
41
42
|
else
|
42
43
|
"(" + segments[i] + ").to_s;"
|
43
44
|
end
|
44
|
-
segments[i] = Token.new(:
|
45
|
+
segments[i] = Token.new(:print, segment_value)
|
45
46
|
|
46
47
|
i += 1
|
47
48
|
elsif !segments[i].nil? && segments[i] != ""
|
@@ -1,10 +1,10 @@
|
|
1
|
+
require "rblade/compiler/statements/compiles_component_helpers"
|
1
2
|
require "rblade/compiler/statements/compiles_conditionals"
|
2
3
|
require "rblade/compiler/statements/compiles_form"
|
3
4
|
require "rblade/compiler/statements/compiles_html_attributes"
|
4
5
|
require "rblade/compiler/statements/compiles_inline_ruby"
|
5
6
|
require "rblade/compiler/statements/compiles_loops"
|
6
7
|
require "rblade/compiler/statements/compiles_once"
|
7
|
-
require "rblade/compiler/statements/compiles_props"
|
8
8
|
require "rblade/compiler/statements/compiles_stacks"
|
9
9
|
|
10
10
|
module RBlade
|
@@ -71,7 +71,6 @@ module RBlade
|
|
71
71
|
@@statement_handlers = {
|
72
72
|
"blank?" => [CompilesConditionals, :compileBlank],
|
73
73
|
"break" => [CompilesLoops, :compileBreak],
|
74
|
-
"breakif" => [CompilesLoops, :compileBreakIf],
|
75
74
|
"case" => [CompilesConditionals, :compileCase],
|
76
75
|
"checked" => [CompilesConditionals, :compileChecked],
|
77
76
|
"class" => [CompilesHtmlAttributes, :compileClass],
|
@@ -97,7 +96,6 @@ module RBlade
|
|
97
96
|
"if" => [CompilesConditionals, :compileIf],
|
98
97
|
"method" => [CompilesForm, :compileMethod],
|
99
98
|
"next" => [CompilesLoops, :compileNext],
|
100
|
-
"nextif" => [CompilesLoops, :compileNextIf],
|
101
99
|
"nil?" => [CompilesConditionals, :compileNil],
|
102
100
|
"old" => [CompilesForm, :compileOld],
|
103
101
|
"once" => [CompilesOnce, :compileOnce],
|
@@ -107,7 +105,7 @@ module RBlade
|
|
107
105
|
"prependonce" => [CompilesOnce, :compilePrependOnce],
|
108
106
|
"present?" => [CompilesConditionals, :compilePresent],
|
109
107
|
"production" => [CompilesConditionals, :compileProduction],
|
110
|
-
"props" => [
|
108
|
+
"props" => [CompilesComponentHelpers, :compileProps],
|
111
109
|
"push" => [CompilesStacks, :compilePush],
|
112
110
|
"pushif" => [CompilesStacks, :compilePushIf],
|
113
111
|
"pushonce" => [CompilesOnce, :compilePushOnce],
|
@@ -116,6 +114,7 @@ module RBlade
|
|
116
114
|
"required" => [CompilesConditionals, :compileRequired],
|
117
115
|
"ruby" => [CompilesInlineRuby, :compile],
|
118
116
|
"selected" => [CompilesConditionals, :compileSelected],
|
117
|
+
"shouldrender" => [CompilesComponentHelpers, :compileShouldRender],
|
119
118
|
"stack" => [CompilesStacks, :compileStack],
|
120
119
|
"style" => [CompilesHtmlAttributes, :compileStyle],
|
121
120
|
"unless" => [CompilesConditionals, :compileUnless],
|
@@ -2,23 +2,37 @@ require "rblade/helpers/tokenizer"
|
|
2
2
|
|
3
3
|
module RBlade
|
4
4
|
class CompilesStatements
|
5
|
-
class
|
6
|
-
def
|
7
|
-
if args
|
8
|
-
raise StandardError.new "
|
5
|
+
class CompilesComponentHelpers
|
6
|
+
def compileShouldRender args
|
7
|
+
if args&.count != 1
|
8
|
+
raise StandardError.new "Should render statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
9
|
+
end
|
10
|
+
|
11
|
+
"unless(#{args[0]});return'';end;"
|
12
|
+
end
|
13
|
+
|
14
|
+
def compileProps args, tokens
|
15
|
+
if args&.count != 1
|
16
|
+
raise StandardError.new "Props statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
9
17
|
end
|
10
18
|
|
11
19
|
props = extractProps args[0]
|
12
20
|
props.map do |key, value|
|
13
21
|
compiled_code = ""
|
14
|
-
|
15
|
-
|
22
|
+
|
23
|
+
# `_required` is deprecated. Use `required`. To be removed in 2.0.0
|
24
|
+
compiled_code << if value == "_required" || value == "required"
|
25
|
+
"if !attributes.has?(:'#{RBlade.escape_quotes(key)}');raise \"Props statement: #{key} is not defined\";end;"
|
26
|
+
else
|
27
|
+
"attributes.default(:'#{RBlade.escape_quotes(key)}', #{value});"
|
16
28
|
end
|
29
|
+
|
17
30
|
if isValidVariableName key
|
18
|
-
compiled_code <<
|
19
|
-
|
20
|
-
|
21
|
-
|
31
|
+
compiled_code << if variableIsSlot key, tokens
|
32
|
+
"#{key}=RBlade::SlotManager.wrap(attributes.delete :'#{RBlade.escape_quotes(key)}');"
|
33
|
+
else
|
34
|
+
"#{key}=attributes.delete :'#{RBlade.escape_quotes(key)}';"
|
35
|
+
end
|
22
36
|
end
|
23
37
|
|
24
38
|
compiled_code
|
@@ -75,6 +89,11 @@ module RBlade
|
|
75
89
|
|
76
90
|
true
|
77
91
|
end
|
92
|
+
|
93
|
+
# Automatically detect if a variable is a slot by looking for "<var>.attributes"
|
94
|
+
def variableIsSlot name, tokens
|
95
|
+
tokens.any? { |token| token.value.to_s.match "#{name}.attributes" }
|
96
|
+
end
|
78
97
|
end
|
79
98
|
end
|
80
99
|
end
|
@@ -58,8 +58,8 @@ module RBlade
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def compileElse args
|
61
|
-
|
62
|
-
raise StandardError.new "Else statement: wrong number of arguments (given #{args
|
61
|
+
unless args.nil?
|
62
|
+
raise StandardError.new "Else statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
63
63
|
end
|
64
64
|
|
65
65
|
"else;"
|
@@ -82,8 +82,8 @@ module RBlade
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def compileWhen args
|
85
|
-
if args.nil?
|
86
|
-
raise StandardError.new "When statement: wrong number of arguments (given
|
85
|
+
if args.nil?
|
86
|
+
raise StandardError.new "When statement: wrong number of arguments (given 0, expecting at least 1)"
|
87
87
|
end
|
88
88
|
|
89
89
|
"when #{args.join ","};"
|
@@ -141,19 +141,11 @@ module RBlade
|
|
141
141
|
|
142
142
|
def compileProduction args
|
143
143
|
unless args.nil?
|
144
|
-
raise StandardError.new "Production statement: wrong number of arguments (given #{args.count}, expecting
|
144
|
+
raise StandardError.new "Production statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
145
145
|
end
|
146
146
|
|
147
147
|
"if Rails.env.production?;"
|
148
148
|
end
|
149
|
-
|
150
|
-
def compileOnce args
|
151
|
-
if args&.count&.> 1
|
152
|
-
raise StandardError.new "Production statement: wrong number of arguments (given #{args.count}, expecting 0 or 1)"
|
153
|
-
end
|
154
|
-
|
155
|
-
args[0].nil? ? "" : args[0]
|
156
|
-
end
|
157
149
|
end
|
158
150
|
end
|
159
151
|
end
|
@@ -3,40 +3,40 @@ module RBlade
|
|
3
3
|
class CompilesForm
|
4
4
|
def compileMethod args
|
5
5
|
if args&.count != 1
|
6
|
-
raise StandardError.new "
|
6
|
+
raise StandardError.new "Method statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
7
7
|
end
|
8
|
-
method = RBlade.h(args[0].tr
|
8
|
+
method = RBlade.h(args[0].tr("\"'", ""))
|
9
9
|
|
10
|
-
%
|
10
|
+
%(_out<<'<input type="hidden" name="_method" value="#{method}">';)
|
11
11
|
end
|
12
12
|
|
13
13
|
def compileDelete args
|
14
|
-
|
15
|
-
raise StandardError.new "
|
14
|
+
unless args.nil?
|
15
|
+
raise StandardError.new "Delete statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
16
16
|
end
|
17
17
|
|
18
|
-
compileMethod([
|
18
|
+
compileMethod(["DELETE"])
|
19
19
|
end
|
20
20
|
|
21
21
|
def compilePatch args
|
22
|
-
|
23
|
-
raise StandardError.new "
|
22
|
+
unless args.nil?
|
23
|
+
raise StandardError.new "Patch statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
24
24
|
end
|
25
25
|
|
26
|
-
compileMethod([
|
26
|
+
compileMethod(["PATCH"])
|
27
27
|
end
|
28
28
|
|
29
29
|
def compilePut args
|
30
|
-
|
31
|
-
raise StandardError.new "
|
30
|
+
unless args.nil?
|
31
|
+
raise StandardError.new "Put statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
32
32
|
end
|
33
33
|
|
34
|
-
compileMethod([
|
34
|
+
compileMethod(["PUT"])
|
35
35
|
end
|
36
36
|
|
37
37
|
def compileOld args
|
38
38
|
if args.nil? || args.count > 2
|
39
|
-
raise StandardError.new "
|
39
|
+
raise StandardError.new "Old statement: wrong number of arguments (given #{args&.count || 0}, expecting 1 or 2)"
|
40
40
|
end
|
41
41
|
|
42
42
|
default_value = args[1] || "''"
|
@@ -7,7 +7,7 @@ module RBlade
|
|
7
7
|
|
8
8
|
def compileBreak args
|
9
9
|
if args&.count&.> 1
|
10
|
-
raise StandardError.new "Break statement: wrong number of arguments (given #{args
|
10
|
+
raise StandardError.new "Break statement: wrong number of arguments (given #{args.count}, expecting 0 or 1)"
|
11
11
|
end
|
12
12
|
|
13
13
|
if args.nil?
|
@@ -31,7 +31,7 @@ module RBlade
|
|
31
31
|
|
32
32
|
def compileEachElse args
|
33
33
|
if args.nil? || args.count > 2
|
34
|
-
raise StandardError.new "Each statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
34
|
+
raise StandardError.new "Each else statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
35
35
|
end
|
36
36
|
# Allow variables to be a key, value pair
|
37
37
|
args = args.join ","
|
@@ -59,7 +59,11 @@ module RBlade
|
|
59
59
|
"_looped_#{@loop_else_counter}=false;for #{args[0]};_looped_#{@loop_else_counter}=true;"
|
60
60
|
end
|
61
61
|
|
62
|
-
def compileEmpty
|
62
|
+
def compileEmpty args
|
63
|
+
unless args.nil?
|
64
|
+
raise StandardError.new "Empty statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
65
|
+
end
|
66
|
+
|
63
67
|
@loop_else_counter -= 1
|
64
68
|
|
65
69
|
"end;if !_looped_#{@loop_else_counter + 1};"
|
@@ -67,7 +71,7 @@ module RBlade
|
|
67
71
|
|
68
72
|
def compileNext args
|
69
73
|
if args&.count&.> 1
|
70
|
-
raise StandardError.new "
|
74
|
+
raise StandardError.new "Next statement: wrong number of arguments (given #{args.count}, expecting 0 or 1)"
|
71
75
|
end
|
72
76
|
|
73
77
|
if args.nil?
|
@@ -17,7 +17,7 @@ module RBlade
|
|
17
17
|
|
18
18
|
def compilePushOnce args
|
19
19
|
if args&.count != 1 && args&.count != 2
|
20
|
-
raise StandardError.new "Push once statement: wrong number of arguments (given #{args
|
20
|
+
raise StandardError.new "Push once statement: wrong number of arguments (given #{args&.count || 0}, expecting 1 or 2)"
|
21
21
|
end
|
22
22
|
@once_counter += 1
|
23
23
|
once_id = args[1].nil? ? ":_#{@once_counter}" : args[1]
|
@@ -27,8 +27,8 @@ module RBlade
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def compileEndPushOnce args
|
30
|
-
|
31
|
-
raise StandardError.new "End push once statement: wrong number of arguments (given #{args
|
30
|
+
unless args.nil?
|
31
|
+
raise StandardError.new "End push once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
32
32
|
end
|
33
33
|
|
34
34
|
"RBlade::StackManager.push(_p1_#{@once_counter}, _out);_out=_p1_#{@once_counter}_b;end;"
|
@@ -36,7 +36,7 @@ module RBlade
|
|
36
36
|
|
37
37
|
def compilePrependOnce args
|
38
38
|
if args&.count != 1 && args&.count != 2
|
39
|
-
raise StandardError.new "Prepend once statement: wrong number of arguments (given #{args
|
39
|
+
raise StandardError.new "Prepend once statement: wrong number of arguments (given #{args&.count || 0}, expecting 1 or 2)"
|
40
40
|
end
|
41
41
|
@once_counter += 1
|
42
42
|
once_id = args[1].nil? ? ":_#{@once_counter}" : args[1]
|
@@ -46,8 +46,8 @@ module RBlade
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def compileEndPrependOnce args
|
49
|
-
|
50
|
-
raise StandardError.new "End prepend once statement: wrong number of arguments (given #{args
|
49
|
+
unless args.nil?
|
50
|
+
raise StandardError.new "End prepend once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
51
51
|
end
|
52
52
|
|
53
53
|
"RBlade::StackManager.prepend(_p1_#{@once_counter}, _out);_out=_p1_#{@once_counter}_b;end;"
|