counting drops that matched an if

222 views
Skip to first unread message

Michael Ivey

unread,
May 1, 2007, 10:58:09 AM5/1/07
to Liquid Templates
Hi folks. I'm using liquid for the reporting engine for a home-grown
conference management tool I've been working on the last year or so.

One of the things that keeps coming up from my users is a need to
count the number of items that matched an if condition. My first
reaction was to add some counters to drops, but I don't know what all
they're going to want to count.

Is there currently any facility for something like {% assign a = a + 1
%} (which I already know doesn't work)?

If not, what about the following syntax:

{% newcounter a %}
{% increment a %}
{% decrement a %}

I'll be happy to write it, but don't want to re-invent the wheel.

Suggestions on a better approach encouraged.

Ian Leitch

unread,
May 1, 2007, 11:58:43 AM5/1/07
to liquid-t...@googlegroups.com
You could just use a generic counter drop?

class Counter < ::Liquid::Drop

    def new
      self.class.new
    end

    def initialize(base=false)
        @count = 0
        @base = base
    end

    def increment
         if @base
            foo = self.class.new
            foo.increment
            return foo
        end

        @count += 1
    end
 
    def decrement
        @count -= 1
     end

     def value
         @value
     end

end

{% assign a = counter.new %}
{{ a.increment }}

You might need to choose a different method name other than 'new', I've not tested it. Also note the use of a 'base' flag that would be set to true when the template is rendered, to ensure you don't accidently use the original increment drop directly. Sorry if this is a little incoherent, I just woke up.

Michael Ivey

unread,
May 1, 2007, 12:02:07 PM5/1/07
to Liquid Templates
On May 1, 9:58 am, Michael Ivey <michael.i...@gmail.com> wrote:
> {% newcounter a %}
> {% increment a %}
> {% decrement a %}

I just went ahead and wrote the things. I called it counter, not
newcounter.


class Counter < Liquid::Tag
Syntax = /(#{Liquid::VariableSignature}+)/

def initialize(tag_name, markup, tokens)
if markup =~ Syntax
@to = $1
else
raise SyntaxError.new("Syntax Error in 'newcounter' - Valid
syntax: newcounter [var]")
end

super
end

def render(context)
context.scopes.last[@to.to_s] = 0
''
end

end
Liquid::Template.register_tag('counter', Counter)

class Increment < Liquid::Tag
Syntax = /(#{Liquid::VariableSignature}+)/

def initialize(tag_name, markup, tokens)
if markup =~ Syntax
@to = $1
else
raise SyntaxError.new("Syntax Error in 'increment' - Valid
syntax: increment [var]")
end

super
end

def render(context)
context.scopes.last[@to.to_s] += 1
''
end

end
Liquid::Template.register_tag('increment', Increment)

class Decrement < Liquid::Tag
Syntax = /(#{Liquid::VariableSignature}+)/

def initialize(tag_name, markup, tokens)
if markup =~ Syntax
@to = $1
else
raise SyntaxError.new("Syntax Error in 'decrement' - Valid
syntax: decrement [var]")
end

super
end

def render(context)
context.scopes.last[@to.to_s] -= 1
''
end

end
Liquid::Template.register_tag('decrement', Decrement)

I'll make it a patch if you want one, but they're simple enough.

Michael Ivey

unread,
May 1, 2007, 12:03:19 PM5/1/07
to Liquid Templates
I knew I should have waited. Yours is nicer.

Eric

unread,
May 1, 2007, 11:41:00 PM5/1/07
to Liquid Templates
You might want to check out the django templating:
http://www.djangoproject.com/documentation/templates/

It looks like they may use a filter for that:
http://www.djangoproject.com/documentation/templates/#add

Breno Perucchi

unread,
Sep 27, 2012, 3:55:21 PM9/27/12
to liquid-t...@googlegroups.com, michae...@gmail.com
Have way more easily to do that

{% assign counter = 0 %}
{% for product in products %}
{% capture temp %}{{ counter | plus: 1 }}{% endcapture %}
{% assign counter = temp %}
{% if counter == '6' %}
<div class'clear'></div>
{% assign counter = 0 %}
{% endif %} 
Reply all
Reply to author
Forward
0 new messages