add yard tags

This commit is contained in:
Jake Olney
2022-06-27 15:10:21 -04:00
committed by Melanie Wang
parent eb70bb9b87
commit f3aa5fbd7c
21 changed files with 820 additions and 216 deletions
+16
View File
@@ -98,6 +98,22 @@ module Liquid
end
end
# @liquid_public_docs
# @liquid_type tag
# @liquid_category syntax
# @liquid_name liquid
# @liquid_summary
# Allows you to have a block of Liquid without delimeters on each tag.
# @liquid_description
# Because the tags don't have delimeters, each tag needs to be on its own line.
#
# > Tip:
# > Use the [`echo` tag](/api/liquid/tags#echo) to output an expression inside `liquid` tags.
# @liquid_syntax
# {% liquid
# expression
# %}
# @liquid_syntax_keyword expression The expression to be rendered inside the `liquid` tag.
private def parse_liquid_tag(markup, parse_context)
liquid_tag_tokenizer = parse_context.new_tokenizer(
markup, start_line_number: parse_context.line_number, for_liquid_tag: true
+37 -1
View File
@@ -1,6 +1,11 @@
# frozen_string_literal: true
module Liquid
# @liquid_public_docs
# @liquid_type object
# @liquid_name forloop
# @liquid_summary
# The `forloop` object contains information about a parent [`for` loop](/api/liquid/tags#for).
class ForloopDrop < Drop
def initialize(name, length, parentloop)
@name = name
@@ -9,33 +14,64 @@ module Liquid
@index = 0
end
attr_reader :length, :parentloop
# @liquid_public_docs
# @liquid_name forloop.length
# @liquid_summary
# The number of iterations.
# @liquid_return [number]
attr_reader :length
attr_reader :parentloop
def name
Usage.increment('forloop_drop_name')
@name
end
# @liquid_public_docs
# @liquid_summary
# The 1-based index of the current iteration.
# @liquid_return [number]
def index
@index + 1
end
# @liquid_public_docs
# @liquid_summary
# The 0-based index of the current iteration.
# @liquid_return [number]
def index0
@index
end
# @liquid_public_docs
# @liquid_summary
# The 1-based index of the current iteration, in reverse order.
# @liquid_return [number]
def rindex
@length - @index
end
# @liquid_public_docs
# @liquid_summary
# The 0-based index of the current iteration, in reverse order.
# @liquid_return [number]
def rindex0
@length - @index - 1
end
# @liquid_public_docs
# @liquid_summary
# Returns `true` if the current iteration is the first. Returns `false` if not.
# @liquid_return [boolean]
def first
@index == 0
end
# @liquid_public_docs
# @liquid_summary
# Returns `true` if the current iteration is the last. Returns `false` if not.
# @liquid_return [boolean]
def last
@index == @length - 1
end
+456 -57
View File
@@ -22,39 +22,107 @@ module Liquid
)
STRIP_HTML_TAGS = /<.*?>/m
# Return the size of an array or of an string
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name size
# @liquid_summary
# Returns the size of a string or array.
# @liquid_description
# The size of a string is the number of characters that the string includes. The size of an array is the number of items
# in the array.
# @liquid_syntax variable | size
# @liquid_return [number]
def size(input)
input.respond_to?(:size) ? input.size : 0
end
# convert an input string to DOWNCASE
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name downcase
# @liquid_summary
# Converts a string to all lowercase characters.
# @liquid_syntax string | downcase
# @liquid_return [string]
def downcase(input)
input.to_s.downcase
end
# convert an input string to UPCASE
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name upcase
# @liquid_summary
# Converts a string to all uppercase characters.
# @liquid_syntax string | upcase
# @liquid_return [string]
def upcase(input)
input.to_s.upcase
end
# capitalize words in the input centence
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name capitalize
# @liquid_summary
# Capitalizes the first word in a string.
# @liquid_syntax string | capitalize
# @liquid_return [string]
def capitalize(input)
input.to_s.capitalize
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name escape
# @liquid_summary
# Escapes a string.
# @liquid_syntax string | escape
# @liquid_return [string]
def escape(input)
CGI.escapeHTML(input.to_s) unless input.nil?
end
alias_method :h, :escape
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name escape_once
# @liquid_summary
# Escapes a string without changing characters that have already been escaped.
# @liquid_syntax string | escape_once
# @liquid_return [string]
def escape_once(input)
input.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name url_encode
# @liquid_summary
# Converts any URL-unsafe characters in a string to the
# [percent-encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding) equivalent.
# @liquid_description
# > Note:
# > Spaces are converted to a `+` charcter, instead of a percent-encoded character.
# @liquid_syntax string | url_encode
# @liquid_return [string]
def url_encode(input)
CGI.escape(input.to_s) unless input.nil?
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name url_decode
# @liquid_summary
# Decodes any [percent-encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding) characters
# in a string.
# @liquid_syntax string | url_decode
# @liquid_return [string]
def url_decode(input)
return if input.nil?
@@ -64,26 +132,71 @@ module Liquid
result
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name base64_encode
# @liquid_summary
# Encodes a string to [Base64 format](https://developer.mozilla.org/en-US/docs/Glossary/Base64).
# @liquid_syntax string | base64_encode
# @liquid_return [string]
def base64_encode(input)
Base64.strict_encode64(input.to_s)
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name base64_decode
# @liquid_summary
# Decodes a string in [Base64 format](https://developer.mozilla.org/en-US/docs/Glossary/Base64).
# @liquid_syntax string | base64_decode
# @liquid_return [string]
def base64_decode(input)
Base64.strict_decode64(input.to_s)
rescue ::ArgumentError
raise Liquid::ArgumentError, "invalid base64 provided to base64_decode"
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name base64_url_safe_encode
# @liquid_summary
# Encodes a string to URL-safe [Base64 format](https://developer.mozilla.org/en-US/docs/Glossary/Base64).
# @liquid_syntax string | base64_url_safe_encode
# @liquid_return [string]
def base64_url_safe_encode(input)
Base64.urlsafe_encode64(input.to_s)
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name base64_url_safe_decode
# @liquid_summary
# Decodes a string in URL-safe [Base64 format](https://developer.mozilla.org/en-US/docs/Glossary/Base64).
# @liquid_syntax string | base64_url_safe_decode
# @liquid_return [string]
def base64_url_safe_decode(input)
Base64.urlsafe_decode64(input.to_s)
rescue ::ArgumentError
raise Liquid::ArgumentError, "invalid base64 provided to base64_url_safe_decode"
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name slice
# @liquid_summary
# Returns a substring or series of array items, starting at a given 0-based index.
# @liquid_description
# By default, the substring has a length of one character, and the array series has one array item. However, you can
# provide a second parameter to specify the number of characters or array items.
#
# You can also supply a negative index which will count from the end of the string.
# @liquid_syntax string | slice
# @liquid_return [string]
def slice(input, offset, length = nil)
offset = Utils.to_integer(offset)
length = length ? Utils.to_integer(length) : 1
@@ -95,7 +208,17 @@ module Liquid
end
end
# Truncate a string down to x characters
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name truncate
# @liquid_summary
# Truncates a string down to a given number of characters.
# @liquid_description
# If the specified number of characters is less than the length of the string, then an ellipsis (`...`) is appended to
# the truncated string. The ellipsis is included in the character count of the truncated string.
# @liquid_syntax string | truncate: number
# @liquid_return [string]
def truncate(input, length = 50, truncate_string = "...")
return if input.nil?
input_str = input.to_s
@@ -109,6 +232,17 @@ module Liquid
input_str.length > length ? input_str[0...l].concat(truncate_string_str) : input_str
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name truncatewords
# @liquid_summary
# Truncates a string down to a given number of words.
# @liquid_description
# If the specified number of words is less than the number of words in the string, then an ellipsis (`...`) is appended to
# the truncated string.
# @liquid_syntax string | truncatewords: number
# @liquid_return [string]
def truncatewords(input, words = 15, truncate_string = "...")
return if input.nil?
input = input.to_s
@@ -128,27 +262,62 @@ module Liquid
wordlist.join(" ").concat(truncate_string.to_s)
end
# Split input string into an array of substrings separated by given pattern.
#
# Example:
# <div class="summary">{{ post | split '//' | first }}</div>
#
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name split
# @liquid_summary
# Splits a string into an array of substrings based on a given separator.
# @liquid_syntax string | split: string
# @liquid_return [array[string]]
def split(input, pattern)
input.to_s.split(pattern.to_s)
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name strip
# @liquid_summary
# Strips all whitespace from the left and right of a string.
# @liquid_syntax string | strip
# @liquid_return [string]
def strip(input)
input.to_s.strip
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name lstrip
# @liquid_summary
# Strips all whitespace from the left of a string.
# @liquid_syntax string | lstrip
# @liquid_return [string]
def lstrip(input)
input.to_s.lstrip
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name rstrip
# @liquid_summary
# Strips all whitespace from the right of a string.
# @liquid_syntax string | rstrip
# @liquid_return [string]
def rstrip(input)
input.to_s.rstrip
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name strip_html
# @liquid_summary
# Strips all HTML tags from a string.
# @liquid_syntax string | strip_html
# @liquid_return [string]
def strip_html(input)
empty = ''
result = input.to_s.gsub(STRIP_HTML_BLOCKS, empty)
@@ -156,18 +325,38 @@ module Liquid
result
end
# Remove all newlines from the string
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name strip_newlines
# @liquid_summary
# Strips all newline characters (line breaks) from a string.
# @liquid_syntax string | strip_newlines
# @liquid_return [string]
def strip_newlines(input)
input.to_s.gsub(/\r?\n/, '')
end
# Join elements of the array with certain character between them
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name join
# @liquid_summary
# Combines all the items in an array into a single string, separated by a space.
# @liquid_syntax array | join
# @liquid_return [string]
def join(input, glue = ' ')
InputIterator.new(input, context).join(glue)
end
# Sort elements of the array
# provide optional property with which to sort an array of hashes or drops
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name sort
# @liquid_summary
# Sorts the items in an array in case-sensitive alphabetical, or numerical, order.
# @liquid_syntax array | sort
# @liquid_return [array[untyped]]
def sort(input, property = nil)
ary = InputIterator.new(input, context)
@@ -186,8 +375,14 @@ module Liquid
end
end
# Sort elements of an array ignoring case if strings
# provide optional property with which to sort an array of hashes or drops
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name sort
# @liquid_summary
# Sorts the items in an array in case-insensitive alphabetical, or numerical, order.
# @liquid_syntax array | sort
# @liquid_return [array[untyped]]
def sort_natural(input, property = nil)
ary = InputIterator.new(input, context)
@@ -206,8 +401,19 @@ module Liquid
end
end
# Filter the elements of an array to those with a certain property value.
# By default the target is any truthy value.
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name where
# @liquid_summary
# Filters an array to include only items with a specific property value.
# @liquid_description
# You can use the `where` filter in the following ways:
#
# - Filter for items with a specific property value. This requires you to provide both the property name and the associated value.
# - Filter for items that have a `true` value for a boolean property. This requires only the property name.
# @liquid_syntax array | where: string, string
# @liquid_return [array[untyped]]
def where(input, property, target_value = nil)
ary = InputIterator.new(input, context)
@@ -234,8 +440,14 @@ module Liquid
end
end
# Remove duplicate elements from an array
# provide optional property with which to determine uniqueness
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name uniq
# @liquid_summary
# Removes any duplicate items in an array.
# @liquid_syntax array | uniq
# @liquid_return [array[untyped]]
def uniq(input, property = nil)
ary = InputIterator.new(input, context)
@@ -255,13 +467,27 @@ module Liquid
end
end
# Reverse the elements of an array
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name reverse
# @liquid_summary
# Reverses the order of the items in an array.
# @liquid_syntax array | reverse
# @liquid_return [array[untyped]]
def reverse(input)
ary = InputIterator.new(input, context)
ary.reverse
end
# map/collect on a given property
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name map
# @liquid_summary
# Creates an array of values from a specific property of the items in an array.
# @liquid_syntax array | map: string
# @liquid_return [array[untyped]]
def map(input, property)
InputIterator.new(input, context).map do |e|
e = e.call if e.is_a?(Proc)
@@ -277,8 +503,14 @@ module Liquid
raise_property_error(property)
end
# Remove nils within an array
# provide optional property with which to check for nil
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name map
# @liquid_summary
# Removes any `nil` items from an array.
# @liquid_syntax array | compact
# @liquid_return [array[untyped]]
def compact(input, property = nil)
ary = InputIterator.new(input, context)
@@ -298,17 +530,38 @@ module Liquid
end
end
# Replace occurrences of a string with another
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name replace
# @liquid_summary
# Replaces any instance of a substring inside a string with a given string.
# @liquid_syntax string | replace: string, string
# @liquid_return [string]
def replace(input, string, replacement = '')
input.to_s.gsub(string.to_s, replacement.to_s)
end
# Replace the first occurrences of a string with another
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name replace_first
# @liquid_summary
# Replaces the first instance of a substring inside a string with a given string.
# @liquid_syntax string | replace_first: string, string
# @liquid_return [string]
def replace_first(input, string, replacement = '')
input.to_s.sub(string.to_s, replacement.to_s)
end
# Replace the last occurrences of a string with another
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name replace_last
# @liquid_summary
# Replaces the last instance of a substring inside a string with a given string.
# @liquid_syntax string | replace_last: string, string
# @liquid_return [string]
def replace_last(input, string, replacement)
input = input.to_s
string = string.to_s
@@ -323,26 +576,66 @@ module Liquid
output
end
# remove a substring
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name replace
# @liquid_summary
# Removes any instance of a substring inside a string.
# @liquid_syntax string | remove: string
# @liquid_return [string]
def remove(input, string)
replace(input, string, '')
end
# remove the first occurrences of a substring
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name remove_first
# @liquid_summary
# Removes the first instance of a substring inside a string.
# @liquid_syntax string | remove_first: string
# @liquid_return [string]
def remove_first(input, string)
replace_first(input, string, '')
end
# remove the last occurences of a substring
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name remove_last
# @liquid_summary
# Removes the last instance of a substring inside a string.
# @liquid_syntax string | remove_last: string
# @liquid_return [string]
def remove_last(input, string)
replace_last(input, string, '')
end
# add one string to another
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name append
# @liquid_summary
# Adds a given string to the end of a string.
# @liquid_syntax string | append: string
# @liquid_return [string]
def append(input, string)
input.to_s + string.to_s
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name concat
# @liquid_summary
# Concatenates (combines) two arrays.
# @liquid_description
# > Note:
# > The `concat` filter won't filter out duplicates. If you want to remove duplicates, then you need to use the
# > [`uniq` filter](/api/liquid/filters#uniq).
# @liquid_syntax array | concat: array
# @liquid_return [array[untyped]]
def concat(input, array)
unless array.respond_to?(:to_ary)
raise ArgumentError, "concat filter requires an array argument"
@@ -350,12 +643,26 @@ module Liquid
InputIterator.new(input, context).concat(array)
end
# prepend a string to another
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name prepend
# @liquid_summary
# Adds a given string to the beginning of a string.
# @liquid_syntax string | prepend: string
# @liquid_return [string]
def prepend(input, string)
string.to_s + input.to_s
end
# Add <br /> tags in front of all newlines in input string
# @liquid_public_docs
# @liquid_type filter
# @liquid_category string
# @liquid_name newline_to_br
# @liquid_summary
# Converts newlines (`\n`) in a string to HTML line breaks (`<br>`).
# @liquid_syntax string | newline_to_br
# @liquid_return [string]
def newline_to_br(input)
input.to_s.gsub(/\r?\n/, "<br />\n")
end
@@ -399,58 +706,115 @@ module Liquid
date.strftime(format.to_s)
end
# Get the first element of the passed in array
#
# Example:
# {{ product.images | first | to_img }}
#
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name first
# @liquid_summary
# Returns the first item in the array.
# @liquid_syntax string | first
# @liquid_return [string]
def first(array)
array.first if array.respond_to?(:first)
end
# Get the last element of the passed in array
#
# Example:
# {{ product.images | last | to_img }}
#
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name last
# @liquid_summary
# Returns the last item in the array.
# @liquid_syntax string | last
# @liquid_return [string]
def last(array)
array.last if array.respond_to?(:last)
end
# absolute value
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name abs
# @liquid_summary
# Returns the absolute value of a number.
# @liquid_syntax number | abs
# @liquid_return [number]
def abs(input)
result = Utils.to_number(input).abs
result.is_a?(BigDecimal) ? result.to_f : result
end
# addition
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name plus
# @liquid_summary
# Adds two numbers.
# @liquid_syntax number | plus: number
# @liquid_return [number]
def plus(input, operand)
apply_operation(input, operand, :+)
end
# subtraction
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name minus
# @liquid_summary
# Subtracts a given number from another number.
# @liquid_syntax number | minus: number
# @liquid_return [number]
def minus(input, operand)
apply_operation(input, operand, :-)
end
# multiplication
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name times
# @liquid_summary
# Multiplies two numbers.
# @liquid_syntax number | times: number
# @liquid_return [number]
def times(input, operand)
apply_operation(input, operand, :*)
end
# division
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name minus
# @liquid_summary
# Divides a number by a given number.
# @liquid_syntax number | minus: number
# @liquid_return [number]
def divided_by(input, operand)
apply_operation(input, operand, :/)
rescue ::ZeroDivisionError => e
raise Liquid::ZeroDivisionError, e.message
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name modulo
# @liquid_summary
# Returns the remainder of dividing a number by a given number.
# @liquid_syntax number | modulo: number
# @liquid_return [number]
def modulo(input, operand)
apply_operation(input, operand, :%)
rescue ::ZeroDivisionError => e
raise Liquid::ZeroDivisionError, e.message
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name round
# @liquid_summary
# Rounds a number to the nearest integer.
# @liquid_syntax number | round
# @liquid_return [number]
def round(input, n = 0)
result = Utils.to_number(input).round(Utils.to_number(n))
result = result.to_f if result.is_a?(BigDecimal)
@@ -460,18 +824,42 @@ module Liquid
raise Liquid::FloatDomainError, e.message
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name ceil
# @liquid_summary
# Rounds a number up to the nearest integer.
# @liquid_syntax number | ceil
# @liquid_return [number]
def ceil(input)
Utils.to_number(input).ceil.to_i
rescue ::FloatDomainError => e
raise Liquid::FloatDomainError, e.message
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name floor
# @liquid_summary
# Rounds a number down to the nearest integer.
# @liquid_syntax number | floor
# @liquid_return [number]
def floor(input)
Utils.to_number(input).floor.to_i
rescue ::FloatDomainError => e
raise Liquid::FloatDomainError, e.message
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name at_least
# @liquid_summary
# Limits a number to a minimum value.
# @liquid_syntax number | at_least
# @liquid_return [number]
def at_least(input, n)
min_value = Utils.to_number(n)
@@ -480,6 +868,14 @@ module Liquid
result.is_a?(BigDecimal) ? result.to_f : result
end
# @liquid_public_docs
# @liquid_type filter
# @liquid_category math
# @liquid_name at_most
# @liquid_summary
# Limits a number to a maximum value.
# @liquid_syntax number | at_most
# @liquid_return [number]
def at_most(input, n)
max_value = Utils.to_number(n)
@@ -488,16 +884,19 @@ module Liquid
result.is_a?(BigDecimal) ? result.to_f : result
end
# Set a default value when the input is nil, false or empty
#
# Example:
# {{ product.title | default: "No Title" }}
#
# Use `allow_false` when an input should only be tested against nil or empty and not false.
#
# Example:
# {{ product.title | default: "No Title", allow_false: true }}
# @liquid_public_docs
# @liquid_type filter
# @liquid_category array
# @liquid_name default
# @liquid_summary
# Sets a default value for any variable whose value is one of the following:
#
# - [`EmptyDrop`](/api/liquid/basics#emptydrop)
# - [`false`](/api/liquid/basics#truthy-and-falsy)
# - [`nil`](/api/liquid/basics#nil)
# @liquid_syntax variable | default: variable
# @liquid_optional_param allow_false [boolean] Whether to use false values instead of the default.
# @liquid_return [variable]
def default(input, default_value = '', options = {})
options = {} unless options.is_a?(Hash)
false_check = options['allow_false'] ? input.nil? : !Liquid::Utils.to_liquid_value(input)
+61 -1
View File
@@ -1,6 +1,11 @@
# frozen_string_literal: true
module Liquid
# @liquid_public_docs
# @liquid_type object
# @liquid_name forloop
# @liquid_summary
# The `tablerow` object contains information about a parent [`tablerow` loop](/api/liquid/tags#tablerow).
class TablerowloopDrop < Drop
def initialize(length, cols)
@length = length
@@ -10,40 +15,95 @@ module Liquid
@index = 0
end
attr_reader :length, :col, :row
# @liquid_public_docs
# @liquid_name tablerow.length
# @liquid_summary
# The number of iterations.
# @liquid_return [number]
attr_reader :length
# @liquid_public_docs
# @liquid_name tablerow.col
# @liquid_summary
# The 1-based index of the current column.
# @liquid_return [number]
attr_reader :col
# @liquid_public_docs
# @liquid_name tablerow.row
# @liquid_summary
# The 1-based index of current row.
# @liquid_return [number]
attr_reader :row
# @liquid_public_docs
# @liquid_summary
# The 1-based index of the current iteration.
# @liquid_return [number]
def index
@index + 1
end
# @liquid_public_docs
# @liquid_summary
# The 0-based index of the current iteration.
# @liquid_return [number]
def index0
@index
end
# @liquid_public_docs
# @liquid_summary
# The 0-based index of the current column.
# @liquid_return [number]
def col0
@col - 1
end
# @liquid_public_docs
# @liquid_summary
# The 1-based index of the current iteration, in reverse order.
# @liquid_return [number]
def rindex
@length - @index
end
# @liquid_public_docs
# @liquid_summary
# The 0-based index of the current iteration, in reverse order.
# @liquid_return [number]
def rindex0
@length - @index - 1
end
# @liquid_public_docs
# @liquid_summary
# Returns `true` if the current iteration is the first. Returns `false` if not.
# @liquid_return [boolean]
def first
@index == 0
end
# @liquid_public_docs
# @liquid_summary
# Returns `true` if the current iteration is the last. Returns `false` if not.
# @liquid_return [boolean]
def last
@index == @length - 1
end
# @liquid_public_docs
# @liquid_summary
# Returns `true` if the current column is the first in the row. Returns `false` if not.
# @liquid_return [boolean]
def col_first
@col == 1
end
# @liquid_public_docs
# @liquid_summary
# Returns `true` if the current column is the last in the row. Returns `false` if not.
# @liquid_return [boolean]
def col_last
@col == @cols
end
+12 -8
View File
@@ -1,14 +1,18 @@
# frozen_string_literal: true
module Liquid
# Assign sets a variable in your template.
#
# {% assign foo = 'monkey' %}
#
# You can then use the variable later in the page.
#
# {{ foo }}
#
# @liquid_public_docs
# @liquid_type tag
# @liquid_category variable
# @liquid_name assign
# @liquid_summary
# Creates a new variable.
# @liquid_description
# You can create variables of any [basic type](/api/liquid/basics#types), [object](/api/liquid/objects), or object property.
# @liquid_syntax
# {% assign variable_name = value %}
# @liquid_syntax_keyword variable_name The name of the variable being created.
# @liquid_syntax_keyword value The value you want to assign to the variable.
class Assign < Tag
Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/om
+8 -9
View File
@@ -1,15 +1,14 @@
# frozen_string_literal: true
module Liquid
# Break tag to be used to break out of a for loop.
#
# == Basic Usage:
# {% for item in collection %}
# {% if item.condition %}
# {% break %}
# {% endif %}
# {% endfor %}
#
# @liquid_public_docs
# @liquid_type tag
# @liquid_category iteration
# @liquid_name break
# @liquid_summary
# Stops a [`for` loop](/api/liquid/tags#for) from iterating.
# @liquid_syntax
# {% break %}
class Break < Tag
INTERRUPT = BreakInterrupt.new.freeze
+13 -10
View File
@@ -1,17 +1,20 @@
# frozen_string_literal: true
module Liquid
# Capture stores the result of a block into a variable without rendering it inplace.
#
# {% capture heading %}
# Monkeys!
# @liquid_public_docs
# @liquid_type tag
# @liquid_category variable
# @liquid_name capture
# @liquid_summary
# Creates a new variable with a string value.
# @liquid_description
# You can create complex strings with Liquid logic and variables.
# @liquid_syntax
# {% capture variable %}
# value
# {% endcapture %}
# ...
# <h1>{{ heading }}</h1>
#
# Capture is useful for saving content for use later in your template, such as
# in a sidebar or footer.
#
# @liquid_syntax_keyword variable The name of the variable being created.
# @liquid_syntax_keyword value The value you want to assign to the variable.
class Capture < Block
Syntax = /(#{VariableSignature}+)/o
+18
View File
@@ -1,6 +1,24 @@
# frozen_string_literal: true
module Liquid
# @liquid_public_docs
# @liquid_type tag
# @liquid_category conditional
# @liquid_name case
# @liquid_summary
# Renders a specific expression depending on the value of a specific variable.
# @liquid_syntax
# {% case variable %}
# {% when value %}
# expression
# {% when value %}
# expression
# {% else %}
# expression
# {% endcase %}
# @liquid_syntax_keyword variable The name of the variable you want to base your case statement on.
# @liquid_syntax_keyword value A specific value to check for.
# @liquid_syntax_keyword expression An expression to be rendered when the variable's value matches the value being checked.
class Case < Block
Syntax = /(#{QuotedFragment})/o
WhenSyntax = /(#{QuotedFragment})(?:(?:\s+or\s+|\s*\,\s*)(#{QuotedFragment}.*))?/om
+13
View File
@@ -1,6 +1,19 @@
# frozen_string_literal: true
module Liquid
# @liquid_public_docs
# @liquid_type tag
# @liquid_category syntax
# @liquid_name comment
# @liquid_summary
# Prevents an expression from being rendered or output.
# @liquid_description
# Any text inside `comment` tags won't be output, and any Liquid code won't be rendered.
# @liquid_syntax
# {% comment %}
# content
# {% endcomment %}
# @liquid_syntax_keyword content The content of the comment.
class Comment < Block
def render_to_output_buffer(_context, output)
output
+8 -9
View File
@@ -1,15 +1,14 @@
# frozen_string_literal: true
module Liquid
# Continue tag to be used to break out of a for loop.
#
# == Basic Usage:
# {% for item in collection %}
# {% if item.condition %}
# {% continue %}
# {% endif %}
# {% endfor %}
#
# @liquid_public_docs
# @liquid_type tag
# @liquid_category iteration
# @liquid_name continue
# @liquid_summary
# Causes a [`for` loop](/api/liquid/tags#for) to skip to the next iteration.
# @liquid_syntax
# {% continue %}
class Continue < Tag
INTERRUPT = ContinueInterrupt.new.freeze
+11 -12
View File
@@ -1,18 +1,17 @@
# frozen_string_literal: true
module Liquid
# Cycle is usually used within a loop to alternate between values, like colors or DOM classes.
#
# {% for item in items %}
# <div class="{% cycle 'red', 'green', 'blue' %}"> {{ item }} </div>
# {% end %}
#
# <div class="red"> Item one </div>
# <div class="green"> Item two </div>
# <div class="blue"> Item three </div>
# <div class="red"> Item four </div>
# <div class="green"> Item five</div>
#
# @liquid_public_docs
# @liquid_type tag
# @liquid_category iteration
# @liquid_name cycle
# @liquid_summary
# Loops through a group of strings and outputs them one at a time for each iteration of a [`for` loop](/api/liquid/tags#for).
# @liquid_description
# > Note:
# > The `cycle` tag must be used inside a `for` loop.
# @liquid_syntax
# {% cycle string, string, ... %}
class Cycle < Tag
SimpleSyntax = /\A#{QuotedFragment}+/o
NamedSyntax = /\A(#{QuotedFragment})\s*\:\s*(.*)/om
+16 -17
View File
@@ -1,24 +1,23 @@
# frozen_string_literal: true
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.
# NOTE: decrement is a pre-decrement, --i,
# while increment is post: i++.
#
# (To achieve the survival, the application must keep the context)
#
# if the variable does not exist, it is created with value 0.
# Hello: {% decrement variable %}
#
# gives you:
#
# Hello: -1
# Hello: -2
# Hello: -3
# @liquid_public_docs
# @liquid_type tag
# @liquid_category variable
# @liquid_name decrement
# @liquid_summary
# Creates a new variable, with a default value of -1, that's decreased by 1 with each subsequent call.
# @liquid_desription
# Variables that are declared with `decrement` are unique to the file ([layout](/themes/architecture/layouts), [section](/themes/architecture/sections),
# or [template](/themes/architecture/templates)) that they're created in. However, these variables are shared across
# [snippets](/themes/architecture#snippets) inside each of those files.
#
# Similarly, variables that are created with `decrement` are are unique to those created with [`assign`](/api/liquid/tags#assign)
# and [`capture`](/api/liquid/tags#capture). However, these variables are shared with variables created with
# [`increment`](/api/liquid/tags#increment).
# @liquid_syntax
# {% decrement variable_name %}
# @liquid_syntax_keyword variable_name The name of the variable being decremented.
class Decrement < Tag
def initialize(tag_name, markup, options)
super
+14 -9
View File
@@ -1,16 +1,21 @@
# frozen_string_literal: true
module Liquid
# Echo outputs an expression
#
# {% echo monkey %}
# {% echo user.name %}
#
# This is identical to variable output syntax, like {{ foo }}, but works
# inside {% liquid %} tags. The full syntax is supported, including filters:
#
# {% echo user | link %}
# @liquid_public_docs
# @liquid_type tag
# @liquid_category syntax
# @liquid_name echo
# @liquid_summary
# Outputs an expression.
# @liquid_desription
# Using the `echo` tag is the same as wrapping an expression in `{{` and `}}`, however you can use it inside
# [`liquid` tags](/api/liquid/tags#liquid).
#
# > Note:
# > You can use [filters](/api/liquid/filters) on expressions inside `echo` tags.
# @liquid_syntax
# {% echo expression %}
# @liquid_syntax_keyword expression The expression to be output.
class Echo < Tag
attr_reader :variable
+22 -43
View File
@@ -1,50 +1,29 @@
# frozen_string_literal: true
module Liquid
# "For" iterates over an array or collection.
# Several useful variables are available to you within the loop.
#
# == Basic usage:
# {% for item in collection %}
# {{ forloop.index }}: {{ item.name }}
# {% endfor %}
#
# == Advanced usage:
# {% for item in collection %}
# <div {% if forloop.first %}class="first"{% endif %}>
# Item {{ forloop.index }}: {{ item.name }}
# </div>
# {% else %}
# There is nothing in the collection.
# {% endfor %}
#
# You can also define a limit and offset much like SQL. Remember
# that offset starts at 0 for the first item.
#
# {% for item in collection limit:5 offset:10 %}
# {{ item.name }}
# {% end %}
#
# To reverse the for loop simply use {% for item in collection reversed %} (note that the flag's spelling is different to the filter `reverse`)
#
# == Available variables:
#
# forloop.name:: 'item-collection'
# forloop.length:: Length of the loop
# forloop.index:: The current item's position in the collection;
# forloop.index starts at 1.
# This is helpful for non-programmers who start believe
# the first item in an array is 1, not 0.
# forloop.index0:: The current item's position in the collection
# where the first item is 0
# forloop.rindex:: Number of items remaining in the loop
# (length - index) where 1 is the last item.
# forloop.rindex0:: Number of items remaining in the loop
# where 0 is the last item.
# forloop.first:: Returns true if the item is the first item.
# forloop.last:: Returns true if the item is the last item.
# forloop.parentloop:: Provides access to the parent loop, if present.
# @liquid_public_docs
# @liquid_type tag
# @liquid_category iteration
# @liquid_name for
# @liquid_summary
# Renders an expression for every item in an array.
# @liquid_desription
# > Tip:
# > Every `for` loop has an associated [`forloop` object](/api/liquid/objects#forloop) with information about the loop.
#
# You can do a maximum of 50 iterations with a `for` loop. If you need to iterate over more than 50 items, then use the
# [`paginate` tag](/api/liquid/tags#paginate) to split the items over multiple pages.
# @liquid_syntax
# {% for variable in array %}
# expression
# {% endfor %}
# @liquid_syntax_keyword variable The current item in the array.
# @liquid_syntax_keyword array The array to iterate over.
# @liquid_syntax_keyword expression The expression to render.
# @liquid_optional_param limit [number] The number of iterations to perform.
# @liquid_optional_param offset [number] The 1-based index to start iterating at.
# @liquid_optional_param range [untyped] A custom numeric range to iterate over.
# @liquid_optional_param reversed [untyped] Iterate in reverse order.
class For < Block
Syntax = /\A(#{VariableSegment}+)\s+in\s+(#{QuotedFragment}+)\s*(reversed)?/o
+11 -9
View File
@@ -1,16 +1,18 @@
# frozen_string_literal: true
module Liquid
# If is the conditional block
#
# {% if user.admin %}
# Admin user!
# {% else %}
# Not admin user
# @liquid_public_docs
# @liquid_type tag
# @liquid_category conditional
# @liquid_name if
# @liquid_summary
# Renders an expression if a specific condition is `true`.
# @liquid_syntax
# {% if condition %}
# expression
# {% endif %}
#
# There are {% if count < 5 %} less {% else %} more {% endif %} items than you need.
#
# @liquid_syntax_keyword condition The condition to evaluate.
# @liquid_syntax_keyword expression The expression to render if the condition is met.
class If < Block
Syntax = /(#{QuotedFragment})\s*([=!<>a-z_]+)?\s*(#{QuotedFragment})?/o
ExpressionsAndOperators = /(?:\b(?:\s?and\s?|\s?or\s?)\b|(?:\s*(?!\b(?:\s?and\s?|\s?or\s?)\b)(?:#{QuotedFragment}|\S+)\s*)+)/o
+16 -13
View File
@@ -1,20 +1,23 @@
# frozen_string_literal: true
module Liquid
# Include allows templates to relate with other templates
#
# Simply include another template:
#
# {% include 'product' %}
#
# Include a template with a local variable:
#
# {% include 'product' with products[0] %}
#
# Include a template for a collection:
#
# {% include 'product' for products %}
# @liquid_public_docs
# @liquid_type tag
# @liquid_category theme
# @liquid_name include
# @liquid_summary
# Renders a [snippet](/themes/architecture#snippets).
# @liquid_description
# Inside the snippet, you can access and alter variables that are [created](/api/liquid/tags#variable-tags) outside of the
# snippet.
# @liquid_syntax
# {% include 'filename' %}
# @liquid_syntax_keyword filename The name of the snippet to render, without the `.liquid` extension.
# @liquid_deprecated
# Deprecated because the way that variables are handled reduces performance and makes code harder to both read and maintain.
#
# > Tip:
# > The `include` tag has been replaced by [`render`](/api/liquid/tags#render).
class Include < Tag
prepend Tag::Disableable
+16 -14
View File
@@ -1,21 +1,23 @@
# frozen_string_literal: true
module Liquid
# increment 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.
# (To achieve the survival, the application must keep the context)
#
# if the variable does not exist, it is created with value 0.
#
# Hello: {% increment variable %}
#
# gives you:
#
# Hello: 0
# Hello: 1
# Hello: 2
# @liquid_public_docs
# @liquid_type tag
# @liquid_category variable
# @liquid_name increment
# @liquid_summary
# Creates a new variable, with a default value of 0, that's increased by 1 with each subsequent call.
# @liquid_desription
# Variables that are declared with `increment` are unique to the file ([layout](/themes/architecture/layouts), [section](/themes/architecture/sections),
# or [template](/themes/architecture/templates)) that they're created in. However, these variables are shared across
# [snippets](/themes/architecture#snippets) inside each of those files.
#
# Similarly, variables that are created with `increment` are are unique to those created with [`assign`](/api/liquid/tags#assign)
# and [`capture`](/api/liquid/tags#capture). However, these variables are shared with variables created with
# [`decrement`](/api/liquid/tags#decrement).
# @liquid_syntax
# {% increment variable_name %}
# @liquid_syntax_keyword variable_name The name of the variable being decremented.
class Increment < Tag
def initialize(tag_name, markup, options)
super
+11
View File
@@ -1,6 +1,17 @@
# frozen_string_literal: true
module Liquid
# @liquid_public_docs
# @liquid_type tag
# @liquid_category syntax
# @liquid_name raw
# @liquid_summary
# Outputs any Liquid code as text instead of rendering it.
# @liquid_syntax
# {% raw %}
# expression
# {% endraw %}
# @liquid_syntax_keyword expression The expression to be output without being rendered.
class Raw < Block
Syntax = /\A\s*\z/
FullTokenPossiblyInvalid = /\A(.*)#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/om
+24
View File
@@ -1,6 +1,30 @@
# frozen_string_literal: true
module Liquid
# @liquid_public_docs
# @liquid_type tag
# @liquid_category theme
# @liquid_name include
# @liquid_summary
# Renders a [snippet](/themes/architecture#snippets).
# @liquid_description
# > Tip:
# > The `render` tag is also used to [render app blocks](/themes/architecture/sections/section-schema#render-app-blocks).
#
# Inside the snippet, there's no direct access to variables that are [created](/api/liquid/tags#variable-tags) outside
# of the snippet. If you want to pass in outside variables, then you can [specify variables as parameters](/api/liquid/tags#render-passing-variables-to-snippets).
#
# While there's no direct access to created variables, there's access to global objects, as well as any objects that are
# directly accessible outside the snippet.
#
# Outside the snippet, you can't access variables created inside the snippet.
#
# > Note:
# > When a snippet is rendered using the `render` tag, you can't use the [`include` tag](/api/liquid/tags#include)
# > inside the snippet.
# @liquid_syntax
# {% render 'filename' %}
# @liquid_syntax_keyword filename The name of the snippet to render, without the `.liquid` extension.
class Render < Tag
FOR = 'for'
SYNTAX = /(#{QuotedString}+)(\s+(with|#{FOR})\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
+22
View File
@@ -1,6 +1,28 @@
# frozen_string_literal: true
module Liquid
# @liquid_public_docs
# @liquid_type tag
# @liquid_category iteration
# @liquid_name tablerow
# @liquid_summary
# Generates HTML table rows for every item in an array.
# @liquid_desription
# The `tablerow` tag must be wrapped in HTML `<table>` and `</table>` tags.
#
# > Tip:
# > Every `tablerow` loop has an associated [`tablerow` object](/api/liquid/objects#tablerow) with information about the loop.
# @liquid_syntax
# {% tablerow variable in array %}
# expression
# {% endtablerow %}
# @liquid_syntax_keyword variable The current item in the array.
# @liquid_syntax_keyword array The array to iterate over.
# @liquid_syntax_keyword expression The expression to render.
# @liquid_optional_param cols [number] The number of columns that the table should have.
# @liquid_optional_param limit [number] The number of iterations to perform.
# @liquid_optional_param offset [number] The 1-based index to start iterating at.
# @liquid_optional_param range [untyped] A custom numeric range to iterate over.
class TableRow < Block
Syntax = /(\w+)\s+in\s+(#{QuotedFragment}+)/o
+15 -4
View File
@@ -3,10 +3,21 @@
require_relative 'if'
module Liquid
# Unless is a conditional just like 'if' but works on the inverse logic.
#
# {% unless x < 0 %} x is greater than zero {% endunless %}
#
# @liquid_public_docs
# @liquid_type tag
# @liquid_category conditional
# @liquid_name unless
# @liquid_summary
# Renders an expression unless a specific condition is `true`.
# @liquid_description
# > Tip:
# > Similar to the [`if` tag](/api/liquid/tags#if), you can use `elsif` to add more conditions to an `unless` tag.
# @liquid_syntax
# {% unless condition %}
# expression
# {% endif %}
# @liquid_syntax_keyword condition The condition to evaluate.
# @liquid_syntax_keyword expression The expression to render unless the condition is met.
class Unless < If
def render_to_output_buffer(context, output)
# First condition is interpreted backwards ( if not )