Sha256: ec3e17148525ae1a859fff7eec0f98c7851f1e2a4318d2de242fa4a80b47a977

Contents?: true

Size: 1.96 KB

Versions: 5

Compression:

Stored size: 1.96 KB

Contents

# 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>
  #
  class Cycle < Tag
    SimpleSyntax = /\A#{QuotedFragment}+/o
    NamedSyntax  = /\A(#{QuotedFragment})\s*\:\s*(.*)/om

    attr_reader :variables

    def initialize(tag_name, markup, options)
      super
      case markup
      when NamedSyntax
        @variables = variables_from_string(Regexp.last_match(2))
        @name      = parse_expression(Regexp.last_match(1))
      when SimpleSyntax
        @variables = variables_from_string(markup)
        @name      = @variables.to_s
      else
        raise SyntaxError, options[:locale].t("errors.syntax.cycle")
      end
    end

    def render_to_output_buffer(context, output)
      context.registers[:cycle] ||= {}

      key       = context.evaluate(@name)
      iteration = context.registers[:cycle][key].to_i

      val = context.evaluate(@variables[iteration])

      if val.is_a?(Array)
        val = val.join
      elsif !val.is_a?(String)
        val = val.to_s
      end

      output << val

      iteration += 1
      iteration = 0 if iteration >= @variables.size

      context.registers[:cycle][key] = iteration
      output
    end

    private

    def variables_from_string(markup)
      markup.split(',').collect do |var|
        var =~ /\s*(#{QuotedFragment})\s*/o
        Regexp.last_match(1) ? parse_expression(Regexp.last_match(1)) : nil
      end.compact
    end

    class ParseTreeVisitor < Liquid::ParseTreeVisitor
      def children
        Array(@node.variables)
      end
    end
  end

  Template.register_tag('cycle', Cycle)
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
liquid-5.3.0 lib/liquid/tags/cycle.rb
liquid-5.2.0 lib/liquid/tags/cycle.rb
liquid-5.1.0 lib/liquid/tags/cycle.rb
liquid-5.0.1 lib/liquid/tags/cycle.rb
liquid-5.0.0 lib/liquid/tags/cycle.rb