curly icon indicating copy to clipboard operation
curly copied to clipboard

Add presented variables method getter

Open hauleth opened this issue 9 years ago • 11 comments

hauleth avatar Aug 12 '15 12:08 hauleth

While I understand the reasoning behind this, I don't fully support this because of the fact that this method can no longer be used internally by the presenter class reliably. If, for example, you were to want to list the users that were passed to the presenter (a non-trivial example), you would most likely use the users component - but this conflicts with the users method, since the behaviours of both are distinct. My example:

<!-- app/views/users/index.html.curly -->
<ul class="user list">
  {{users}}
</ul>
# app/presenters/users/index_presenter.rb

class Users::IndexPresenter < Curly::Presenter
  presents :users

  def users
    render partial: "user", collection: @users
  end
end

Even if the protected method users is overwritten by the new public method, it's still undesirable for the sole fact that they both perform completely disjoint behaviours. Also, considering the fact that the method is defined on the class, it means that attempting to call super would fail.

teliosdev avatar Aug 12 '15 16:08 teliosdev

I wanted it to allow nicer delegate …, to: … syntax as currently I need to write delegate …, to: :@…. There could be also syntax for delegation simple methods like

class BlahPresenter < Curly::Presenter
  present :user, delegate: %i(id name)
end

Or similar as often there is need to delegate only some fileds, it will be nice to have nice syntax for that case (other than delegate …, to: :@…).

hauleth avatar Aug 12 '15 16:08 hauleth

I like the presents delegate:... syntax; maybe exposes_fields :user, :id, :name, which creates a user method that takes one argument, so you can do {{user.name}} and {{user.id}}?

teliosdev avatar Aug 12 '15 17:08 teliosdev

Thanks! I'll take a look at this when I'm back from vacation.

On 12/08/2015, at 14.34, Łukasz Niemier [email protected] wrote:

You can view, comment on, or merge this pull request online at:

https://github.com/zendesk/curly/pull/152

Commit Summary

Add presented variables method getter File Changes

M lib/curly/presenter.rb (7) Patch Links:

https://github.com/zendesk/curly/pull/152.patch https://github.com/zendesk/curly/pull/152.diff — Reply to this email directly or view it on GitHub.

dasch avatar Aug 15 '15 08:08 dasch

I think having an explicit API on presenters is hugely valuable – having to call delegate in order to delegate calls seems perfectly reasonable.

dasch avatar Aug 25 '15 08:08 dasch

@dasch while that does seem reasonable, I really like being able to "namespace" specific fields as it were, so that doing something like this is feasible:

class SomePresenter < Curly::Presenter
  presents :user, delegate: [:id, :name]
end
<div class="user" data-id="{{user.id}}">
  <h2><a href="/users/{{user.id}}">{{user.name}}</a></h2>
</div>

If you note, it's no longer the id component, it's the user.id component (the former being what would be supplied if just delegate was used, the latter being the more preferred syntax). I really like this syntax so that it makes more sense as to whose id we're talking about here - if you're presenting both an article and a user, which id is being used can be confusing.

teliosdev avatar Aug 25 '15 22:08 teliosdev

@medcat in that case, simply use a context:

class SomePresenter < Curly::Presenter
  def user(&block)
    block.call(@user)
  end

  class UserPresenter < Curly::Presenter
    presents :user

    delegate :id, :name, to: :@user
  end
end
<div class="user" data-id="{{user:id}}">
  <!-- or use a {{@user}} ... {{/user}} block instead of namespacing the components. -->
  <h2><a href="/users/{{user:id}}">{{user:name}}</a></h2>
</div>

dasch avatar Aug 26 '15 08:08 dasch

@dasch would it be possible, then, to have a specific syntax dedicated to creating a context presenter?

teliosdev avatar Aug 26 '15 16:08 teliosdev

@medcat isn't class UserPresenter < Curly::Presenter; end concise enough?

dasch avatar Aug 27 '15 09:08 dasch

@dasch You'd have to do this:

class UserPresenter < Curly::Presenter
  presents :user
  delegate :id, :name, to: :@user
end

teliosdev avatar Aug 27 '15 18:08 teliosdev

@medcat I hacked something together: #156. I'm not sure I want to merge it – it seems a bit hacky to me. Maybe there's a more robust implementation.

If you need this functionality you could simply copy the base class into your codebase though. That way we could get some real world feedback on this. That goes for you too, @hauleth – it would be nice if you could check out #156.

dasch avatar Aug 28 '15 08:08 dasch