That Guy
That Guy

Reputation: 103

Defining Liquid tag, returning string works but processing to return string doesn't?

I'm new to Liquid, but not to Ruby, and I know that Liquid isn't necessarily Ruby for safety reasons. However, in a Jekyll Blog, I tried to define the following code as a plugin:

module Jekyll
  class Person_Index < Liquid::Tag

    def initialize(tag_name, text, tokens)
      super
      @text = text
    end

    def render(context)
      for person in context.registers[:site].data["people"]

        if (person.index.to_s() == @text.to_s())
            return person.display
        end    
      end

      # We reach here, something's wrong anyway
      return "(( INDEX NOT FOUND #{@text} ))"
    end
  end
end

Liquid::Template.register_tag('Person_Index', Jekyll::Person_Index)

This, unsurprisingly, fails during document generation. Calling it as {% Person_Index 2 %} gives me this error:

Liquid Exception: wrong number of arguments (0 for 1) in _posts/2014-07-22-an-entry.md/#excerpt

I'm sure someone's thinking "maybe it somehow got caught by the buggy excerpt generation". I tried that workaround by simply rewriting it with a second paragraph as a test case ; it still gives the same error, it's just not in #excerpt anymore.

A direct change to render to make it a one liner will make it run without any hesitation, and output "just fine" (I say that in quotes because it's not the desired behavior):

    def render(context)
      return "HOW ARE YOU BECAUSE I AM A POTATO"
    end

Where the tag is called, that will output the line lifted from Portal 2 just fine. (Yes, I know return is unnecessary in ruby, to each his own.)

Why does the first one fail and the second one work? Is there a way to do what the first one seems to want to do?

_data/people.yml is defined similar to:

-   index: 1
    nick:    Guy
    display: That Guy
    name:
        first:  That
        middle: One
        last:   Guy
    account:
        github: greysondn

-   index: 2
    nick:    Galt
    display: Johnny
    name:
        first:  John
        middle: 
        last:   Galt
    account:
        github: 

Thank you in advance.

Upvotes: 0

Views: 264

Answers (1)

David Jacquel
David Jacquel

Reputation: 52809

I've spotted the problem :

if (person.index.to_s() == @text.to_s())
  return person.display
end

Here your code tries to use index method on person. person.['index'].to_s() is better. Same for person.display => person['display']

Once here you still have a problem with person.index.to_s() == @text.to_s(). As your liquid tag is {% Person_Index 2 %}, @text is "2 " with a space. So "2" != "2 ". We need to strip strings :

if (person['index'].to_s().strip == @text.to_s().strip)

is good but I prefer

if (person['index'].to_i() == @text.to_i())
    return person['display']
end

Upvotes: 1

Related Questions