Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Decorator with PartBuilder, supporting built-in part class resolution from a namespace #80

Merged
merged 4 commits into from Dec 2, 2018

Conversation

timriley
Copy link
Member

@timriley timriley commented Nov 26, 2018

Now, a view controller can be configured with a part_namespace and the default part builder will look up part classes to use from that namespace.

For example:

module MyParts
  class User < Dry::View::Part
  end
end

class MyVC < Dry::View::Controller
  configure do |config|
    config.template = "test"
    config.part_namespace = MyParts
  end

  expose :user
end

my_vc = MyVC.new
my_vc.(user: my_user).locals[:user] # => MyParts::User

This works for decorated attributes, too. If the part classes looked like this:

module MyParts
  class User < Dry::View::Part
    decorate :profile
  end

  class Profile < Dry::View::Part
  end
end

Then locals[:user].profile would be a MyParts::Profile.

Providing aliases for part names continues to work largely as before, e.g. expose :user, as: :admin_user will return the part as a MyParts::AdminUser (if it exists).

The API for providing a the part to use for array values has changed, however. Previously it took the form of as: {:collection_part_name => :item_part_name}. However, this made things feel pretty awkward if you didn't want to supply a custom name for the individual item (as: {:collection_part_name => nil} is pretty bad). Now you can provide one or both name aliases via an array syntax, e.g. as: [:collection_part_name] if you only want to provide an alias for the collection, or as: [:collection_part_name, :item_part_name] if you want to provide both. The array format here also works nicely as a mnemonic device, since it's relating to the wrapping of an array value.

Names are resolved using an inflector (by default a Dry::Inflector instance) which can be configured on view controllers via an inflector setting.

Custom part builders can still be provided to view controllers via a part_builder setting. When the view controller is initialized, the part builder will be prepared with the part namespace and inflector like so:

config.part_builder.new(namespace: config.part_namespace, inflector: config.inflector)

So any custom part builder will need to conform to this interface.

Replacing the decorator name with part_builder not only makes the purpose of the object clearer, but it also paves the way for a related scope_builder to be established as part of an upcoming feature.

Resolves #54, resolves #73

@timriley timriley changed the title [WIP] Part builder with built-in part class resolution Replace Decorator with PartBuilder, supporting built-in part class resolution from a namespace Nov 27, 2018
@timriley
Copy link
Member Author

@solnic @jodosha Here's one of the first big steps forward in dry-view functionality I've recently promised. This makes it possible for view parts to have custom classes resolved from a namespace automatically (similar to how rom's struct_namespace works).

I've described most of the behaviour in the PR description. Please have a look and let me know if there's anything you'd like to see adjusted or finessed in this feature (please keep in mind this is one in a series of many steps I'll be taking to improve the gem, there's a bunch of issues tagged 1.0 laying out what will come next).

@solnic
Copy link
Member

solnic commented Nov 29, 2018

This is great, it's a very useful feature, we know that already :)

@timriley timriley merged commit e385f27 into master Dec 2, 2018
@timriley timriley deleted the part-builder branch December 2, 2018 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants