locomotive_liquid 2.1.3

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.
@@ -0,0 +1,20 @@
1
+ module Liquid
2
+ class Ifchanged < Block
3
+
4
+ def render(context)
5
+ context.stack do
6
+
7
+ output = render_all(@nodelist, context)
8
+
9
+ if output != context.registers[:ifchanged]
10
+ context.registers[:ifchanged] = output
11
+ output
12
+ else
13
+ ''
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Template.register_tag('ifchanged', Ifchanged)
20
+ end
@@ -0,0 +1,56 @@
1
+ module Liquid
2
+ class Include < Tag
3
+ Syntax = /(#{QuotedFragment}+)(\s+(?:with|for)\s+(#{QuotedFragment}+))?/
4
+
5
+ def initialize(tag_name, markup, tokens, context)
6
+ if markup =~ Syntax
7
+
8
+ @template_name = $1
9
+ @variable_name = $3
10
+ @attributes = {}
11
+
12
+ markup.scan(TagAttributes) do |key, value|
13
+ @attributes[key] = value
14
+ end
15
+
16
+ else
17
+ raise SyntaxError.new("Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]")
18
+ end
19
+
20
+ super
21
+ end
22
+
23
+ def parse(tokens)
24
+ end
25
+
26
+ def render(context)
27
+ file_system = context.registers[:file_system] || Liquid::Template.file_system
28
+ source = file_system.read_template_file(context[@template_name])
29
+ partial = Liquid::Template.parse(source)
30
+
31
+ variable = context[@variable_name || @template_name[1..-2]]
32
+
33
+ context.stack do
34
+ @attributes.each do |key, value|
35
+ context[key] = context[value]
36
+ end
37
+
38
+ if variable.is_a?(Array)
39
+
40
+ variable.collect do |variable|
41
+ context[@template_name[1..-2]] = variable
42
+ partial.render(context)
43
+ end
44
+
45
+ else
46
+
47
+ context[@template_name[1..-2]] = variable
48
+ partial.render(context)
49
+
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ Template.register_tag('include', Include)
56
+ end
@@ -0,0 +1,93 @@
1
+ module Liquid
2
+
3
+ # Blocks are used with the Extends tag to define
4
+ # the content of blocks. Nested blocks are allowed.
5
+ #
6
+ # {% extends home %}
7
+ # {% block content }Hello world{% endblock %}
8
+ #
9
+ class InheritedBlock < Block
10
+ Syntax = /(#{QuotedFragment}+)/
11
+
12
+ attr_accessor :parent
13
+ attr_reader :name
14
+
15
+ def initialize(tag_name, markup, tokens, context)
16
+ if markup =~ Syntax
17
+ @name = $1
18
+ else
19
+ raise SyntaxError.new("Error in tag 'block' - Valid syntax: block [name]")
20
+ end
21
+
22
+ (context[:block_stack] ||= []).push(self)
23
+ context[:current_block] = self
24
+
25
+ super if tokens
26
+ end
27
+
28
+ def render(context)
29
+ context.stack do
30
+ context['block'] = InheritedBlockDrop.new(self)
31
+ render_all(@nodelist, context)
32
+ end
33
+ end
34
+
35
+ def end_tag
36
+ self.register_current_block
37
+
38
+ @context[:block_stack].pop
39
+ @context[:current_block] = @context[:block_stack].last
40
+ end
41
+
42
+ def call_super(context)
43
+ if parent
44
+ parent.render(context)
45
+ else
46
+ ''
47
+ end
48
+ end
49
+
50
+ def self.clone_block(block)
51
+ new_block = self.new(block.send(:instance_variable_get, :"@tag_name"), block.name, nil, {})
52
+ new_block.parent = block.parent
53
+ new_block.nodelist = block.nodelist
54
+ new_block
55
+ end
56
+
57
+ protected
58
+
59
+ def register_current_block
60
+ @context[:blocks] ||= {}
61
+
62
+ block = @context[:blocks][@name]
63
+
64
+ if block
65
+ # copy the existing block in order to make it a parent of the parsed block
66
+ new_block = self.class.clone_block(block)
67
+
68
+ # replace the up-to-date version of the block in the parent template
69
+ block.parent = new_block
70
+ block.nodelist = @nodelist
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ class InheritedBlockDrop < Drop
77
+
78
+ def initialize(block)
79
+ @block = block
80
+ end
81
+
82
+ def name
83
+ @block.name
84
+ end
85
+
86
+ def super
87
+ @block.call_super(@context)
88
+ end
89
+
90
+ end
91
+
92
+ Template.register_tag('block', InheritedBlock)
93
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/if'
2
+
3
+ module Liquid
4
+
5
+ # Unless is a conditional just like 'if' but works on the inverse logic.
6
+ #
7
+ # {% unless x < 0 %} x is greater than zero {% end %}
8
+ #
9
+ class Unless < If
10
+ def render(context)
11
+ context.stack do
12
+
13
+ # First condition is interpreted backwards ( if not )
14
+ block = @blocks.first
15
+ unless block.evaluate(context)
16
+ return render_all(block.attachment, context)
17
+ end
18
+
19
+ # After the first condition unless works just like if
20
+ @blocks[1..-1].each do |block|
21
+ if block.evaluate(context)
22
+ return render_all(block.attachment, context)
23
+ end
24
+ end
25
+
26
+ ''
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ Template.register_tag('unless', Unless)
33
+ end
@@ -0,0 +1,149 @@
1
+ module Liquid
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.
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.
10
+ #
11
+ # Example:
12
+ #
13
+ # template = Liquid::Template.parse(source)
14
+ # template.render('user_name' => 'bob')
15
+ #
16
+ class Template
17
+ attr_accessor :root
18
+ @@file_system = BlankFileSystem.new
19
+
20
+ class << self
21
+ def file_system
22
+ @@file_system
23
+ end
24
+
25
+ def file_system=(obj)
26
+ @@file_system = obj
27
+ end
28
+
29
+ def register_tag(name, klass)
30
+ tags[name.to_s] = klass
31
+ end
32
+
33
+ def tags
34
+ @tags ||= {}
35
+ end
36
+
37
+ # Pass a module with filter methods which should be available
38
+ # to all liquid views. Good for registering the standard library
39
+ def register_filter(mod)
40
+ Strainer.global_filter(mod)
41
+ end
42
+
43
+ # creates a new <tt>Template</tt> object from liquid source code
44
+ def parse(source, context = {})
45
+ template = Template.new
46
+ template.parse(source, context)
47
+ template
48
+ end
49
+ end
50
+
51
+ # creates a new <tt>Template</tt> from an array of tokens. Use <tt>Template.parse</tt> instead
52
+ def initialize
53
+ end
54
+
55
+ # Parse source code.
56
+ # Returns self for easy chaining
57
+ def parse(source, context = {})
58
+ @root = Document.new(tokenize(source), context.merge!(:template => self))
59
+ self
60
+ end
61
+
62
+ def registers
63
+ @registers ||= {}
64
+ end
65
+
66
+ def assigns
67
+ @assigns ||= {}
68
+ end
69
+
70
+ def instance_assigns
71
+ @instance_assigns ||= {}
72
+ end
73
+
74
+ def errors
75
+ @errors ||= []
76
+ end
77
+
78
+ # Render takes a hash with local variables.
79
+ #
80
+ # if you use the same filters over and over again consider registering them globally
81
+ # with <tt>Template.register_filter</tt>
82
+ #
83
+ # Following options can be passed:
84
+ #
85
+ # * <tt>filters</tt> : array with local filters
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
88
+ #
89
+ def render(*args)
90
+ return '' if @root.nil?
91
+
92
+ context = case args.first
93
+ when Liquid::Context
94
+ args.shift
95
+ when Hash
96
+ Context.new([args.shift, assigns], instance_assigns, registers, @rethrow_errors)
97
+ when nil
98
+ Context.new(assigns, instance_assigns, registers, @rethrow_errors)
99
+ else
100
+ raise ArgumentError, "Expect Hash or Liquid::Context as parameter"
101
+ end
102
+
103
+ case args.last
104
+ when Hash
105
+ options = args.pop
106
+
107
+ if options[:registers].is_a?(Hash)
108
+ self.registers.merge!(options[:registers])
109
+ end
110
+
111
+ if options[:filters]
112
+ context.add_filters(options[:filters])
113
+ end
114
+
115
+ when Module
116
+ context.add_filters(args.pop)
117
+ when Array
118
+ context.add_filters(args.pop)
119
+ end
120
+
121
+ begin
122
+ # render the nodelist.
123
+ # for performance reasons we get a array back here. join will make a string out of it
124
+ @root.render(context).join
125
+ ensure
126
+ @errors = context.errors
127
+ end
128
+ end
129
+
130
+ def render!(*args)
131
+ @rethrow_errors = true; render(*args)
132
+ end
133
+
134
+ private
135
+
136
+ # Uses the <tt>Liquid::TemplateParser</tt> regexp to tokenize the passed source
137
+ def tokenize(source)
138
+ source = source.source if source.respond_to?(:source)
139
+ return [] if source.to_s.empty?
140
+ tokens = source.split(TemplateParser)
141
+
142
+ # removes the rogue empty element at the beginning of the array
143
+ tokens.shift if tokens[0] and tokens[0].empty?
144
+
145
+ tokens
146
+ end
147
+
148
+ end
149
+ end
@@ -0,0 +1,50 @@
1
+ module Liquid
2
+
3
+ # Holds variables. Variables are only loaded "just in time"
4
+ # and are not evaluated as part of the render stage
5
+ #
6
+ # {{ monkey }}
7
+ # {{ user.name }}
8
+ #
9
+ # Variables can be combined with filters:
10
+ #
11
+ # {{ user | link }}
12
+ #
13
+ class Variable
14
+ FilterParser = /(?:#{FilterSeparator}|(?:\s*(?!(?:#{FilterSeparator}))(?:#{QuotedFragment}|\S+)\s*)+)/
15
+ attr_accessor :filters, :name
16
+
17
+ def initialize(markup)
18
+ @markup = markup
19
+ @name = nil
20
+ @filters = []
21
+ if match = markup.match(/\s*(#{QuotedFragment})(.*)/)
22
+ @name = match[1]
23
+ if match[2].match(/#{FilterSeparator}\s*(.*)/)
24
+ filters = Regexp.last_match(1).scan(FilterParser)
25
+ filters.each do |f|
26
+ if matches = f.match(/\s*(\w+)/)
27
+ filtername = matches[1]
28
+ filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*(#{QuotedFragment})/).flatten
29
+ @filters << [filtername.to_sym, filterargs]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def render(context)
37
+ return '' if @name.nil?
38
+ @filters.inject(context[@name]) do |output, filter|
39
+ filterargs = filter[1].to_a.collect do |a|
40
+ context[a]
41
+ end
42
+ begin
43
+ output = context.invoke(filter[0], output, *filterargs)
44
+ rescue FilterNotFound
45
+ raise FilterNotFound, "Error - filter '#{filter[0]}' in '#{@markup.strip}' could not be found."
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1 @@
1
+ require 'liquid'
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: locomotive_liquid
3
+ version: !ruby/object:Gem::Version
4
+ hash: 13
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 1
9
+ - 3
10
+ version: 2.1.3
11
+ platform: ruby
12
+ authors:
13
+ - Tobias Luetke
14
+ - Didier Lafforgue
15
+ - Jacques Crocker
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2010-09-27 00:00:00 -07:00
21
+ default_executable:
22
+ dependencies: []
23
+
24
+ description: A secure, non-evaling end user template engine with aesthetic markup. Extended with liquid template inheritance for use in LocomotiveCMS
25
+ email:
26
+ - tobi@leetsoft.com
27
+ - didier@nocoffee.fr
28
+ - railsjedi@gmail.com
29
+ executables: []
30
+
31
+ extensions: []
32
+
33
+ extra_rdoc_files:
34
+ - History.txt
35
+ - README.txt
36
+ files:
37
+ - CHANGELOG
38
+ - History.txt
39
+ - MIT-LICENSE
40
+ - README.txt
41
+ - Rakefile
42
+ - init.rb
43
+ - lib/extras/liquid_view.rb
44
+ - lib/liquid/block.rb
45
+ - lib/liquid/condition.rb
46
+ - lib/liquid/context.rb
47
+ - lib/liquid/document.rb
48
+ - lib/liquid/drop.rb
49
+ - lib/liquid/errors.rb
50
+ - lib/liquid/extensions.rb
51
+ - lib/liquid/file_system.rb
52
+ - lib/liquid/htmltags.rb
53
+ - lib/liquid/module_ex.rb
54
+ - lib/liquid/standardfilters.rb
55
+ - lib/liquid/strainer.rb
56
+ - lib/liquid/tag.rb
57
+ - lib/liquid/tags/assign.rb
58
+ - lib/liquid/tags/capture.rb
59
+ - lib/liquid/tags/case.rb
60
+ - lib/liquid/tags/comment.rb
61
+ - lib/liquid/tags/cycle.rb
62
+ - lib/liquid/tags/extends.rb
63
+ - lib/liquid/tags/for.rb
64
+ - lib/liquid/tags/if.rb
65
+ - lib/liquid/tags/ifchanged.rb
66
+ - lib/liquid/tags/include.rb
67
+ - lib/liquid/tags/inherited_block.rb
68
+ - lib/liquid/tags/unless.rb
69
+ - lib/liquid/template.rb
70
+ - lib/liquid/variable.rb
71
+ - lib/liquid.rb
72
+ - lib/locomotive_liquid.rb
73
+ has_rdoc: true
74
+ homepage: http://www.locomotiveapp.org
75
+ licenses: []
76
+
77
+ post_install_message:
78
+ rdoc_options:
79
+ - --main
80
+ - README.txt
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 23
98
+ segments:
99
+ - 1
100
+ - 3
101
+ - 6
102
+ version: 1.3.6
103
+ requirements: []
104
+
105
+ rubyforge_project: locomotive_liquid
106
+ rubygems_version: 1.3.7
107
+ signing_key:
108
+ specification_version: 2
109
+ summary: A secure, non-evaling end user template engine with aesthetic markup.
110
+ test_files: []
111
+