How to call drop methods that take parameters...

1,146 views
Skip to first unread message

rrwhite

unread,
Mar 23, 2007, 1:58:28 AM3/23/07
to Liquid Templates
... seems like something that should be simple enough, but even after
scouring your site and this forum no one seems to even address this
issue. So I come before your exasperated and weary.

I'm in Mephisto and trying to get all the articles for a specific
section and iterate over them. If I was in rhtml templates I might do
the following (based on the drops available):

site.find_section('tutorials').pages.each do |page|

My problem is the find_section part. I see how I can get the section
by doing

{{ site | find_section: 'tutorials' }}

But trying to assign it doesn't work

{% assign tutorials = site | find_section: 'tutorials' %}

I'm trying to do assignment simply because I don't know how to chain
method calls together to get something like:

{% for page in (site | find_section: 'tutorials').pages %}

What am I missing?

Thanks

Rich

Ian Leitch

unread,
Mar 23, 2007, 7:55:28 AM3/23/07
to liquid-t...@googlegroups.com
Which variable is your drop? | is used for piping input to filters, not drops. Drops aren't designed to act as methods, they're more like a hash only using nicer dot-notation rather than [] element selection. For an example of to how "fudge" the passing of an argument to a drop, take a look at the usage of before_method(): http://home.leetsoft.com/liquid/wiki/HowTo#LiquidDrops
It looks like you're wanting to use filters however, so in this case your 'find_section' filter might look like this:

module MyFilters

    def find_section(site, category)
        . . .
    end

end

Might I also suggest you change the name to just 'section' as filters should be viewed as functions that transform data rather than something that performs an action of any external significance. 'find_section' just sounds semantically incorrect to me.

I assume from your use of '.pages', your 'find_section' filter returns a drop? I've not got much in the way of chained calls like that myself, though it appears to be syntactically correct.

If you could show us your 'find_section' code that would help us help you.

Cheers
Ian

rrwhite

unread,
Mar 23, 2007, 1:19:15 PM3/23/07
to Liquid Templates

Thanks for the quick response Ian, here is what my site drop looks
like.

class SiteDrop < BaseDrop

def find_section(path)
@section_index ||= sections.inject({}) { |memo, section|
memo.update section['path'] => section }
@section_index[path]
end

end

And you are correct that find_section itself returns another drop, one
for section, that I then want to call pages on to iterate over. The
link you provided me about drops says that you cannot invoke any
arguments on drop methods so maybe I'm up a creek here. If so would I
need to create a drop method like find_tutorials_section and hardcode
my path argument, that seems very unsavory.

Thanks for your help

Rich


On Mar 23, 4:55 am, "Ian Leitch" <port...@gmail.com> wrote:
> Which variable is your drop? | is used for piping input to filters, not
> drops. Drops aren't designed to act as methods, they're more like a hash
> only using nicer dot-notation rather than [] element selection. For an
> example of to how "fudge" the passing of an argument to a drop, take a look
> at the usage of before_method():http://home.leetsoft.com/liquid/wiki/HowTo#LiquidDrops
> It looks like you're wanting to use filters however, so in this case your
> 'find_section' filter might look like this:
>
> module MyFilters
>
> def find_section(site, category)
> . . .
> end
>
> end
>
> Might I also suggest you change the name to just 'section' as filters should
> be viewed as functions that transform data rather than something that
> performs an action of any external significance. 'find_section' just sounds
> semantically incorrect to me.
>
> I assume from your use of '.pages', your 'find_section' filter returns a
> drop? I've not got much in the way of chained calls like that myself, though
> it appears to be syntactically correct.
>
> If you could show us your 'find_section' code that would help us help you.
>
> Cheers
> Ian
>

Ian Leitch

unread,
Mar 23, 2007, 7:30:15 PM3/23/07
to liquid-t...@googlegroups.com
Provided your section names have the same format as methods do, i.e. /[a-zA-Z_]+[0-9_]*/ then you can do something like this:

class SiteDrop < BaseDrop
  def find_section
    @finder ||= SectionFinderDrop.new (@sections)
  end
end

class SectionFinderDrop < ::Liquid::Drop
  def initialize(sections)
    @sections = sections
  end

  def before_method(path)

    @section_index ||= sections.inject({}) { |memo, section|
memo.update section['path'] => section }
    @section_index[path]
  end
end

and in your template:

{% assign tutorials = site.find_section.tutorials %} # or site.find_section[tutorials] if you prefer

Again, 'site.section.tutorials' reads better to me ;)


On 23/03/07, rrwhite <rrw...@gmail.com > wrote:

rrwhite

unread,
Mar 23, 2007, 10:07:25 PM3/23/07
to Liquid Templates
Cool thanks.

I am a little confused though. I haven't written any of this code
myself, it's all straight out of Mephisto. So my question is: why
would they have public methods in their drops that have parameters? I
realize this is probably something I should put to them directly, but
I can't help but wonder if they themselves aren't fully aware of how
liquid templates work.

Thanks

Rich

On Mar 23, 4:30 pm, "Ian Leitch" <port...@gmail.com> wrote:
> Provided your section names have the same format as methods do, i.e.
> /[a-zA-Z_]+[0-9_]*/ then you can do something like this:
>
> class SiteDrop < BaseDrop
> def find_section
> @finder ||= SectionFinderDrop.new(@sections)
> end
> end
>
> class SectionFinderDrop < ::Liquid::Drop
> def initialize(sections)
> @sections = sections
> end
>
> def before_method(path)
> @section_index ||= sections.inject({}) { |memo, section|
> memo.update section['path'] => section }
> @section_index[path]
> end
> end
>
> and in your template:
>
> {% assign tutorials = site.find_section.tutorials %} # or
> site.find_section[tutorials]
> if you prefer
>
> Again, 'site.section.tutorials' reads better to me ;)
>

rrwhite

unread,
Mar 23, 2007, 10:19:20 PM3/23/07
to Liquid Templates
I just answerd my own question. They created a number of Filters that
just delegated to those drop methods.

Thanks

Rick Olson

unread,
Mar 24, 2007, 12:09:21 AM3/24/07
to liquid-t...@googlegroups.com
> My problem is the find_section part. I see how I can get the section
> by doing
>
> {{ site | find_section: 'tutorials' }}
>
> But trying to assign it doesn't work
>
> {% assign tutorials = site | find_section: 'tutorials' %}

In Mephisto, the filters know the current site. The above filter code
can be changed to this:

{{ 'tutorials' | section }}

Since you can't assign that, I added an assign_to filter:

{{ 'tutorials' | section | assign_to: 'tutorials' }}

--
Rick Olson
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com

rrwhite

unread,
Mar 24, 2007, 12:32:37 AM3/24/07
to Liquid Templates
Thanks Rick, that's what I found on the cheat sheet forum of Mephisto.
There's a wealth of Liquid information on the Mephisto forum it seems,
perhaps there should be a link to it on the Liquid site /shrug

Thanks everyone.

Reply all
Reply to author
Forward
0 new messages