Class: Jekyll::Tags::IncludeTag
- Inherits:
-
Liquid::Tag
- Object
- Liquid::Tag
- Jekyll::Tags::IncludeTag
- Defined in:
- lib/jekyll/tags/include.rb
Direct Known Subclasses
Constant Summary collapse
- VALID_SYNTAX =
%r! ([\w-]+)\s*=\s* (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+)) !x
- VARIABLE_SYNTAX =
%r! (?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+) (?<params>.*) !mx
- FULL_VALID_SYNTAX =
%r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!
- VALID_FILENAME_CHARS =
%r!^[\w/\.-]+$!
- INVALID_SEQUENCES =
%r![./]{2,}!
Instance Method Summary collapse
- #add_include_to_dependency(site, path, context) ⇒ Object
-
#file_read_opts(context) ⇒ Object
Grab file read opts in the context.
-
#initialize(tag_name, markup, tokens) ⇒ IncludeTag
constructor
A new instance of IncludeTag.
- #load_cached_partial(path, context) ⇒ Object
- #locate_include_file(context, file, safe) ⇒ Object
- #outside_site_source?(path, dir, safe) ⇒ Boolean
- #parse_params(context) ⇒ Object
-
#read_file(file, context) ⇒ Object
This method allows to modify the file content by inheriting from the class.
- #realpath_prefixed_with?(path, dir) ⇒ Boolean
- #render(context) ⇒ Object
-
#render_variable(context) ⇒ Object
Render the variable if required.
- #syntax_example ⇒ Object
- #tag_includes_dirs(context) ⇒ Object
- #valid_include_file?(path, dir, safe) ⇒ Boolean
- #validate_file_name(file) ⇒ Object
- #validate_params ⇒ Object
Constructor Details
#initialize(tag_name, markup, tokens) ⇒ IncludeTag
Returns a new instance of IncludeTag.
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/jekyll/tags/include.rb', line 28 def initialize(tag_name, markup, tokens) super matched = markup.strip.match(VARIABLE_SYNTAX) if matched @file = matched["variable"].strip @params = matched["params"].strip else @file, @params = markup.strip.split(%r!\s+!, 2) end validate_params if @params @tag_name = tag_name end |
Instance Method Details
#add_include_to_dependency(site, path, context) ⇒ Object
149 150 151 152 153 154 155 156 |
# File 'lib/jekyll/tags/include.rb', line 149 def add_include_to_dependency(site, path, context) if context.registers[:page] && context.registers[:page].key?("path") site.regenerator.add_dependency( site.in_source_dir(context.registers[:page]["path"]), path ) end end |
#file_read_opts(context) ⇒ Object
Grab file read opts in the context
96 97 98 |
# File 'lib/jekyll/tags/include.rb', line 96 def file_read_opts(context) context.registers[:site].file_read_opts end |
#load_cached_partial(path, context) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/jekyll/tags/include.rb', line 158 def load_cached_partial(path, context) context.registers[:cached_partials] ||= {} cached_partial = context.registers[:cached_partials] if cached_partial.key?(path) cached_partial[path] else unparsed_file = context.registers[:site] .liquid_renderer .file(path) begin cached_partial[path] = unparsed_file.parse(read_file(path, context)) rescue Liquid::Error => e e.template_name = path e.markup_context = "included " if e.markup_context.nil? raise e end end end |
#locate_include_file(context, file, safe) ⇒ Object
115 116 117 118 119 120 121 122 |
# File 'lib/jekyll/tags/include.rb', line 115 def locate_include_file(context, file, safe) includes_dirs = tag_includes_dirs(context) includes_dirs.each do |dir| path = File.join(dir.to_s, file.to_s) return path if valid_include_file?(path, dir.to_s, safe) end raise IOError, (file, includes_dirs, safe) end |
#outside_site_source?(path, dir, safe) ⇒ Boolean
182 183 184 |
# File 'lib/jekyll/tags/include.rb', line 182 def outside_site_source?(path, dir, safe) safe && !realpath_prefixed_with?(path, dir) end |
#parse_params(context) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/jekyll/tags/include.rb', line 45 def parse_params(context) params = {} markup = @params while (match = VALID_SYNTAX.match(markup)) markup = markup[match.end(0)..-1] value = if match[2] match[2].gsub(%r!\\"!, '"') elsif match[3] match[3].gsub(%r!\\'!, "'") elsif match[4] context[match[4]] end params[match[1]] = value end params end |
#read_file(file, context) ⇒ Object
This method allows to modify the file content by inheriting from the class.
193 194 195 |
# File 'lib/jekyll/tags/include.rb', line 193 def read_file(file, context) File.read(file, file_read_opts(context)) end |
#realpath_prefixed_with?(path, dir) ⇒ Boolean
186 187 188 189 190 |
# File 'lib/jekyll/tags/include.rb', line 186 def realpath_prefixed_with?(path, dir) File.exist?(path) && File.realpath(path).start_with?(dir) rescue StandardError false end |
#render(context) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/jekyll/tags/include.rb', line 124 def render(context) site = context.registers[:site] file = render_variable(context) || @file validate_file_name(file) path = locate_include_file(context, file, site.safe) return unless path add_include_to_dependency(site, path, context) partial = load_cached_partial(path, context) context.stack do context["include"] = parse_params(context) if @params begin partial.render!(context) rescue Liquid::Error => e e.template_name = path e.markup_context = "included " if e.markup_context.nil? raise e end end end |
#render_variable(context) ⇒ Object
Render the variable if required
101 102 103 104 105 106 107 108 109 |
# File 'lib/jekyll/tags/include.rb', line 101 def render_variable(context) if @file =~ VARIABLE_SYNTAX partial = context.registers[:site] .liquid_renderer .file("(variable)") .parse(@file) partial.render!(context) end end |
#syntax_example ⇒ Object
41 42 43 |
# File 'lib/jekyll/tags/include.rb', line 41 def syntax_example "{% #{@tag_name} file.ext param='value' param2='value' %}" end |
#tag_includes_dirs(context) ⇒ Object
111 112 113 |
# File 'lib/jekyll/tags/include.rb', line 111 def tag_includes_dirs(context) context.registers[:site].includes_load_paths.freeze end |
#valid_include_file?(path, dir, safe) ⇒ Boolean
178 179 180 |
# File 'lib/jekyll/tags/include.rb', line 178 def valid_include_file?(path, dir, safe) !outside_site_source?(path, dir, safe) && File.file?(path) end |
#validate_file_name(file) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/jekyll/tags/include.rb', line 65 def validate_file_name(file) if file =~ INVALID_SEQUENCES || file !~ VALID_FILENAME_CHARS raise ArgumentError, <<-MSG Invalid syntax for include tag. File contains invalid characters or sequences: #{file} Valid syntax: #{syntax_example} MSG end end |
#validate_params ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/jekyll/tags/include.rb', line 80 def validate_params unless @params =~ FULL_VALID_SYNTAX raise ArgumentError, <<-MSG Invalid syntax for include tag: #{@params} Valid syntax: #{syntax_example} MSG end end |