This commit is contained in:
Florian Weingarten
2015-05-14 14:37:18 +00:00
parent 8cf524e91c
commit 3372ca8136
84 changed files with 1069 additions and 908 deletions
+6 -6
View File
@@ -35,17 +35,17 @@ module Liquid
all_warnings
end
def unknown_tag(tag, params, tokens)
def unknown_tag(tag, _params, _tokens)
case tag
when 'else'.freeze
raise SyntaxError.new(options[:locale].t("errors.syntax.unexpected_else".freeze,
:block_name => block_name))
block_name: block_name))
when 'end'.freeze
raise SyntaxError.new(options[:locale].t("errors.syntax.invalid_delimiter".freeze,
:block_name => block_name,
:block_delimiter => block_delimiter))
block_name: block_name,
block_delimiter: block_delimiter))
else
raise SyntaxError.new(options[:locale].t("errors.syntax.unknown_tag".freeze, :tag => tag))
raise SyntaxError.new(options[:locale].t("errors.syntax.unknown_tag".freeze, tag: tag))
end
end
@@ -65,7 +65,7 @@ module Liquid
return false if end_tag_name == block_delimiter
unless end_tag_name
raise SyntaxError.new(@options[:locale].t("errors.syntax.tag_never_closed".freeze, :block_name => block_name))
raise SyntaxError.new(@options[:locale].t("errors.syntax.tag_never_closed".freeze, block_name: block_name))
end
# this tag is not registered with the system
+3 -3
View File
@@ -79,7 +79,7 @@ module Liquid
# If we get an Interrupt that means the block must stop processing. An
# Interrupt is any command that stops block execution such as {% break %}
# or {% continue %}
if token.is_a?(Continue) or token.is_a?(Break)
if token.is_a?(Continue) || token.is_a?(Break)
context.push_interrupt(token.interrupt)
break
end
@@ -121,11 +121,11 @@ module Liquid
end
def raise_missing_tag_terminator(token, options)
raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, :token => token, :tag_end => TagEnd.inspect))
raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, token: token, tag_end: TagEnd.inspect))
end
def raise_missing_variable_terminator(token, options)
raise SyntaxError.new(options[:locale].t("errors.syntax.variable_termination".freeze, :token => token, :tag_end => VariableEnd.inspect))
raise SyntaxError.new(options[:locale].t("errors.syntax.variable_termination".freeze, token: token, tag_end: VariableEnd.inspect))
end
end
end
+8 -12
View File
@@ -8,16 +8,16 @@ module Liquid
#
class Condition #:nodoc:
@@operators = {
'=='.freeze => lambda { |cond, left, right| cond.send(:equal_variables, left, right) },
'!='.freeze => lambda { |cond, left, right| !cond.send(:equal_variables, left, right) },
'<>'.freeze => lambda { |cond, left, right| !cond.send(:equal_variables, left, right) },
'=='.freeze => ->(cond, left, right) { cond.send(:equal_variables, left, right) },
'!='.freeze => ->(cond, left, right) { !cond.send(:equal_variables, left, right) },
'<>'.freeze => ->(cond, left, right) { !cond.send(:equal_variables, left, right) },
'<'.freeze => :<,
'>'.freeze => :>,
'>='.freeze => :>=,
'<='.freeze => :<=,
'contains'.freeze => lambda { |cond, left, right|
'contains'.freeze => lambda do |cond, left, right|
left && right && left.respond_to?(:include?) ? left.include?(right) : false
}
end
}
def self.operators
@@ -96,7 +96,7 @@ module Liquid
# If the operator is empty this means that the decision statement is just
# a single variable. We can just poll this variable from the context and
# return this as the result.
return context.evaluate(left) if op == nil
return context.evaluate(left) if op.nil?
left = context.evaluate(left)
right = context.evaluate(right)
@@ -105,27 +105,23 @@ module Liquid
if operation.respond_to?(:call)
operation.call(self, left, right)
elsif left.respond_to?(operation) and right.respond_to?(operation)
elsif left.respond_to?(operation) && right.respond_to?(operation)
begin
left.send(operation, right)
rescue ::ArgumentError => e
raise Liquid::ArgumentError.new(e.message)
end
else
nil
end
end
end
class ElseCondition < Condition
def else?
true
end
def evaluate(context)
def evaluate(_context)
true
end
end
end
+15 -17
View File
@@ -1,5 +1,4 @@
module Liquid
# Context keeps the variable stack and resolves variables, as well as keywords
#
# context['variable'] = 'testing'
@@ -63,8 +62,7 @@ module Liquid
@interrupts.pop
end
def handle_error(e, token=nil)
def handle_error(e, token = nil)
if e.is_a?(Liquid::Error)
e.set_line_number_from_token(token)
end
@@ -79,7 +77,7 @@ module Liquid
end
# Push new local scope on the stack. use <tt>Context#stack</tt> instead
def push(new_scope={})
def push(new_scope = {})
@scopes.unshift(new_scope)
raise StackLevelError, "Nesting too deep".freeze if @scopes.length > 100
end
@@ -103,7 +101,7 @@ module Liquid
# end
#
# context['var] #=> nil
def stack(new_scope=nil)
def stack(new_scope = nil)
old_stack_used = @this_stack_used
if new_scope
push(new_scope)
@@ -153,7 +151,6 @@ module Liquid
# Fetches an object starting at the local scope and then moving up the hierachy
def find_variable(key)
# This was changed from find() to find_index() because this is a very hot
# path and find_index() is optimized in MRI to reduce object allocation
index = @scopes.find_index { |s| s.has_key?(key) }
@@ -171,13 +168,13 @@ module Liquid
end
end
scope ||= @environments.last || @scopes.last
variable ||= lookup_and_evaluate(scope, key)
scope ||= @environments.last || @scopes.last
variable ||= lookup_and_evaluate(scope, key)
variable = variable.to_liquid
variable.context = self if variable.respond_to?(:context=)
return variable
variable
end
def lookup_and_evaluate(obj, key)
@@ -189,15 +186,16 @@ module Liquid
end
private
def squash_instance_assigns_with_environments
@scopes.last.each_key do |k|
@environments.each do |env|
if env.has_key?(k)
scopes.last[k] = lookup_and_evaluate(env, k)
break
end
def squash_instance_assigns_with_environments
@scopes.last.each_key do |k|
@environments.each do |env|
if env.has_key?(k)
scopes.last[k] = lookup_and_evaluate(env, k)
break
end
end
end # squash_instance_assigns_with_environments
end
end # squash_instance_assigns_with_environments
end # Context
end # Liquid
+2 -2
View File
@@ -15,9 +15,9 @@ module Liquid
def unknown_tag(tag, options)
case tag
when 'else'.freeze, 'end'.freeze
raise SyntaxError.new(options[:locale].t("errors.syntax.unexpected_outer_tag".freeze, :tag => tag))
raise SyntaxError.new(options[:locale].t("errors.syntax.unexpected_outer_tag".freeze, tag: tag))
else
raise SyntaxError.new(options[:locale].t("errors.syntax.unknown_tag".freeze, :tag => tag))
raise SyntaxError.new(options[:locale].t("errors.syntax.unknown_tag".freeze, tag: tag))
end
end
end
+4 -5
View File
@@ -1,7 +1,6 @@
require 'set'
module Liquid
# A drop in liquid is a class which allows you to export DOM like things to liquid.
# Methods of drops are callable.
# The main use for liquid drops is to implement lazy loaded objects.
@@ -27,7 +26,7 @@ module Liquid
EMPTY_STRING = ''.freeze
# Catch all for the method
def before_method(method)
def before_method(_method)
nil
end
@@ -40,7 +39,7 @@ module Liquid
end
end
def has_key?(name)
def has_key?(_name)
true
end
@@ -56,13 +55,13 @@ module Liquid
self.class.name
end
alias :[] :invoke_drop
alias_method :[], :invoke_drop
private
# Check for method existence without invoking respond_to?, which creates symbols
def self.invokable?(method_name)
self.invokable_methods.include?(method_name.to_s)
invokable_methods.include?(method_name.to_s)
end
def self.invokable_methods
+3 -3
View File
@@ -3,7 +3,7 @@ module Liquid
attr_accessor :line_number
attr_accessor :markup_context
def to_s(with_prefix=true)
def to_s(with_prefix = true)
str = ""
str << message_prefix if with_prefix
str << super()
@@ -18,7 +18,7 @@ module Liquid
def set_line_number_from_token(token)
return unless token.respond_to?(:line_number)
return if self.line_number
return if line_number
self.line_number = token.line_number
end
@@ -26,7 +26,7 @@ module Liquid
if e.is_a?(Liquid::Error)
e.to_s
else
"Liquid error: #{e.to_s}"
"Liquid error: #{e}"
end
end
-1
View File
@@ -28,6 +28,5 @@ module Liquid
end
end
end
end
end
+2 -2
View File
@@ -14,7 +14,7 @@ module Liquid
# This will parse the template with a LocalFileSystem implementation rooted at 'template_path'.
class BlankFileSystem
# Called by Liquid to retrieve a template file
def read_template_file(template_path)
def read_template_file(_template_path)
raise FileSystemError, "This liquid context does not allow includes."
end
end
@@ -51,7 +51,7 @@ module Liquid
def read_template_file(template_path)
full_path = full_path(template_path)
raise FileSystemError, "No such template '#{template_path}'" unless File.exists?(full_path)
raise FileSystemError, "No such template '#{template_path}'" unless File.exist?(full_path)
File.read(full_path)
end
+1
View File
@@ -22,6 +22,7 @@ module Liquid
end
private
def interpolate(name, vars)
name.gsub(/%\{(\w+)\}/) {
# raise TranslationError, "Undefined key #{$1} for interpolation in translation #{name}" unless vars[$1.to_sym]
+1 -2
View File
@@ -1,10 +1,9 @@
module Liquid
# An interrupt is any command that breaks processing of a block (ex: a for loop).
class Interrupt
attr_reader :message
def initialize(message=nil)
def initialize(message = nil)
@message = message || "interrupt".freeze
end
end
+2 -2
View File
@@ -27,7 +27,7 @@ module Liquid
def tokenize
@output = []
while !@ss.eos?
until @ss.eos?
@ss.skip(/\s*/)
tok = case
when t = @ss.scan(COMPARISON_OPERATOR) then [:comparison, t]
@@ -39,7 +39,7 @@ module Liquid
else
c = @ss.getch
if s = SPECIALS[c]
[s,c]
[s, c]
else
raise SyntaxError, "Unexpected character #{c}"
end
+4 -4
View File
@@ -43,17 +43,17 @@
#
class Module
def liquid_methods(*allowed_methods)
drop_class = eval "class #{self.to_s}::LiquidDropClass < Liquid::Drop; self; end"
drop_class = eval "class #{self}::LiquidDropClass < Liquid::Drop; self; end"
define_method :to_liquid do
drop_class.new(self)
end
drop_class.class_eval do
def initialize(object)
@object = object
end
allowed_methods.each do |sym|
define_method sym do
@object.send sym
+1
View File
@@ -17,6 +17,7 @@ module Liquid
end
private
def strict_parse_with_error_context(markup)
strict_parse(markup)
rescue SyntaxError => e
+2 -6
View File
@@ -1,7 +1,6 @@
require 'liquid/profiler/hooks'
module Liquid
# Profiler enables support for profiling template rendering to help track down performance issues.
#
# To enable profiling, first require 'liquid/profiler'.
@@ -55,9 +54,7 @@ module Liquid
end
def self.start(token, partial)
new(token, partial).tap do |t|
t.start
end
new(token, partial).tap(&:start)
end
def start
@@ -139,7 +136,7 @@ module Liquid
@timing_stack.push(Timing.start(token, current_partial))
end
def end_token(token)
def end_token(_token)
timing = @timing_stack.pop
timing.finish
@@ -157,6 +154,5 @@ module Liquid
def pop_partial
@partial_stack.pop
end
end
end
+3 -3
View File
@@ -1,7 +1,7 @@
module Liquid
class ResourceLimits
attr_accessor :render_length, :render_score, :assign_score,
:render_length_limit, :render_score_limit, :assign_score_limit
:render_length_limit, :render_score_limit, :assign_score_limit
def initialize(limits)
@render_length_limit = limits[:render_length_limit]
@@ -12,8 +12,8 @@ module Liquid
def reached?
(@render_length_limit && @render_length > @render_length_limit) ||
(@render_score_limit && @render_score > @render_score_limit ) ||
(@assign_score_limit && @assign_score > @assign_score_limit )
(@render_score_limit && @render_score > @render_score_limit) ||
(@assign_score_limit && @assign_score > @assign_score_limit)
end
def reset
+8 -11
View File
@@ -2,7 +2,6 @@ require 'cgi'
require 'bigdecimal'
module Liquid
module StandardFilters
HTML_ESCAPE = {
'&'.freeze => '&amp;'.freeze,
@@ -46,7 +45,7 @@ module Liquid
CGI.escape(input) rescue input
end
def slice(input, offset, length=nil)
def slice(input, offset, length = nil)
offset = Integer(offset)
length = length ? Integer(length) : 1
@@ -59,14 +58,14 @@ module Liquid
# Truncate a string down to x characters
def truncate(input, length = 50, truncate_string = "...".freeze)
if input.nil? then return end
return if input.nil?
l = length.to_i - truncate_string.length
l = 0 if l < 0
input.length > length.to_i ? input[0...l] + truncate_string : input
end
def truncatewords(input, words = 15, truncate_string = "...".freeze)
if input.nil? then return end
return if input.nil?
wordlist = input.to_s.split
l = words.to_i - 1
l = 0 if l < 0
@@ -116,9 +115,9 @@ module Liquid
if property.nil?
ary.sort
elsif ary.first.respond_to?(:[]) && !ary.first[property].nil?
ary.sort {|a,b| a[property] <=> b[property] }
ary.sort { |a, b| a[property] <=> b[property] }
elsif ary.first.respond_to?(property)
ary.sort {|a,b| a.send(property) <=> b.send(property) }
ary.sort { |a, b| a.send(property) <=> b.send(property) }
end
end
@@ -128,11 +127,11 @@ module Liquid
ary = InputIterator.new(input)
if property.nil?
ary.sort {|a,b| a.casecmp(b) }
ary.sort { |a, b| a.casecmp(b) }
elsif ary.first.respond_to?(:[]) && !ary.first[property].nil?
ary.sort {|a,b| a[property].casecmp(b[property]) }
ary.sort { |a, b| a[property].casecmp(b[property]) }
elsif ary.first.respond_to?(property)
ary.sort {|a,b| a.send(property).casecmp(b.send(property)) }
ary.sort { |a, b| a.send(property).casecmp(b.send(property)) }
end
end
@@ -336,8 +335,6 @@ module Liquid
Time.at(obj.to_i)
when String
Time.parse(obj)
else
nil
end
rescue ArgumentError
nil
+3 -4
View File
@@ -1,7 +1,6 @@
require 'set'
module Liquid
# Strainer is the parent class for the filters system.
# New filters are mixed into the strainer class which is then instantiated for each liquid template render run.
#
@@ -22,14 +21,14 @@ module Liquid
@context = context
end
def self.filter_methods
@filter_methods
class << self
attr_reader :filter_methods
end
def self.add_filter(filter)
raise ArgumentError, "Expected module but got: #{f.class}" unless filter.is_a?(Module)
unless self.class.include?(filter)
self.send(:include, filter)
send(:include, filter)
@filter_methods.merge(filter.public_instance_methods.map(&:to_s))
end
end
+2 -2
View File
@@ -20,7 +20,7 @@ module Liquid
@options = options
end
def parse(tokens)
def parse(_tokens)
end
def raw
@@ -31,7 +31,7 @@ module Liquid
self.class.name.downcase
end
def render(context)
def render(_context)
''.freeze
end
+1 -2
View File
@@ -1,5 +1,4 @@
module Liquid
# Assign sets a variable in your template.
#
# {% assign foo = 'monkey' %}
@@ -15,7 +14,7 @@ module Liquid
super
if markup =~ Syntax
@to = $1
@from = Variable.new($2,options)
@from = Variable.new($2, options)
@from.line_number = line_number
else
raise SyntaxError.new options[:locale].t("errors.syntax.assign".freeze)
-3
View File
@@ -1,5 +1,4 @@
module Liquid
# Break tag to be used to break out of a for loop.
#
# == Basic Usage:
@@ -10,11 +9,9 @@ module Liquid
# {% endfor %}
#
class Break < Tag
def interrupt
BreakInterrupt.new
end
end
Template.register_tag('break'.freeze, Break)
+2 -2
View File
@@ -59,7 +59,7 @@ module Liquid
body = BlockBody.new
while markup
if not markup =~ WhenSyntax
unless markup =~ WhenSyntax
raise SyntaxError.new(options[:locale].t("errors.syntax.case_invalid_when".freeze))
end
@@ -72,7 +72,7 @@ module Liquid
end
def record_else_condition(markup)
if not markup.strip.empty?
unless markup.strip.empty?
raise SyntaxError.new(options[:locale].t("errors.syntax.case_invalid_else".freeze))
end
+2 -2
View File
@@ -1,10 +1,10 @@
module Liquid
class Comment < Block
def render(context)
def render(_context)
''.freeze
end
def unknown_tag(tag, markup, tokens)
def unknown_tag(_tag, _markup, _tokens)
end
def blank?
+1 -4
View File
@@ -1,5 +1,4 @@
module Liquid
# decrement is used in a place where one needs to insert a counter
# into a template, and needs the counter to survive across
# multiple instantiations of the template.
@@ -26,12 +25,10 @@ module Liquid
def render(context)
value = context.environments.first[@variable] ||= 0
value = value - 1
value -= 1
context.environments.first[@variable] = value
value.to_s
end
private
end
Template.register_tag('decrement'.freeze, Decrement)
+2 -4
View File
@@ -1,5 +1,4 @@
module Liquid
# "For" iterates over an array or collection.
# Several useful variables are available to you within the loop.
#
@@ -54,9 +53,8 @@ module Liquid
end
def parse(tokens)
if more = parse_body(@for_block, tokens)
parse_body(@else_block, tokens)
end
return unless parse_body(@for_block, tokens)
parse_body(@else_block, tokens)
end
def nodelist
+41 -41
View File
@@ -21,7 +21,7 @@ module Liquid
end
def parse(tokens)
while more = parse_body(@blocks.last.attachment, tokens)
while parse_body(@blocks.last.attachment, tokens)
end
end
@@ -50,61 +50,61 @@ module Liquid
private
def push_block(tag, markup)
block = if tag == 'else'.freeze
ElseCondition.new
else
parse_with_selected_parser(markup)
end
@blocks.push(block)
block.attach(BlockBody.new)
def push_block(tag, markup)
block = if tag == 'else'.freeze
ElseCondition.new
else
parse_with_selected_parser(markup)
end
def lax_parse(markup)
expressions = markup.scan(ExpressionsAndOperators)
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop =~ Syntax
@blocks.push(block)
block.attach(BlockBody.new)
end
condition = Condition.new(Expression.parse($1), $2, Expression.parse($3))
def lax_parse(markup)
expressions = markup.scan(ExpressionsAndOperators)
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop =~ Syntax
while not expressions.empty?
operator = expressions.pop.to_s.strip
condition = Condition.new(Expression.parse($1), $2, Expression.parse($3))
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop.to_s =~ Syntax
until expressions.empty?
operator = expressions.pop.to_s.strip
new_condition = Condition.new(Expression.parse($1), $2, Expression.parse($3))
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless BOOLEAN_OPERATORS.include?(operator)
new_condition.send(operator, condition)
condition = new_condition
end
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop.to_s =~ Syntax
condition
new_condition = Condition.new(Expression.parse($1), $2, Expression.parse($3))
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless BOOLEAN_OPERATORS.include?(operator)
new_condition.send(operator, condition)
condition = new_condition
end
def strict_parse(markup)
p = Parser.new(markup)
condition
end
condition = parse_comparison(p)
def strict_parse(markup)
p = Parser.new(markup)
while op = (p.id?('and'.freeze) || p.id?('or'.freeze))
new_cond = parse_comparison(p)
new_cond.send(op, condition)
condition = new_cond
end
p.consume(:end_of_string)
condition = parse_comparison(p)
condition
while op = (p.id?('and'.freeze) || p.id?('or'.freeze))
new_cond = parse_comparison(p)
new_cond.send(op, condition)
condition = new_cond
end
p.consume(:end_of_string)
def parse_comparison(p)
a = Expression.parse(p.expression)
if op = p.consume?(:comparison)
b = Expression.parse(p.expression)
Condition.new(a, op, b)
else
Condition.new(a)
end
condition
end
def parse_comparison(p)
a = Expression.parse(p.expression)
if op = p.consume?(:comparison)
b = Expression.parse(p.expression)
Condition.new(a, op, b)
else
Condition.new(a)
end
end
end
Template.register_tag('if'.freeze, If)
-2
View File
@@ -1,9 +1,7 @@
module Liquid
class Ifchanged < Block
def render(context)
context.stack do
output = super
if output != context.registers[:ifchanged]
+26 -26
View File
@@ -1,5 +1,4 @@
module Liquid
# Include allows templates to relate with other templates
#
# Simply include another template:
@@ -38,7 +37,7 @@ module Liquid
end
end
def parse(tokens)
def parse(_tokens)
end
def render(context)
@@ -71,35 +70,36 @@ module Liquid
end
private
def load_cached_partial(context)
cached_partials = context.registers[:cached_partials] || {}
template_name = context.evaluate(@template_name_expr)
if cached = cached_partials[template_name]
return cached
end
source = read_template_from_file_system(context)
partial = Liquid::Template.parse(source, pass_options)
cached_partials[template_name] = partial
context.registers[:cached_partials] = cached_partials
partial
def load_cached_partial(context)
cached_partials = context.registers[:cached_partials] || {}
template_name = context.evaluate(@template_name_expr)
if cached = cached_partials[template_name]
return cached
end
source = read_template_from_file_system(context)
partial = Liquid::Template.parse(source, pass_options)
cached_partials[template_name] = partial
context.registers[:cached_partials] = cached_partials
partial
end
def read_template_from_file_system(context)
file_system = context.registers[:file_system] || Liquid::Template.file_system
def read_template_from_file_system(context)
file_system = context.registers[:file_system] || Liquid::Template.file_system
file_system.read_template_file(context.evaluate(@template_name_expr))
end
def pass_options
dont_pass = @options[:include_options_blacklist]
return {locale: @options[:locale]} if dont_pass == true
opts = @options.merge(included: true, include_options_blacklist: false)
if dont_pass.is_a?(Array)
dont_pass.each {|o| opts.delete(o)}
end
opts
file_system.read_template_file(context.evaluate(@template_name_expr))
end
def pass_options
dont_pass = @options[:include_options_blacklist]
return { locale: @options[:locale] } if dont_pass == true
opts = @options.merge(included: true, include_options_blacklist: false)
if dont_pass.is_a?(Array)
dont_pass.each { |o| opts.delete(o) }
end
opts
end
end
Template.register_tag('include'.freeze, Include)
+2 -2
View File
@@ -9,11 +9,11 @@ module Liquid
@body << $1 if $1 != "".freeze
return if block_delimiter == $2
end
@body << token if not token.empty?
@body << token unless token.empty?
end
end
def render(context)
def render(_context)
@body
end
+1 -4
View File
@@ -33,7 +33,6 @@ module Liquid
result = "<tr class=\"row1\">\n"
context.stack do
collection.each_with_index do |item, index|
context[@variable_name] = item
context['tablerowloop'.freeze] = {
@@ -50,17 +49,15 @@ module Liquid
'col_last'.freeze => (col == cols - 1)
}
col += 1
result << "<td class=\"col#{col}\">" << super << '</td>'
if col == cols and (index != length - 1)
if col == cols && (index != length - 1)
col = 0
row += 1
result << "</tr>\n<tr class=\"row#{row}\">"
end
end
end
result << "</tr>\n"
-1
View File
@@ -8,7 +8,6 @@ module Liquid
class Unless < If
def render(context)
context.stack do
# First condition is interpreted backwards ( if not )
first_block = @blocks.first
unless first_block.evaluate(context)
+3 -4
View File
@@ -1,5 +1,4 @@
module Liquid
# Templates are central to liquid.
# Interpretating templates is a two step process. First you compile the
# source code you got. During compile time some extensive error checking is performed.
@@ -15,7 +14,7 @@ module Liquid
#
class Template
DEFAULT_OPTIONS = {
:locale => I18n.new
locale: I18n.new
}
attr_accessor :root
@@ -189,7 +188,7 @@ module Liquid
options = args.pop
if options[:registers].is_a?(Hash)
self.registers.merge!(options[:registers])
registers.merge!(options[:registers])
end
if options[:filters]
@@ -237,7 +236,7 @@ module Liquid
tokens = calculate_line_numbers(source.split(TemplateParser))
# removes the rogue empty element at the beginning of the array
tokens.shift if tokens[0] and tokens[0].empty?
tokens.shift if tokens[0] && tokens[0].empty?
tokens
end
+1 -3
View File
@@ -1,8 +1,7 @@
module Liquid
module Utils
def self.slice_collection(collection, from, to)
if (from != 0 || to != nil) && collection.respond_to?(:load_slice)
if (from != 0 || !to.nil?) && collection.respond_to?(:load_slice)
collection.load_slice(from, to)
else
slice_collection_using_each(collection, from, to)
@@ -21,7 +20,6 @@ module Liquid
return [collection] if non_blank_string?(collection)
collection.each do |item|
if to && to <= index
break
end
+13 -16
View File
@@ -1,5 +1,4 @@
module Liquid
# Holds variables. Variables are only loaded "just in time"
# and are not evaluated as part of the render stage
#
@@ -34,18 +33,18 @@ module Liquid
def lax_parse(markup)
@filters = []
if markup =~ /(#{QuotedFragment})(.*)/om
name_markup = $1
filter_markup = $2
@name = Expression.parse(name_markup)
if filter_markup =~ /#{FilterSeparator}\s*(.*)/om
filters = $1.scan(FilterParser)
filters.each do |f|
if f =~ /\w+/
filtername = Regexp.last_match(0)
filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*((?:\w+\s*\:\s*)?#{QuotedFragment})/o).flatten
@filters << parse_filter_expressions(filtername, filterargs)
end
return unless markup =~ /(#{QuotedFragment})(.*)/om
name_markup = $1
filter_markup = $2
@name = Expression.parse(name_markup)
if filter_markup =~ /#{FilterSeparator}\s*(.*)/om
filters = $1.scan(FilterParser)
filters.each do |f|
if f =~ /\w+/
filtername = Regexp.last_match(0)
filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*((?:\w+\s*\:\s*)?#{QuotedFragment})/o).flatten
@filters << parse_filter_expressions(filtername, filterargs)
end
end
end
@@ -68,9 +67,7 @@ module Liquid
# first argument
filterargs = [p.argument]
# followed by comma separated others
while p.consume?(:comma)
filterargs << p.argument
end
filterargs << p.argument while p.consume?(:comma)
filterargs
end
+3 -3
View File
@@ -41,8 +41,8 @@ module Liquid
# If object is a hash- or array-like object we look for the
# presence of the key and if its available we return it
if object.respond_to?(:[]) &&
((object.respond_to?(:has_key?) && object.has_key?(key)) ||
(object.respond_to?(:fetch) && key.is_a?(Integer)))
((object.respond_to?(:has_key?) && object.has_key?(key)) ||
(object.respond_to?(:fetch) && key.is_a?(Integer)))
# if its a proc we will replace the entry with the proc
res = context.lookup_and_evaluate(object, key)
@@ -68,7 +68,7 @@ module Liquid
end
def ==(other)
self.class == other.class && self.state == other.state
self.class == other.class && state == other.state
end
protected