liquid 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,7 +42,7 @@ module Liquid
42
42
  # forloop.last:: Returns true if the item is the last item.
43
43
  #
44
44
  class For < Block
45
- Syntax = /(\w+)\s+in\s+(#{Expression}+)\s*(reversed)?/
45
+ Syntax = /(\w+)\s+in\s+(#{QuotedFragment}+)\s*(reversed)?/
46
46
 
47
47
  def initialize(tag_name, markup, tokens)
48
48
  if markup =~ Syntax
@@ -13,7 +13,8 @@ module Liquid
13
13
  #
14
14
  class If < Block
15
15
  SyntaxHelp = "Syntax Error in tag 'if' - Valid syntax: if [expression]"
16
- Syntax = /(#{Expression})\s*([=!<>a-z_]+)?\s*(#{Expression})?/
16
+ Syntax = /(#{QuotedFragment})\s*([=!<>a-z_]+)?\s*(#{QuotedFragment})?/
17
+ ExpressionsAndOperators = /(?:and|or|(?:\s*(?!\b(?:and|or)\b)(?:#{QuotedFragment}|\S+)\s*)+)/
17
18
 
18
19
  def initialize(tag_name, markup, tokens)
19
20
 
@@ -50,7 +51,7 @@ module Liquid
50
51
  ElseCondition.new
51
52
  else
52
53
 
53
- expressions = markup.split(/\b(and|or)\b/).reverse
54
+ expressions = markup.scan(ExpressionsAndOperators).reverse
54
55
  raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax
55
56
 
56
57
  condition = Condition.new($1, $2, $3)
@@ -24,7 +24,8 @@ module Liquid
24
24
  end
25
25
 
26
26
  def render(context)
27
- source = Liquid::Template.file_system.read_template_file(context[@template_name])
27
+ file_system = context.registers[:file_system] || Liquid::Template.file_system
28
+ source = file_system.read_template_file(context[@template_name])
28
29
  partial = Liquid::Template.parse(source)
29
30
 
30
31
  variable = context[@variable_name || @template_name[1..-2]]
@@ -1,120 +1,123 @@
1
1
  module Liquid
2
2
 
3
- # Templates are central to liquid.
4
- # Interpretating templates is a two step process. First you compile the
5
- # source code you got. During compile time some extensive error checking is performed.
6
- # your code should expect to get some SyntaxErrors.
3
+ # Templates are central to liquid.
4
+ # Interpretating templates is a two step process. First you compile the
5
+ # source code you got. During compile time some extensive error checking is performed.
6
+ # your code should expect to get some SyntaxErrors.
7
7
  #
8
- # After you have a compiled template you can then <tt>render</tt> it.
9
- # You can use a compiled template over and over again and keep it cached.
8
+ # After you have a compiled template you can then <tt>render</tt> it.
9
+ # You can use a compiled template over and over again and keep it cached.
10
+ #
11
+ # Example:
10
12
  #
11
- # Example:
12
- #
13
13
  # template = Liquid::Template.parse(source)
14
14
  # template.render('user_name' => 'bob')
15
15
  #
16
16
  class Template
17
17
  attr_accessor :root
18
18
  @@file_system = BlankFileSystem.new
19
-
20
- class <<self
19
+
20
+ class << self
21
21
  def file_system
22
22
  @@file_system
23
23
  end
24
-
24
+
25
25
  def file_system=(obj)
26
26
  @@file_system = obj
27
27
  end
28
-
29
- def register_tag(name, klass)
28
+
29
+ def register_tag(name, klass)
30
30
  tags[name.to_s] = klass
31
- end
32
-
31
+ end
32
+
33
33
  def tags
34
34
  @tags ||= {}
35
35
  end
36
-
37
- # Pass a module with filter methods which should be available
36
+
37
+ # Pass a module with filter methods which should be available
38
38
  # to all liquid views. Good for registering the standard library
39
- def register_filter(mod)
39
+ def register_filter(mod)
40
40
  Strainer.global_filter(mod)
41
- end
42
-
41
+ end
42
+
43
43
  # creates a new <tt>Template</tt> object from liquid source code
44
44
  def parse(source)
45
45
  template = Template.new
46
46
  template.parse(source)
47
47
  template
48
- end
48
+ end
49
49
  end
50
50
 
51
51
  # creates a new <tt>Template</tt> from an array of tokens. Use <tt>Template.parse</tt> instead
52
52
  def initialize
53
53
  end
54
-
55
- # Parse source code.
56
- # Returns self for easy chaining
54
+
55
+ # Parse source code.
56
+ # Returns self for easy chaining
57
57
  def parse(source)
58
58
  @root = Document.new(tokenize(source))
59
59
  self
60
60
  end
61
-
62
- def registers
61
+
62
+ def registers
63
63
  @registers ||= {}
64
64
  end
65
-
65
+
66
66
  def assigns
67
67
  @assigns ||= {}
68
68
  end
69
-
69
+
70
+ def instance_assigns
71
+ @instance_assigns ||= {}
72
+ end
73
+
70
74
  def errors
71
75
  @errors ||= []
72
76
  end
73
-
77
+
74
78
  # Render takes a hash with local variables.
75
79
  #
76
- # if you use the same filters over and over again consider registering them globally
80
+ # if you use the same filters over and over again consider registering them globally
77
81
  # with <tt>Template.register_filter</tt>
78
- #
82
+ #
79
83
  # Following options can be passed:
80
- #
84
+ #
81
85
  # * <tt>filters</tt> : array with local filters
82
- # * <tt>registers</tt> : hash with register variables. Those can be accessed from
83
- # filters and tags and might be useful to integrate liquid more with its host application
86
+ # * <tt>registers</tt> : hash with register variables. Those can be accessed from
87
+ # filters and tags and might be useful to integrate liquid more with its host application
84
88
  #
85
89
  def render(*args)
86
- return '' if @root.nil?
87
-
90
+ return '' if @root.nil?
91
+
88
92
  context = case args.first
89
93
  when Liquid::Context
90
94
  args.shift
91
95
  when Hash
92
- self.assigns.merge!(args.shift)
93
- Context.new(assigns, registers, @rethrow_errors)
96
+ Context.new([args.shift, assigns], instance_assigns, registers, @rethrow_errors)
94
97
  when nil
95
- Context.new(assigns, registers, @rethrow_errors)
98
+ Context.new(assigns, instance_assigns, registers, @rethrow_errors)
96
99
  else
97
100
  raise ArgumentError, "Expect Hash or Liquid::Context as parameter"
98
101
  end
99
-
102
+
100
103
  case args.last
101
104
  when Hash
102
105
  options = args.pop
103
-
106
+
104
107
  if options[:registers].is_a?(Hash)
105
- self.registers.merge!(options[:registers])
108
+ self.registers.merge!(options[:registers])
106
109
  end
107
110
 
108
111
  if options[:filters]
109
112
  context.add_filters(options[:filters])
110
- end
111
-
113
+ end
114
+
112
115
  when Module
113
- context.add_filters(args.pop)
116
+ context.add_filters(args.pop)
114
117
  when Array
115
- context.add_filters(args.pop)
118
+ context.add_filters(args.pop)
116
119
  end
117
-
120
+
118
121
  begin
119
122
  # render the nodelist.
120
123
  # for performance reasons we get a array back here. join will make a string out of it
@@ -123,24 +126,24 @@ module Liquid
123
126
  @errors = context.errors
124
127
  end
125
128
  end
126
-
129
+
127
130
  def render!(*args)
128
131
  @rethrow_errors = true; render(*args)
129
132
  end
130
-
133
+
131
134
  private
132
-
135
+
133
136
  # Uses the <tt>Liquid::TemplateParser</tt> regexp to tokenize the passed source
134
137
  def tokenize(source)
135
- source = source.source if source.respond_to?(:source)
138
+ source = source.source if source.respond_to?(:source)
136
139
  return [] if source.to_s.empty?
137
140
  tokens = source.split(TemplateParser)
138
141
 
139
142
  # removes the rogue empty element at the beginning of the array
140
- tokens.shift if tokens[0] and tokens[0].empty?
143
+ tokens.shift if tokens[0] and tokens[0].empty?
141
144
 
142
145
  tokens
143
146
  end
144
-
145
- end
147
+
148
+ end
146
149
  end
@@ -11,17 +11,18 @@ module Liquid
11
11
  # {{ user | link }}
12
12
  #
13
13
  class Variable
14
+ FilterParser = /(?:#{FilterSeparator}|(?:\s*(?!(?:#{FilterSeparator}))(?:#{QuotedFragment}|\S+)\s*)+)/
14
15
  attr_accessor :filters, :name
15
16
 
16
17
  def initialize(markup)
17
18
  @markup = markup
18
19
  @name = nil
19
20
  @filters = []
20
- if match = markup.match(/\s*(#{QuotedFragment})/)
21
+ if match = markup.match(/\s*(#{QuotedFragment})(.*)/)
21
22
  @name = match[1]
22
- if markup.match(/#{FilterSeparator}\s*(.*)/)
23
- filters = Regexp.last_match(1).split(/#{FilterSeparator}/)
24
- filters.each do |f|
23
+ if match[2].match(/#{FilterSeparator}\s*(.*)/)
24
+ filters = Regexp.last_match(1).scan(FilterParser)
25
+ filters.each do |f|
25
26
  if matches = f.match(/\s*(\w+)/)
26
27
  filtername = matches[1]
27
28
  filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*(#{QuotedFragment})/).flatten
@@ -34,8 +35,7 @@ module Liquid
34
35
 
35
36
  def render(context)
36
37
  return '' if @name.nil?
37
- output = context[@name]
38
- @filters.inject(output) do |output, filter|
38
+ @filters.inject(context[@name]) do |output, filter|
39
39
  filterargs = filter[1].to_a.collect do |a|
40
40
  context[a]
41
41
  end
@@ -45,7 +45,6 @@ module Liquid
45
45
  raise FilterNotFound, "Error - filter '#{filter[0]}' in '#{@markup.strip}' could not be found."
46
46
  end
47
47
  end
48
- output
49
48
  end
50
49
  end
51
- end
50
+ end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: liquid
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ hash: 11
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 1
9
+ - 0
10
+ version: 2.1.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Tobias Luetke
@@ -9,20 +15,11 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-03-10 00:00:00 -04:00
18
+ date: 2009-04-13 00:00:00 -04:00
13
19
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: hoe
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 1.8.2
24
- version:
25
- description: A secure non evaling end user template engine with aesthetic markup.
20
+ dependencies: []
21
+
22
+ description: A secure, non-evaling end user template engine with aesthetic markup.
26
23
  email: tobi@leetsoft.com
27
24
  executables: []
28
25
 
@@ -39,7 +36,6 @@ files:
39
36
  - Manifest.txt
40
37
  - README.txt
41
38
  - Rakefile
42
- - init.rb
43
39
  - lib/extras/liquid_view.rb
44
40
  - lib/liquid.rb
45
41
  - lib/liquid/block.rb
@@ -69,6 +65,8 @@ files:
69
65
  - lib/liquid/variable.rb
70
66
  has_rdoc: true
71
67
  homepage: http://www.liquidmarkup.org
68
+ licenses: []
69
+
72
70
  post_install_message:
73
71
  rdoc_options:
74
72
  - --main
@@ -76,23 +74,29 @@ rdoc_options:
76
74
  require_paths:
77
75
  - lib
78
76
  required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
79
78
  requirements:
80
79
  - - ">="
81
80
  - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
82
84
  version: "0"
83
- version:
84
85
  required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
85
87
  requirements:
86
88
  - - ">="
87
89
  - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
88
93
  version: "0"
89
- version:
90
94
  requirements: []
91
95
 
92
96
  rubyforge_project: liquid
93
- rubygems_version: 1.3.1
97
+ rubygems_version: 1.3.7
94
98
  signing_key:
95
99
  specification_version: 2
96
- summary: A secure non evaling end user template engine with aesthetic markup.
97
- test_files:
98
- - test/test_helper.rb
100
+ summary: A secure, non-evaling end user template engine with aesthetic markup.
101
+ test_files: []
102
+
data/init.rb DELETED
@@ -1,8 +0,0 @@
1
- require 'liquid'
2
- require 'extras/liquid_view'
3
-
4
- if defined? ActionView::Template and ActionView::Template.respond_to? :register_template_handler
5
- ActionView::Template
6
- else
7
- ActionView::Base
8
- end.register_template_handler(:liquid, LiquidView)
data/test/test_helper.rb DELETED
@@ -1,20 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $LOAD_PATH.unshift(File.dirname(__FILE__)+ '/extra')
3
-
4
- require 'test/unit'
5
- require 'test/unit/assertions'
6
- require 'caller'
7
- require 'breakpoint'
8
- require File.dirname(__FILE__) + '/../lib/liquid'
9
-
10
-
11
- module Test
12
- module Unit
13
- module Assertions
14
- include Liquid
15
- def assert_template_result(expected, template, assigns={}, message=nil)
16
- assert_equal expected, Template.parse(template).render(assigns)
17
- end
18
- end
19
- end
20
- end