zendesk/curly

Providing a Shortcut for Components

teliosdev opened this issue · 4 comments

I find myself doing things like this often:

<article>
  <header>
     <h2>{{ article.name }}</h2>
     <small>{{ article.posted }}</small>
  </header>
  <section>
    {{ article.body }}
  </section>
  <footer>
     <a href="{{ author.link }}">{{ author.name }}</a>
  </footer>
</article>

I think it looks excellent on the template. But when you go over to the presenter, it looks like this:

class Articles::ArticlePresenter < Curly::Presenter
  presents :article

  def article(item)
    case item
    when "name"
      @article.name
    when "posted"
       time_tag @article.created_at
    when "body"
       @article.formatted_body
    else
      # error.
    end
  end

  def author(item)
    case item
    when "link"
      link_to @article.author
    when "name"
       @article.author.name
    end
  end
end

This is not so excellent. I was wondering if you would be welcome to a class method to make it easier to create such methods. It would look something like this:

provides :article, 
  name: -> { @article.name },
  posted: -> { time_tag @article.created_at },
  body: -> { @article.formatted_body }

I'd be happy to write the code for it, but I'm just wondering what you think before I go ahead with it.

dasch commented

Wouldn't this be a better fit for the context shorthand syntax?

dasch commented

Alternatively, if you want to have a single presenter (e.g. if you're using a single partial template) just use underscore instead of dot?

def article_name ... end
def article_posted ... end

I'm not sure I understand the dot syntax in the first place - why is it that the syntax for passing a single argument to the method is a dot ({{ article.name }})? Why specifically that syntax?

dasch commented

There's a historical reason for it – it provides a level of compatibility with a subset of Liquid that was used at Zendesk. Specifically, we had the notion of "dynamic content" which were user managed translation strings. You'd reference them by their key, e.g. {{dc.frontpage.welcome}}. Hence, the argument is dynamic and resolved at runtime. The : operator is strongly typed and thus better suited for what you're trying to do. It also automatically works with the presenter system.