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

Add NicePartials#t to aid I18n. #56

Merged
merged 3 commits into from
Sep 5, 2022
Merged

Conversation

kaspth
Copy link
Contributor

@kaspth kaspth commented Aug 29, 2022

When using NicePartials with I18n you end up with lots of calls that look like:

<%= partial.content_for :title,       t(".title") %>
<%= partial.content_for :description, t(".header") %>
<%= partial.content_for :byline,      t("custom.key") %>

With NicePartials t method you can write the above as:

<%= partial.t :title, description: :header, byline: "custom.key" %>

Clarifying what keys get converted to what content sections on the partial rather than the boilerplate heavy and repetitive content_for(…), t(".…").

When using NicePartials with I18n you end up with lots of calls that look like:

```erb
<% partialtitle       t(".title") %>
<% partialdescription t(".header") %>
<% partialbyline      t("custom.key") %>
```

With NicePartials' `t` method, you can write the above as:

```erb
<% partial.t :title, description: :header, byline: "custom.key" %>
```

Clarifying what keys get converted to what content sections on the partial rather than the boilerplate heavy and repetitive `partial.…, t(".…")`.
Noting the difference between Rails' `content_for` and our section
abstraction, but in practice it'll be the same thing since `<%= %>` calls to_s.
@kaspth kaspth changed the base branch from main to expose-sections September 5, 2022 07:28
@andrewculver
Copy link
Contributor

@kaspth This is awesome!

@andrewculver andrewculver merged commit 8197fae into expose-sections Sep 5, 2022
@kaspth kaspth deleted the features/t-helper branch September 5, 2022 16:14
kaspth added a commit that referenced this pull request Sep 5, 2022
* Expose Content object to separate content_for compatibility

If we're starting to layer on more complex behavior to Section and
exposing them, it's nice to have an alternate implementation that's
easier to maintain for our content_for inter-op with Rails.

* Defer creating contents Hash now that Section will be different storage

* Make Section an extension of Content to simplify it for now

* Reintroduce Sections as a new API (strip deferred contents for now)

* Trial out reusing present? to indicate content

* Reintroduce deferred content blocks

* Rename internal call to process and simplify signature

* Write arguments by type and not position

* Expose sections through methods on the partial

* Trial out write shorthand API

* become the andthesis of syntax

* Skip nils first so we spare the respond_to checks

* These didn't turn out that different, let's slim 'em

* Slightly nicer name

* Hoist up the fact that we have to return nil for erroneous <%=  %> calls

* Expose store so write isn't public

* Now write can be really simple again

* We don't have to support an endless variation of signatures

* Explore `render` shorthand to auto-concat

It's possible we may want a general method_missing hook that delegates
to @view_context and concatenates the result and returns self
for chaining. Would allow for something like this too:

```ruby
<% partial.title.link_to(@document.name, @document) %>
```

* Shorten concat since << returns the string and handles the truthy part

* Inline store and reuse write as the API

* Allow a shorthand with just the block

* Add a general concat proxy

* Start adding an append abstraction to handle ViewComponent etc.

* Add abstraction to let us append Components that respond to render_in

* Test what happens if we append a Section from another partial

* Test appending via proxy

* Add tag proxy that builds on the stored content and passed options

* Move attr_reader above initialize since that's more conventional

* Add a config point for AttributesAndTokenLists integration

* Extend tag proxy to append for the invocation only

This lets you generate different elements with overrides without appending
to the content/options for the next invocation.

Additionally, `tag#method_missing` responds to everything so we'll never
reach super.

* Use our fancy lil t extension

* Document proxying supports

* Use append since that's the internal API now over concat

* Remove nil returns to indicate writing

Various explicit nil returns were inserted to prevent things like

<%= partial.title.t ".title" %> # <% %> should have been used here.

But the more extensions we add the more we have to be careful of it,
and it prevents other potentially interesting directions like chaining.

* Add `write?` similar to `Set#add?`

…and then we can expose `write`, with some potential for chaining.

* Simplify integration hook and just expect `merge!`/`merge` to work

* Pipe options.to_s through tag.attributes automatically

* Document all the goodies ✨

* Note presence utility

* Make attributes_and_token_lists integration automatic

* Test with attributes_and_token_lists in the Gemfile

* Make testing with attributes_and_token_lists a comment/uncomment deal

* Test with ViewComponent's render_in integration

* Add nice bin/test from Rails plugins and use on CI

Removes need for the old test task in the Rakefile.

* Reuse our Test class so we don't have to stub the view context

* Remove non-standard capture expectation exposed in d6f9d18

When we fixed the view context stubbing, `capture` didn't just `yield`
anymore but also processed the returned value as a string
https://github.com/rails/rails/blob/06e9fbd954ab113108a7982357553fdef285bff1/actionview/lib/action_view/helpers/capture_helper.rb#L47

So our expectation that `partial.body { NameComponent.new(:plain) }` works,
won't work in practice.

But `partial.body { render NameComponent.new(:plain) }` is what's needed.

* Flex an extra assertion just because it's cool that this works 😎

* content_for returns a String, have users use our section abstraction if they want an object

* Remove attributes_and_token_lists integration

The author is unsure about the future of the lib, so let's chop the
extra code we for that relatively large dependency.

* The block is just passed directly now

* Fix content_for returned non-nil when writing

* Add `NicePartials#t` to aid I18n. (#56)
@kaspth kaspth mentioned this pull request Sep 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants