bullet-train-co/nice_partials

Can't remove `yield p = np` from a specific partial.

Closed this issue · 2 comments

You can see in bullet-train-co/bullet_train-themes-light#27 that I'm basically successful removing all the yield p = np calls in these theme library.

However, there is one that breaks: bullet-train-co/bullet_train-themes-light@771c315

My guess is that this happens because it's testing another nice partial, but referencing the parent partial context within the block of the other one. That's the only thing I can think of.

Steps to reproduce:

  1. Clone https://github.com/bullet-train-co/bullet_train
  2. Get it up and running (e.g. bin/setup, bin/dev, etc.)
  3. Run bin/develop and select the bullet_train-themes-light Ruby gem.
  4. Open local/bullet_train-themes-light.
  5. Edit app/views/themes/light/_page.html.erb
  6. Remove <% yield p = np %>
  7. Experience bug.

This is what the app looks like when this bug is triggered:

Screen Shot 2022-07-02 at 10 04 06 PM

I'm thinking of adding parent tracking to NicePartials::Partial and then expose a relay API to forward on certain keys.

<%= render 'account/shared/title' do |cp| %>
   <% cp.relay :title, :actions %>
<% end %>
# partial.relay :title, :description
def relay(*names)
  contents.merge! parent.contents.slice(*names)
end

Or we could do something from the outer side?

<%= partial.forward(:title, :actions).render 'account/shared/title' %>
<%= partial.(:title, :actions).render 'account/shared/title' %> # Define call on Partial and Ruby lets you call it like this.

@kaspth I think partial.relay :title, :actions isn't the solution because it assumes the slots are named the same, which they might not be in other cases.

Looking at the code in the partial that breaks, I added some debug statements like so:

<% puts p.content_for(:title) # => "The Testing Team’s Dashboard" %>

<%= render 'account/shared/title' do |cp| %>
  <% puts p.content_for(:title) # => nil %>
  <% cp.content_for :title, p.content_for(:title) %>
  <% cp.content_for :actions, p.content_for(:actions) %>
<% end %>

<%= render 'account/shared/notices' %>

<div class="space-y-8 py-4 xl:py-8 xl:px-8">
  <%= p.yield :body %>
</div>

The fact that p is getting clobbered here or replaced with something else in the context of this block feels like a bug to me. As a developer using Nice Partials, I would expect p to be the same inside and outside of the block. Is there a way around this?