tzispa_rig 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c7fc4d4373f601d2153eb629fa2cbd150ce1f2c
4
- data.tar.gz: 179daf386ee3851db47dfc3808667bd9dae5acfd
3
+ metadata.gz: b0ee09cd6bcb8f16477ec4472fe2442599db939d
4
+ data.tar.gz: a168edea1da7db3d372b37ca97bbbb58b6adb3ef
5
5
  SHA512:
6
- metadata.gz: 0b42740653389d7d04833dc5e90ccdfff3d6316ef35eb790fe748f928f0602ef29ea4ed2573b6ef2ec86954aea73e9a3ac92968210cd4f59bb6d7418cc4e5649
7
- data.tar.gz: ffe72dfc14733a083980078d497cc1ca315935de5019a97d2b7e6a457931e635807a9d00b17e47035bc4a93d0f363ced286201c01abc992e258eac4afa87a733
6
+ metadata.gz: 272a50312a02d4455a1701d12a27270fc01523ee03cd61c85fbd7609875671bbf5885f9c942f96b5f825e131174886cefcec3813e82db66b5a13bdf7a5f3c0d6
7
+ data.tar.gz: d67f6a12863368644c24a2988e223972ffe5ce6c20cfe0d7632369096f6f1e5d1865e469c6afc57a6e10dc532d0561c8668d8e3c3e0f4342c2339dcd08bd616a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,9 @@ Tzispa Rig
2
2
 
3
3
  Rig templates implementation
4
4
 
5
+ ## v0.5.1
6
+ - Bug fixes and code refactoring
7
+
5
8
  ## v0.5.0
6
9
  - Rig templates syntax changes in url/purl and blk/iblk/static
7
10
  - Added support for subdoamins in layouts
@@ -5,25 +5,43 @@ require 'forwardable'
5
5
  module Tzispa
6
6
  module Rig
7
7
 
8
+ class UnknownTag < NameError
9
+ def initialize(name, tag)
10
+ super "#{name} there isn't any loop tagged '#{tag}'"
11
+ end
12
+ end
8
13
 
9
- class UnknownTag < NameError; end
10
- class DuplicatedLoop < StandardError; end
14
+ class DuplicatedLoop < StandardError
15
+ def initialize(name, loop_id)
16
+ super "#{name} there are many loops tagged '#{loop_id}' only 1 allowed at the same level"
17
+ end
18
+ end
11
19
 
20
+ class IsnotTemplateBinder < ArgumentError
21
+ def initialize(name)
22
+ super "Class #{name} isn't a TemplateBinder"
23
+ end
24
+ end
12
25
 
13
26
  class Binder
14
27
  extend Forwardable
15
28
 
16
29
  attr_reader :context, :data_struct, :parser
17
30
  def_delegators :@parser, :attribute_tags
18
- def_delegators :@context, :app, :request, :response, :session, :router_params, :cache
31
+ def_delegators :@context, :app, :request, :response,
32
+ :session, :router_params, :cache
19
33
  def_delegators :app, :repository, :config, :logger
20
- alias :tags :attribute_tags
21
34
 
35
+ alias tags attribute_tags
22
36
 
23
37
  def initialize(parser, context)
24
38
  @parser = parser
25
39
  @context = context
26
- @data_struct = attribute_tags.count > 0 ? Struct.new(*attribute_tags) : Struct.new(nil)
40
+ @data_struct = if attribute_tags.count.positive?
41
+ Struct.new(*attribute_tags)
42
+ else
43
+ Struct.new(nil)
44
+ end
27
45
  end
28
46
 
29
47
  # Gets a LoopBinder context for the given loop_id in a rig template
@@ -39,7 +57,7 @@ module Tzispa
39
57
  # The LoopBinder returned by this funcion is independent of the
40
58
  # parent binder where it is defined, so the template symbols of the parent
41
59
  # binder are not accesible in the loop_binder context. In
42
- # other words, in the top example the two 'myvar' symbols are different symbols
60
+ # other words, in the top example the two 'myvar' symbols are different
43
61
  # and you can not access the first myvar value inside the loop
44
62
  #
45
63
  # ==== Parameters
@@ -47,19 +65,25 @@ module Tzispa
47
65
  #
48
66
  def loop_binder(loop_id)
49
67
  loop_parser = @parser.loop_parser loop_id
50
- raise UnknownTag.new("#{self.class.name} there isn't any loop tagged '#{loop_id}'") unless loop_parser && loop_parser.count > 0
51
- raise DuplicatedLoop.new("#{self.class.name} there are #{loop_parser.count} loops tagged '#{loop_id}' at the same level: only one allowed") unless loop_parser.count == 1
68
+ unknown? loop_parser
69
+ duplicated? loop_parser
52
70
  LoopBinder.new loop_parser[0], @context
53
71
  end
54
72
 
55
73
  def attr_cache(*attrs)
56
- attrs.each { |attrib|
57
- cache[attrib] = send(attrib) if respond_to?(attrib)
58
- }
74
+ attrs.each { |attrib| cache[attrib] = send(attrib) if respond_to?(attrib) }
59
75
  end
60
76
 
61
- end
77
+ private
78
+
79
+ def unknown?(loop_parser)
80
+ raise UnknownTag.new(self.class.name, loop_parser.id) unless loop_parser.count.positive?
81
+ end
62
82
 
83
+ def duplicated?(loop_parser)
84
+ raise DuplicatedLoop.new(self.class.name, loop_parser.id) unless loop_parser.count == 1
85
+ end
86
+ end
63
87
 
64
88
  class TemplateBinder < Binder
65
89
  extend Forwardable
@@ -67,7 +91,6 @@ module Tzispa
67
91
  attr_reader :template
68
92
  def_delegators :@template, :params
69
93
 
70
-
71
94
  def initialize(template, context)
72
95
  super(template.parser, context)
73
96
  @template = template
@@ -78,65 +101,61 @@ module Tzispa
78
101
  end
79
102
 
80
103
  def attach(**params)
81
- data.tap { |d|
82
- params.each{ |k,v|
83
- raise UnknownTag.new "#{k} is not a tag in #{self.class.name}" unless tags.include? k
104
+ data.tap do |d|
105
+ params.each do |k, v|
106
+ raise UnknownTag.new(self.class.name, k) unless tags.include? k
84
107
  d[k] = v
85
- }
86
- }
108
+ end
109
+ end
87
110
  end
88
111
 
89
112
  def self.for(template, context)
90
113
  if template.bindable?
91
114
  binder_class = template.binder_class
92
- binder_class.new(template, context).tap { |binder|
93
- raise ArgumentError.new "#{binder_class.name} isn't a TemplateBinder" unless binder&.is_a? Tzispa::Rig::TemplateBinder
94
- } if binder_class
115
+ binder_class&.new(template, context)&.tap do |binder|
116
+ raise IsnotTemplateBinder(binder_class.name) unless binder.is_a? TemplateBinder
117
+ end
95
118
  else
96
- self.new(template, context)
119
+ new(template, context)
97
120
  end
98
121
  end
99
-
100
122
  end
101
123
 
102
-
103
124
  class LoopBinder < Binder
104
-
105
125
  attr_reader :data
106
126
 
107
127
  def bind!(&generator)
108
- @source_object = eval "self", generator.binding
128
+ @source_object = eval 'self', generator.binding
109
129
  @data = instance_eval(&generator).to_enum(:each)
110
130
  self
111
131
  end
112
132
 
113
133
  def method_missing(method, *args, &generator)
114
- @source_object.send method, *args, &generator
134
+ @source_object.send(method, *args, &generator)
115
135
  end
116
136
 
117
- def loop_item(params=nil)
118
- (LoopItem.new self).tap { |item|
119
- params.each{ |k,v|
120
- raise UnknownTag.new "#{k} is not a tag in #{self.class.name}" unless tags.include? k
121
- item.data[k] = v
122
- } if params
123
- }
137
+ def respond_to_missing?(method, *)
138
+ @source_object.respond_to?(method)
124
139
  end
125
140
 
141
+ def loop_item(params = nil)
142
+ (LoopItem.new self).tap do |item|
143
+ params&.each do |k, v|
144
+ raise UnknownTag(self.class.name, k) unless tags.include? k
145
+ item.data[k] = v
146
+ end
147
+ end
148
+ end
126
149
  end
127
150
 
128
-
129
151
  class LoopItem
130
-
131
152
  attr_reader :context, :data
132
153
 
133
154
  def initialize(binder)
134
155
  @context = binder.context
135
156
  @data = binder.data_struct.new
136
157
  end
137
-
138
158
  end
139
159
 
140
-
141
160
  end
142
161
  end
@@ -10,52 +10,44 @@ module Tzispa
10
10
  class Engine
11
11
  include Singleton
12
12
 
13
- @@cache_size = 512
14
- @@cache_ttl = 600 # 10 mins
13
+ @cache_size = 512
14
+ @cache_ttl = 600
15
15
 
16
16
  def initialize
17
- @cache = LruRedux::TTL::ThreadSafeCache.new(@@cache_size, @@cache_ttl)
17
+ @cache = LruRedux::TTL::ThreadSafeCache.new(Engine.cache_size, Engine.cache_ttl)
18
18
  end
19
19
 
20
20
  class << self
21
+ attr_accessor :cache_size, :cache_ttl
21
22
 
22
23
  def empty
23
24
  TemplateBase.new
24
25
  end
25
26
 
26
- def layout(name:, domain:, content_type:, params:nil)
27
+ def layout(name:, domain:, content_type:, params: nil)
27
28
  rig_template name, domain, :layout, content_type, params
28
29
  end
29
30
 
30
- def block(name:, domain:, content_type:, params:nil)
31
+ def block(name:, domain:, content_type:, params: nil)
31
32
  rig_template name, domain, :block, content_type, params
32
33
  end
33
34
 
34
- def static(name:, domain:, content_type:, params:nil)
35
+ def static(name:, domain:, content_type:, params: nil)
35
36
  rig_template name, domain, :static, content_type, params
36
37
  end
37
38
 
38
39
  def rig_template(name, domain, block_type, content_type, params)
39
40
  instance.send(:cache_template, name, domain, block_type, content_type, params)
40
41
  end
41
-
42
- def cache_size=(sz)
43
- @@cache_size = sz
44
- end
45
-
46
- def cache_ttl=(seconds)
47
- @@cache_ttl = seconds
48
- end
49
-
50
42
  end
51
43
 
52
44
  private
53
45
 
54
46
  def cache_template(name, domain, block_type, content_type, params)
55
47
  key = "#{domain}/#{block_type}/#{name}/#{content_type}".to_sym
56
- get_template(key, name, domain, block_type, content_type).dup.tap { |ctpl|
57
- ctpl.params = params if params
58
- }
48
+ get_template(key, name, domain, block_type, content_type).dup.tap do |ctpl|
49
+ ctpl.params = params if params
50
+ end
59
51
  end
60
52
 
61
53
  def get_template(key, name, domain, block_type, content_type)
@@ -67,9 +59,11 @@ module Tzispa
67
59
  end
68
60
 
69
61
  def set_template(key, name, domain, block_type, content_type)
70
- @cache[key] = Template.new(name: name, type: block_type, domain: domain, content_type: content_type).load!.parse!
62
+ @cache[key] = Template.new(name: name,
63
+ type: block_type,
64
+ domain: domain,
65
+ content_type: content_type).load!.parse!
71
66
  end
72
-
73
67
  end
74
68
 
75
69
  end
@@ -4,14 +4,13 @@ module Tzispa
4
4
  module Rig
5
5
 
6
6
  class Parameters
7
-
8
7
  attr_reader :inner, :outer
9
8
 
10
- def initialize(params=nil, outer=',', inner='=')
11
- @data = Hash.new
9
+ def initialize(params = nil, outer = ',', inner = '=')
10
+ @data = {}
12
11
  @outer = outer
13
12
  @inner = inner
14
- setData(params) if params
13
+ load(params) if params
15
14
  end
16
15
 
17
16
  def [](key)
@@ -27,29 +26,28 @@ module Tzispa
27
26
  end
28
27
 
29
28
  def to_s
30
- @data.map { |k,v| "#{k}#{inner}#{v}" }.join(outer)
29
+ @data.map { |k, v| "#{k}#{inner}#{v}" }.join(outer)
31
30
  end
32
31
 
33
32
  def to_h
34
33
  @data.dup
35
34
  end
36
35
 
37
- alias_method :data, :to_h
36
+ alias data to_h
38
37
 
39
38
  def merge(params)
40
- setData(params)
39
+ load(params)
41
40
  end
42
41
 
43
42
  private
44
43
 
45
- def setData(params)
44
+ def load(params)
46
45
  params.split(outer).each do |param|
47
- key,value = param.split(inner)
46
+ key, value = param.split(inner)
48
47
  @data[key.to_sym] = value
49
48
  end
50
49
  end
51
-
52
-
53
50
  end
51
+
54
52
  end
55
53
  end
@@ -6,35 +6,43 @@ module Tzispa
6
6
  module Rig
7
7
 
8
8
  class ParserNext
9
-
10
9
  EMPTY_STRING = ''
11
10
 
12
11
  include Tzispa::Rig::Syntax
13
12
 
14
- attr_reader :flags, :template, :tokens, :domain, :format, :childrens,
15
- :bindable, :content_type, :inner_text, :content_escape_method
13
+ attr_reader :flags, :template, :tokens, :domain, :format,
14
+ :childrens, :content_type, :inner_text
16
15
 
17
- def initialize(template = nil, text: nil, domain: nil, content_type: nil, bindable: nil, parent: nil)
16
+ def initialize(opts = {})
18
17
  @parsed = false
19
- @template = template
20
- @inner_text = (text || template&.content)&.dup
21
- @domain = domain || parent.domain
22
- @bindable = bindable.nil? ? parent.bindable : bindable
23
- @content_type = content_type || parent.content_type
24
- @content_escape_method = :"escape_#{content_type}"
18
+ @template = opts[:template] if opts.key?(:template)
19
+ @inner_text = (opts[:text] || template&.content)&.dup
20
+ parent = opts[:parent]
21
+ @domain = opts[:domain] || parent.domain
22
+ @bindable = opts.key?(:bindable) ? opts[:bindable] : parent.bindable?
23
+ @content_type = opts[:content_type] || parent.content_type
25
24
  end
26
25
 
27
26
  def empty?
28
27
  @tokens.empty?
29
28
  end
30
29
 
30
+ def bindable?
31
+ @bindable
32
+ end
33
+
34
+ def parsed?
35
+ @parsed
36
+ end
37
+
31
38
  def parse!
32
39
  unless parsed?
33
- @attribute_tags = nil
34
- @childrens = Array.new
35
- @tokens = Array.new
40
+ @attribute_tags = nil
41
+ @childrens = []
42
+ @tokens = []
43
+ @loop_parser = {}
36
44
  parse_flags
37
- if bindable
45
+ if bindable?
38
46
  parse_statements
39
47
  parse_expressions
40
48
  parse_url_builder
@@ -45,86 +53,81 @@ module Tzispa
45
53
  self
46
54
  end
47
55
 
48
- def parsed?
49
- @parsed
56
+ def content_escape_method
57
+ @content_escape_method ||= :"escape_#{content_type}"
50
58
  end
51
59
 
52
60
  def render(binder)
53
- @inner_text.dup.tap { |text|
54
- @tokens.each { |value|
55
- text.gsub! value.anchor, value.render(binder)
56
- }
57
- }.freeze
61
+ @inner_text.dup.tap do |text|
62
+ @tokens.each { |value| text.gsub! value.anchor, value.render(binder) }
63
+ end.freeze
58
64
  end
59
65
 
60
66
  def attribute_tags
61
- @attribute_tags ||= tokens.map { |p|
62
- p.id.to_sym if p.respond_to? :id
63
- }.concat(
64
- tokens.map{ |p|
65
- p.attribute_tags if p.type == :ife
66
- }
67
- ).compact.flatten.uniq.freeze
67
+ @at_tags ||= begin
68
+ att = tokens.select { |tk| tk.respond_to? :id }
69
+ att = att.map { |p| p.id.to_sym }
70
+ att.concat(
71
+ tokens.map { |p| p.attribute_tags if p.type == :ife }
72
+ ).compact.flatten.uniq.freeze
73
+ end
68
74
  end
69
75
 
70
76
  def loop_parser(id)
71
- tokens.select{ |p|
72
- p.type==:loop && p.id==id
73
- }.concat(
74
- tokens.select{ |p|
75
- p.type==:ife }.map {
76
- |p| p.loop_parser(id)
77
- }.flatten.compact
77
+ lpp = tokens.select { |p| p.type == :loop && p.id == id }
78
+ lpp.concat(
79
+ tokens.select { |p| p.type == :ife }.map do |p|
80
+ p.loop_parser(id)
81
+ end.flatten.compact
78
82
  )
79
83
  end
80
84
 
81
85
  private
82
86
 
83
87
  def parse_flags
84
- while match = @inner_text.match(RIG_EMPTY[:flags]) do
88
+ while (match = @inner_text.match RIG_EMPTY[:flags])
85
89
  @flags = Regexp.last_match(1)
86
90
  @inner_text.gsub! match[0], ''
87
91
  end
88
92
  end
89
93
 
90
94
  def parse_url_builder
91
- RIG_URL_BUILDER.each_key { |kre|
92
- while match = @inner_text.match(RIG_URL_BUILDER[kre]) do
93
- tk = Token.instance(self, kre, match )
95
+ RIG_URL_BUILDER.each_key do |kre|
96
+ while (match = @inner_text.match RIG_URL_BUILDER[kre])
97
+ tk = Token.instance(self, kre, match)
94
98
  @tokens << tk
95
99
  @inner_text.gsub! match[0], tk.anchor
96
100
  end
97
- }
101
+ end
98
102
  end
99
103
 
100
104
  def parse_expressions
101
- RIG_EXPRESSIONS.each { |kre, re|
102
- while match = @inner_text.match(re) do
103
- tk = Token.instance(self, kre, match )
105
+ RIG_EXPRESSIONS.each do |kre, re|
106
+ while (match = @inner_text.match re)
107
+ tk = Token.instance(self, kre, match)
104
108
  @tokens << tk
105
109
  @inner_text.gsub! match[0], tk.anchor
106
110
  end
107
- }
111
+ end
108
112
  end
109
113
 
110
114
  def parse_statements
111
- while match = @inner_text.match(RIG_STATEMENTS) do
112
- type = (match[2] || String.new) << (match[6] || String.new)
113
- tk = Token.instance(self, type.to_sym, match )
115
+ while (match = @inner_text.match RIG_STATEMENTS)
116
+ type = String.new << (match[2] || match[6])
117
+ tk = Token.instance(self, type.to_sym, match)
114
118
  @tokens << tk.parse!
115
119
  @inner_text.gsub! match[0], tk.anchor
116
120
  end
117
121
  end
118
122
 
119
123
  def parse_templates
120
- while match = @inner_text.match(RIG_TEMPLATES) do
121
- type = (match[2] || String.new) << (match[6] || String.new) << (match[13] || String.new)
122
- tk = Token.instance(self, type.to_sym, match )
124
+ while (match = @inner_text.match RIG_TEMPLATES)
125
+ type = String.new << (match[2] || match[6] || match[13])
126
+ tk = Token.instance(self, type.to_sym, match)
123
127
  @tokens << tk.parse!
124
128
  @inner_text.gsub! match[0], tk.anchor
125
129
  end
126
130
  end
127
-
128
131
  end
129
132
 
130
133
  end
@@ -1,26 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Tzispa
2
4
  module Rig
3
5
  module Syntax
4
6
 
5
7
  RIG_EMPTY = {
6
- :flags => /<flags:(\[(\w+=[^,\]]+(,\w+=[^,\]]+)*?)\])\/>/
8
+ flags: /<flags:(\[(\w+=[^,\]]+(,\w+=[^,\]]+)*?)\])\/>/
7
9
  }.freeze
8
10
 
9
11
  RIG_EXPRESSIONS = {
10
- :meta => /\{%([^%]+?)%\}/,
11
- :var => /<var(\[%[A-Z]?[0-9]*[a-z]\])?:(\w+)\/>/
12
+ meta: /\{%([^%]+?)%\}/,
13
+ var: /<var(\[%[A-Z]?[0-9]*[a-z]\])?:(\w+)\/>/
12
14
  }.freeze
13
15
 
14
16
  RIG_URL_BUILDER = {
15
- :url => /<(url|purl)(#\w+)?:([^\[\@\/]+(?:\@[^\[\/]+)?)(\[(\w+=[^,\]]+(,\w+=[^,\]]+)*?)\])?\/>/,
16
- :api => /<(api|sapi)(#\w+)?:([^:\@]+(?:\@[^:]+)?):([^:\/]+)(?::([^:\/]+))?(?::([^\/]+))?\/>/
17
+ url: /<(url|purl)(#\w+)?:([^\[\@\/]+(?:\@[^\[\/]+)?)(\[(\w+=[^,\]]+(,\w+=[^,\]]+)*?)\])?\/>/,
18
+ api: /<(api|sapi)(#\w+)?:([^:\@]+(?:\@[^:]+)?):([^:\/]+)(?::([^:\/]+))?(?::([^\/]+))?\/>/
17
19
  }.freeze
18
20
 
19
21
  RIG_STATEMENTS = /(<(loop):(\w+)>(.*?)<\/loop:\3>)|(<(ife):(\w+)>(.*?)(<else:\7\/>(.*?))?<\/ife:\7>)/m
20
22
 
21
23
  RIG_TEMPLATES = /(<(blk):(\w+(?:@\w+)?)(?:\[(\w+=[^,\]]+(?:,\w+=[^,\]]+)*)\])?\/>)|(<(iblk):(\w+):(\w+(?:@\w+)?)(?:\[(\w+=[^,\]]+(?:,\w+=[^,\]]+)*)\])?:(\w+(?:@\w+)?)(?:\[(\w+=[^,\]]+(?:,\w+=[^,\]]+)*)\])?\/>)|(<(static):(\w+(?:@\w+)?)(?:\[(\w+=[^,\]]+(?:,\w+=[^,\]]+)*)\])?\/>)/
22
24
 
23
-
24
25
  end
25
26
  end
26
27
  end
@@ -4,16 +4,26 @@ require 'forwardable'
4
4
  require 'fileutils'
5
5
  require 'tzispa/utils/string'
6
6
  require 'tzispa/utils/indenter'
7
+ require 'tzispa/rig/parameters'
8
+ require 'tzispa/rig/parsernext'
9
+ require 'tzispa/rig/binder'
7
10
 
8
11
  module Tzispa
9
12
  module Rig
10
13
 
11
- class NotFound < NameError; end
14
+ class NotFound < NameError
15
+ def initialize(filename)
16
+ super "Template file '#{filename}' not found"
17
+ end
18
+ end
12
19
 
13
- class ReadError < IOError; end
20
+ class ReadError < IOError
21
+ def initialize(file)
22
+ super "Template file '#{file}' could not be read"
23
+ end
24
+ end
14
25
 
15
26
  class TemplateBase
16
-
17
27
  attr_reader :content
18
28
 
19
29
  def initialize
@@ -41,14 +51,12 @@ module Tzispa
41
51
  self
42
52
  end
43
53
 
44
- def render(context, binder=nil)
45
- ""
54
+ def render(_context, _binder = nil)
55
+ ''
46
56
  end
47
-
48
57
  end
49
58
 
50
59
  class File < TemplateBase
51
-
52
60
  attr_reader :filename, :encoding
53
61
 
54
62
  def initialize(name, encoding: 'UTF-8')
@@ -67,33 +75,27 @@ module Tzispa
67
75
  end
68
76
 
69
77
  def load!
70
- raise NotFound.new("Template file '#{filename}' not found") unless exist?
71
- ::File.open(filename, "r:#{encoding}") { |f|
78
+ raise Tzispa::Rig::NotFound.new(filename) unless exist?
79
+ ::File.open(filename, "r:#{encoding}") do |f|
72
80
  @content = String.new
73
81
  @modified = f.mtime
74
- f.each { |line|
75
- @content << line
76
- }
82
+ f.each { |line| @content << line }
77
83
  @loaded = true
78
- }
84
+ end
79
85
  self
80
86
  rescue Errno::ENOENT
81
- raise ReadError.new "Template file '#{@file}' could not be read"
87
+ raise Tzispa::Rig::ReadError.new(@file)
82
88
  end
83
89
 
84
- def create(content=nil)
85
- ::File.open(filename, "w:#{encoding}") { |f|
86
- f.puts content
87
- }
90
+ def create(content = nil)
91
+ ::File.open(filename, "w:#{encoding}") { |f| f.puts content }
88
92
  end
89
-
90
93
  end
91
94
 
92
-
93
95
  class Template < File
94
96
  extend Forwardable
95
97
 
96
- using Tzispa::Utils
98
+ using Tzispa::Utils::TzString
97
99
 
98
100
  BASIC_TYPES = [:layout, :block, :static].freeze
99
101
  RIG_EXTENSION = 'rig'
@@ -103,10 +105,7 @@ module Tzispa
103
105
 
104
106
  def initialize(name:, type:, domain:, content_type:, params: nil)
105
107
  @id = name
106
- name.downcase.split('@').tap { |sdn|
107
- @subdomain = sdn.length > 1 ? sdn.first : nil
108
- @name = sdn.last
109
- }
108
+ build_name name
110
109
  @domain = domain
111
110
  @content_type = content_type
112
111
  @params = Parameters.new(params)
@@ -115,22 +114,23 @@ module Tzispa
115
114
  end
116
115
 
117
116
  def parse!
118
- @parser = ParserNext.new self, domain: domain, content_type: content_type, bindable: bindable?
117
+ @parser = ParserNext.new template: self,
118
+ domain: domain,
119
+ content_type: content_type,
120
+ bindable: bindable?
119
121
  parser.parse!
120
122
  self
121
123
  end
122
124
 
123
125
  def modified?
124
- super || (parser && parser.childrens.index { |tpl|
125
- tpl.modified?
126
- })
126
+ super || (parser && parser.childrens.index(&:modified?))
127
127
  end
128
128
 
129
129
  def valid?
130
130
  !content.empty? && !parser.empty?
131
131
  end
132
132
 
133
- def render(context, binder=nil)
133
+ def render(context, binder = nil)
134
134
  parse! unless parser
135
135
  binder ||= TemplateBinder.for self, context
136
136
  binder.bind! if binder&.respond_to?(:bind!)
@@ -141,7 +141,7 @@ module Tzispa
141
141
  @path ||= "#{domain.path}/view/#{subdomain || '_'}/#{type.to_s.downcase}"
142
142
  end
143
143
 
144
- def create(content='')
144
+ def create(content = '')
145
145
  FileUtils.mkdir_p(path) unless Dir.exist? path
146
146
  super(content)
147
147
  create_binder
@@ -192,38 +192,42 @@ module Tzispa
192
192
 
193
193
  private
194
194
 
195
+ def build_name(name)
196
+ name.to_s.downcase.split('@').tap do |sdn|
197
+ @subdomain = sdn.first if sdn.length > 1
198
+ @name = sdn.last
199
+ end
200
+ end
201
+
195
202
  def type=(value)
196
- raise ArgumentError.new("#{value} is not a Rig block") unless BASIC_TYPES.include?(value)
203
+ raise ArgumentError("#{value} is not a Rig block") unless BASIC_TYPES.include?(value)
197
204
  @type = value
198
205
  end
199
206
 
200
207
  def create_binder
201
- ::File.open("#{domain.path}/#{binder_require}.rb", "w") { |f|
208
+ return unless [:block, :layout].include?(type)
209
+ ::File.open("#{domain.path}/#{binder_require}.rb", 'w') do |f|
202
210
  f.puts write_binder_code
203
- } if type == :block
211
+ end
204
212
  end
205
213
 
206
214
  def write_binder_code
207
- Tzispa::Utils::Indenter.new(2).tap { |binder_code|
215
+ Tzispa::Utils::Indenter.new(2).tap do |binder_code|
208
216
  binder_code << "require 'tzispa/rig/binder'\n\n"
209
217
  level = 0
210
- binder_namespace.split('::').each { |ns|
211
- binder_code.indent if level > 0
218
+ binder_namespace.split('::').each do |ns|
219
+ binder_code.indent if level.positive?
212
220
  binder_code << "module #{ns}\n"
213
221
  level += 1
214
- }
222
+ end
215
223
  binder_code.indent << "\nclass #{binder_class_name} < Tzispa::Rig::TemplateBinder\n\n"
216
224
  binder_code.indent << "def bind!\n"
217
225
  binder_code << "end\n\n"
218
226
  binder_code.unindent << "end\n"
219
- binder_namespace.split('::').each { |ns|
220
- binder_code.unindent << "end\n"
221
- }
222
- }.to_s
227
+ binder_namespace.split('::').each { binder_code.unindent << "end\n" }
228
+ end.to_s
223
229
  end
224
-
225
230
  end
226
231
 
227
-
228
232
  end
229
233
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'forwardable'
4
+ require 'tzispa/utils/string'
4
5
 
5
6
  module Tzispa
6
7
  module Rig
@@ -8,6 +9,8 @@ module Tzispa
8
9
  class Token
9
10
  extend Forwardable
10
11
 
12
+ using Tzispa::Utils::TzString
13
+
11
14
  RE_ANCHOR = /(\$\$\h+\$\$)/
12
15
 
13
16
  attr_reader :type, :parser
@@ -18,33 +21,15 @@ module Tzispa
18
21
  @type = type
19
22
  end
20
23
 
21
- def self.instance(parser, type, match)
22
- case type
23
- when :meta
24
- TypeToken::Meta.new parser, type, match[1]
25
- when :var
26
- TypeToken::Var.new parser, type, match[1], match[2]
27
- when :url
28
- TypeToken::Url.new parser, match[1].to_sym, match[3], match[5], match[2]&.slice(1..-1)
29
- when :api
30
- TypeToken::Api.new parser, match[1].to_sym, match[3], match[4], match[5], match[6], match[2]&.slice(1..-1)
31
- when :loop
32
- TypeToken::Loop.new parser, type, match[3], match[4]
33
- when :ife
34
- TypeToken::Ife.new parser, type, match[7], match[8], match[10]
35
- when :blk
36
- TypeToken::Block.new parser, type, match[3], match[4]
37
- when :iblk
38
- TypeToken::IBlock.new parser, type, match[7], match[8], match[9], match[10], match[11]
39
- when :static
40
- TypeToken::Static.new parser, type, match[14], match[15]
24
+ class << self
25
+ def instance(parser, type, match)
26
+ "Tzispa::Rig::TypeToken::#{type.to_s.capitalize}".constantize.new parser, match
41
27
  end
42
28
  end
43
29
 
44
30
  def anchor
45
- @anchor ||= "$$#{"%x" % object_id}$$".freeze
31
+ @anchor ||= "$$#{format '%x', object_id}$$"
46
32
  end
47
-
48
33
  end
49
34
 
50
35
  require 'tzispa/rig/type_token/api_url'
@@ -52,6 +37,5 @@ module Tzispa
52
37
  require 'tzispa/rig/type_token/statement'
53
38
  require 'tzispa/rig/type_token/block'
54
39
 
55
-
56
40
  end
57
- end
41
+ end
@@ -5,14 +5,13 @@ module Tzispa
5
5
  module TypeToken
6
6
 
7
7
  class Url < Rig::Token
8
-
9
8
  attr_reader :layout, :params, :app_name
10
9
 
11
- def initialize(parser, type, layout, params, app_name = nil)
12
- super(parser, type)
13
- @layout = layout
14
- @params = params
15
- @app_name = app_name&.to_sym
10
+ def initialize(parser, match)
11
+ super(parser, match[1].to_sym)
12
+ @layout = match[3]
13
+ @params = match[5]
14
+ @app_name = match[2]&.slice(1..-1)&.to_sym
16
15
  end
17
16
 
18
17
  def render(binder)
@@ -27,55 +26,55 @@ module Tzispa
27
26
  end
28
27
 
29
28
  def render_purl(binder, app_name, b_layout, h_params)
30
- app_name ?
31
- binder.context.app_layout_path(app_name, b_layout, h_params) :
29
+ if app_name
30
+ binder.context.app_layout_path(app_name, b_layout, h_params)
31
+ else
32
32
  binder.context.layout_path(b_layout, h_params)
33
+ end
33
34
  end
34
35
 
35
36
  def render_url(binder, app_name, b_layout, h_params)
36
- app_name ?
37
- binder.context.app_layout_canonical_url(app_name, b_layout, h_params) :
37
+ if app_name
38
+ binder.context.app_layout_canonical_url(app_name, b_layout, h_params)
39
+ else
38
40
  binder.context.layout_canonical_url(b_layout, h_params)
41
+ end
39
42
  end
40
43
 
41
44
  def bind_value(value, binder)
42
- value&.gsub(RE_ANCHOR) { |match|
43
- parser.tokens.select { |p| p.anchor == match}.first.render(binder)
44
- }
45
+ value&.gsub(RE_ANCHOR) do |match|
46
+ parser.tokens.select { |p| p.anchor == match }.first.render(binder)
47
+ end
45
48
  end
46
-
47
49
  end
48
50
 
49
-
50
51
  class Api < Rig::Token
51
-
52
52
  attr_reader :handler, :verb, :predicate, :app_name
53
53
 
54
- def initialize(parser, type, handler, verb, predicate, sufix, app_name = nil)
55
- super(parser, type)
56
- @handler = handler
57
- @verb = verb
58
- @predicate = predicate
59
- @sufix = sufix
60
- @app_name = app_name&.to_sym
54
+ def initialize(parser, match)
55
+ super(parser, match[1].to_sym)
56
+ @handler = match[3]
57
+ @verb = match[4]
58
+ @predicate = match[5]
59
+ @sufix = match[6]
60
+ @app_name = match[2]&.slice(1..-1)&.to_sym
61
61
  end
62
62
 
63
63
  def render(binder)
64
64
  b_handler = bind_value @handler.dup, binder
65
65
  b_verb = bind_value @verb.dup, binder
66
- b_predicate = bind_value( @predicate.dup, binder ) if @predicate
67
- b_sufix = bind_value( @sufix.dup, binder ) if @sufix
66
+ b_predicate = bind_value(@predicate.dup, binder) if @predicate
67
+ b_sufix = bind_value(@sufix.dup, binder) if @sufix
68
68
  binder.context.send(type.to_sym, b_handler, b_verb, b_predicate, b_sufix, app_name)
69
69
  end
70
70
 
71
71
  private
72
72
 
73
73
  def bind_value(value, binder)
74
- value.gsub(RE_ANCHOR) { |match|
75
- parser.tokens.select { |p| p.anchor == match}.first.render(binder)
76
- }
74
+ value.gsub(RE_ANCHOR) do |match|
75
+ parser.tokens.select { |p| p.anchor == match }.first.render(binder)
76
+ end
77
77
  end
78
-
79
78
  end
80
79
 
81
80
  end
@@ -4,14 +4,13 @@ module Tzispa
4
4
  module Rig
5
5
  module TypeToken
6
6
 
7
- class Block < Rig::Token
8
-
7
+ class Blk < Rig::Token
9
8
  attr_reader :id, :params
10
9
 
11
- def initialize(parser, type, id, params)
12
- super(parser, type)
13
- @id = id
14
- @params = params
10
+ def initialize(parser, match)
11
+ super(parser, :blk)
12
+ @id = match[3]
13
+ @params = match[4]
15
14
  end
16
15
 
17
16
  def parse!
@@ -30,9 +29,10 @@ module Tzispa
30
29
  private
31
30
 
32
31
  def bind_value(value, binder)
33
- value.gsub(RE_ANCHOR) { |match|
34
- parser.tokens.select { |p| p.anchor == match}.first.render(binder)
35
- }
32
+ value.gsub(RE_ANCHOR) do |match|
33
+ anchor = parser.tokens.select { |p| p.anchor == match }
34
+ anchor.first.render(binder)
35
+ end
36
36
  end
37
37
 
38
38
  def obtain_block(id)
@@ -41,29 +41,27 @@ module Tzispa
41
41
  Rig::Engine.empty
42
42
  when template&.id
43
43
  # to avoid infinite recursion
44
- template&.type == :block ?
45
- template :
44
+ if template&.type == :block
45
+ template
46
+ else
46
47
  Rig::Engine.block(name: id, domain: domain, content_type: content_type)
48
+ end
47
49
  else
48
50
  Rig::Engine.block(name: id, domain: domain, content_type: content_type)
49
51
  end
50
52
  end
51
-
52
-
53
53
  end
54
54
 
55
-
56
- class IBlock < Rig::Token
57
-
55
+ class Iblk < Rig::Token
58
56
  attr_reader :id, :id_then, :params_then, :id_else, :params_else
59
57
 
60
- def initialize(parser, type, test, id_then, params_then, id_else, params_else)
61
- super(parser, type)
62
- @id = test
63
- @id_then = id_then
64
- @params_then = params_then
65
- @id_else = id_else
66
- @params_else = params_else
58
+ def initialize(parser, match)
59
+ super(parser, :iblk)
60
+ @id = match[7]
61
+ @id_then = match[8]
62
+ @params_then = match[9]
63
+ @id_else = match[10]
64
+ @params_else = match[11]
67
65
  end
68
66
 
69
67
  def parse!
@@ -92,53 +90,57 @@ module Tzispa
92
90
  Rig::Engine.empty
93
91
  when template&.id
94
92
  # to avoid infinite recursion
95
- template&.type == :block ?
96
- template :
93
+ if template&.type == :block
94
+ template
95
+ else
97
96
  Rig::Engine.block(name: id, domain: domain, content_type: content_type)
97
+ end
98
98
  else
99
99
  Rig::Engine.block(name: id, domain: domain, content_type: content_type)
100
100
  end
101
101
  end
102
102
 
103
103
  def bind_value(value, binder)
104
- value.gsub(RE_ANCHOR) { |match|
105
- parser.tokens.select { |p| p.anchor == match}.first.render(binder)
106
- }
104
+ value.gsub(RE_ANCHOR) do |match|
105
+ anchor = parser.tokens.select { |p| p.anchor == match }
106
+ anchor.first.render(binder)
107
+ end
107
108
  end
108
-
109
109
  end
110
110
 
111
-
112
111
  class Static < Rig::Token
113
-
114
112
  attr_reader :id, :params
115
113
 
116
- def initialize(parser, type, id, params)
117
- super(parser, type)
118
- @id = id
119
- @params = params
114
+ def initialize(parser, match)
115
+ super(parser, :static)
116
+ @id = match[14]
117
+ @params = match[15]
120
118
  end
121
119
 
122
120
  def parse!
123
- @parsed_static = Tzispa::Rig::Engine.static name: @id, domain: domain, content_type: content_type
121
+ @parsed_static = Tzispa::Rig::Engine.static name: @id,
122
+ domain: domain,
123
+ content_type: content_type
124
124
  parser.childrens << @parsed_static
125
125
  self
126
126
  end
127
127
 
128
128
  def render(binder)
129
129
  blk = @parsed_static.dup
130
- if @params
131
- b_params = @params.dup.gsub(RE_ANCHOR) { |match|
132
- parser.tokens.select { |p| p.anchor == match}.first.render(binder)
133
- }
134
- blk.params = b_params
135
- end
130
+ blk.params = bind_value(@params.dup, binder) if @params
136
131
  blk.render binder.context
137
132
  end
138
133
 
139
- end
134
+ private
140
135
 
136
+ def bind_value(value, binder)
137
+ value.gsub(RE_ANCHOR) do |match|
138
+ anchor = parser.tokens.select { |p| p.anchor == match }
139
+ anchor.first.render(binder)
140
+ end
141
+ end
142
+ end
141
143
 
142
144
  end
143
145
  end
144
- end
146
+ end
@@ -7,12 +7,11 @@ module Tzispa
7
7
  module TypeToken
8
8
 
9
9
  class Meta < Rig::Token
10
-
11
10
  attr_reader :id
12
11
 
13
- def initialize(parser, type, id)
14
- super(parser, type)
15
- @id = id.to_sym
12
+ def initialize(parser, match)
13
+ super(parser, :meta)
14
+ @id = match[1].to_sym
16
15
  end
17
16
 
18
17
  def render(binder)
@@ -26,21 +25,19 @@ module Tzispa
26
25
  private
27
26
 
28
27
  def unknown
29
- @unknown ||= "#{@id}"
28
+ @unknown ||= id.to_s
30
29
  end
31
-
32
30
  end
33
31
 
34
-
35
32
  class Var < Rig::Token
36
- using Tzispa::Utils
33
+ using Tzispa::Utils::TzString
37
34
 
38
35
  attr_reader :id
39
36
 
40
- def initialize(parser, type, format, id)
41
- super(parser, type)
42
- @format = format
43
- @id = id.to_sym
37
+ def initialize(parser, match)
38
+ super(parser, :var)
39
+ @format = match[1]
40
+ @id = match[2].to_sym
44
41
  end
45
42
 
46
43
  def render(binder)
@@ -55,11 +52,10 @@ module Tzispa
55
52
  private
56
53
 
57
54
  def unknown
58
- @unknown ||= "#{@id}"
55
+ @unknown ||= @id.to_s
59
56
  end
60
-
61
57
  end
62
58
 
63
59
  end
64
60
  end
65
- end
61
+ end
@@ -12,52 +12,65 @@ module Tzispa
12
12
  attr_reader :id, :body_parser
13
13
  def_delegators :@body_parser, :attribute_tags, :loop_parser
14
14
 
15
- def initialize(parser, type, id, body)
16
- super(parser, type)
17
- @id = id.to_sym
18
- @body = body
15
+ def initialize(parser, match)
16
+ super(parser, :loop)
17
+ @id = match[3].to_sym
18
+ @body = match[4]
19
19
  end
20
20
 
21
21
  def parse!
22
- @body_parser = Rig::ParserNext.new(template, text: @body, parent: parser, bindable: true ).parse!
22
+ @body_parser = Rig::ParserNext.new template: template,
23
+ text: @body,
24
+ parent: parser,
25
+ bindable: true
26
+ @body_parser.parse!
23
27
  self
24
28
  end
25
29
 
26
30
  def render(binder)
27
- String.new.tap { |text|
31
+ String.new.tap do |text|
28
32
  looper = binder.data.send(@id) if binder.data.respond_to?(@id)
29
- looper&.data&.each { |loop_item|
33
+ looper&.data&.each do |loop_item|
30
34
  text << body_parser.render(loop_item) if loop_item
31
- } if looper
32
- }
35
+ end
36
+ end
33
37
  end
34
-
35
38
  end
36
39
 
37
-
38
40
  class Ife < Rig::Token
39
-
40
41
  attr_reader :test, :then_parser, :else_parser
41
42
 
42
- def initialize(parser, type, test, then_body, else_body)
43
- super(parser, type)
44
- @test = test.to_sym
45
- @then_body = then_body
46
- @else_body = else_body
43
+ def initialize(parser, match)
44
+ super(parser, :ife)
45
+ @test = match[7].to_sym
46
+ @then_body = match[8]
47
+ @else_body = match[10]
47
48
  end
48
49
 
49
50
  def parse!
50
- @then_parser = Rig::ParserNext.new(template, text: @then_body, parent: parser ).parse!
51
- @else_parser = @else_body ? Rig::ParserNext.new(template, text: @else_body, parent: parser ).parse! : nil
51
+ @then_parser = Rig::ParserNext.new(template: template,
52
+ text: @then_body,
53
+ parent: parser).parse!
54
+ @else_parser = if @else_body
55
+ Rig::ParserNext.new(template: template,
56
+ text: @else_body,
57
+ parent: parser).parse!
58
+ end
52
59
  self
53
60
  end
54
61
 
55
62
  def attribute_tags
56
- @attribute_tags ||= [test].concat(then_parser.attribute_tags).concat(else_parser&.attribute_tags || Array.new).compact.uniq.freeze
63
+ @attribute_tags ||= begin
64
+ att = [test].concat(then_parser.attribute_tags)
65
+ att.concat(else_parser&.attribute_tags || [])
66
+ att.compact.uniq.freeze
67
+ end
57
68
  end
58
69
 
59
70
  def loop_parser(id)
60
- @then_parser.loop_parser(id).concat(else_parser&.loop_parser(id) || Array.new).compact.freeze
71
+ lpp = then_parser.loop_parser(id)
72
+ lpp.concat(else_parser&.loop_parser(id) || [])
73
+ lpp.compact.freeze
61
74
  end
62
75
 
63
76
  def render(binder)
@@ -65,9 +78,8 @@ module Tzispa
65
78
  ifeparser = test_eval ? then_parser : else_parser
66
79
  ifeparser ? ifeparser.render(binder) : ''
67
80
  end
68
-
69
81
  end
70
82
 
71
83
  end
72
84
  end
73
- end
85
+ end
@@ -3,7 +3,7 @@
3
3
  module Tzispa
4
4
  module Rig
5
5
 
6
- VERSION = '0.5.0'
6
+ VERSION = '0.5.1'
7
7
  GEM_NAME = 'tzispa_rig'
8
8
 
9
9
  end
@@ -212,10 +212,10 @@ class ParsernextTest < Minitest::Test
212
212
  parser = Tzispa::Rig::ParserNext.new text: TPL_BLK, domain: domain, content_type: :htm, bindable: true
213
213
  parser.parse!
214
214
  assert_equal parser.tokens.count, 5
215
- assert_instance_of Tzispa::Rig::TypeToken::Block, parser.tokens[1]
216
- assert_instance_of Tzispa::Rig::TypeToken::Block, parser.tokens[2]
217
- assert_instance_of Tzispa::Rig::TypeToken::IBlock, parser.tokens[3]
218
- assert_instance_of Tzispa::Rig::TypeToken::IBlock, parser.tokens[4]
215
+ assert_instance_of Tzispa::Rig::TypeToken::Blk, parser.tokens[1]
216
+ assert_instance_of Tzispa::Rig::TypeToken::Blk, parser.tokens[2]
217
+ assert_instance_of Tzispa::Rig::TypeToken::Iblk, parser.tokens[3]
218
+ assert_instance_of Tzispa::Rig::TypeToken::Iblk, parser.tokens[4]
219
219
  assert_equal parser.tokens[1].id, 'detail'
220
220
  assert_equal parser.tokens[2].id, 'product@detail'
221
221
  assert_equal parser.tokens[2].params, "tab=#{parser.tokens[0].anchor}"
@@ -0,0 +1 @@
1
+ This is a layout template file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tzispa_rig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Antonio Piñero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-13 00:00:00.000000000 Z
11
+ date: 2017-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzispa_utils
@@ -79,6 +79,7 @@ files:
79
79
  - test/engine_test.rb
80
80
  - test/parameters_test.rb
81
81
  - test/parsernext_test.rb
82
+ - test/res/apps/test_domain/view/_/layout/index.rig.txt
82
83
  - test/res/apps/test_domain/view/product/layout/list.rig.htm
83
84
  - test/template_test.rb
84
85
  - test/test_helper.rb