zendesk/curly

Custom policies for missing components

yurifrl opened this issue · 4 comments

Curly could have a option to not throw a error, a idea is to behave like i18n, i did a work around this:

# Curly Component
module Curly
  ComponentCompiler.class_eval do
    def initialize(presenter_class, component, type: nil)
      unless presenter_class.component_available?(component.name)
        component = Curly::Parser::Component.new('custom_error', nil, {'tag' => 'custom_error'})
      end
      @presenter_class, @component, @type = presenter_class, component, type
    end
  end
end
# Curly Presenter
def custom_error(tag: nil)
    "####{tag}###"
end

I don't think it should be called custom_error; I think it should be something like tag_missing, in style of method_missing.

So there'd be a magic method on Curly::Presenter that would handle missing components?

# curly/presenter.rb
def component_missing(name, identifier, attributes = {})
  # Default implementation is to raise an exception:
  raise ...

  # If you return a string it'll be inserted.
end

Individual presenter classes can then enforce their own policy.

I'm still not 100% sure on this. How about Curly.valid? – should it return false even if there's a missing component that is handled by the presenter?

If you equate components with methods, then ideally, it should return true; if you redefine method_missing it's good practice to implement respond_to_missing? which causes respond_to? to return true for methods that don't exist.

Evem if you don't equate the two, I would say it should return true, because the question is if it's a valid tag, which is independent of it being defined.

There's already Curly::Presenter.component_available? that can be used to signal to Curly that a component is available to use. The only problem is that Curly already uses method_missing to forward messages to the underlying view context, so we'd need to make this compatible with that use case.