tzispa_rig 0.5.0 → 0.5.1

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
  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