bullet-train-co/nice_partials

Is there a way to warn when someone has redundantly called `yield p = np`?

Closed this issue · 3 comments

Going forward, because of #32, folks don't need to call <% yield p = np %>. If they do, it's not probably harmful except for performance... but is there some way of issuing a warning to them?

There might be a way, but I've also been working on an update script to just do it for people.

This removes <%= yield p = np %>\n+ and replaces p.content_for with partial.content_for, so it relies on #36 / #37.

files_to_inspect = []

Dir["app/views/**/*.html.erb"].each do |path|
  if contents = File.read(path).match(/(<%=? yield\(?.*? = np\)? %>\n+)/m)&.post_match
    files_to_inspect << path if contents.match?(/render.*?do \|/)

    contents.gsub! /\bp\.(?=yield|helpers|content_for|content_for\?)/, "partial."
    File.write path, contents
  end
end

if files_to_inspect.any?
  puts "These files had render calls with a block parameter and likely require some manual edits:"
  puts files_to_inspect
else
  puts "No files with renders calls with a block parameter found, you're likely all set"
end

We could put this in the CHANGELOG to help people upgrade.

Generated patch for `bullet_train-themes-light`

Note how this leaves cp.content_for unaltered in _page.html.erb.

It also spit out the two files people need to edit:

These files had render calls with a block parameter and likely require some manual edits:
app/views/themes/light/_page.html.erb
app/views/themes/light/actions/_box.html.erb
diff --git a/app/views/themes/light/_box.html.erb b/app/views/themes/light/_box.html.erb
index 2556e5d..ecc95e8 100644
--- a/app/views/themes/light/_box.html.erb
+++ b/app/views/themes/light/_box.html.erb
@@ -1,48 +1,46 @@
-<% yield p = np %>
-
 <% divider ||= nil %>
 <% no_background ||= false %>
 <% title_size ||= nil %>
 <% title_padding ||= nil %>
 <% border_top ||= false %>
-<% body = p.content_for(:body) || p.content_for(:raw_body) %>
+<% body = partial.content_for(:body) || partial.content_for(:raw_body) %>
 <% pagy ||= nil %>
 
 <div class="<%= "bg-white rounded-md shadow dark:bg-darkPrimary-700" unless no_background %> overflow-hidden <%= border_top ? "border-t dark:border-darkPrimary-500" : "" %>">
   <div class="py-6 px-8 <%= title_padding %> space-y-2 <%= 'border-b shadow-sm dark:border-darkPrimary-600' if divider %>">
-    <% if p.content_for? :title %>
+    <% if partial.content_for? :title %>
       <h2 class="text-xl font-semibold dark:text-white <%= title_size %>">
-        <%= p.content_for :title %>
+        <%= partial.content_for :title %>
       </h2>
     <% end %>
 
-    <% if p.content_for? :description %>
+    <% if partial.content_for? :description %>
       <p class="text-gray-400 font-light leading-normal">
-        <%= p.content_for :description %>
+        <%= partial.content_for :description %>
       </p>
     <% end %>
   </div>
 
   <div class="space-y-4">
-    <% if p.content_for? :table %>
+    <% if partial.content_for? :table %>
       <div class="box-table <%= divider ? 'mt-4' : '-mt-1' %> pb-0.5">
-        <%= p.content_for :table %>
+        <%= partial.content_for :table %>
       </div>
     <% end %>
 
     <% if body %>
-      <div class="<%= "pt-7 px-8 space-y-7 #{p.content_for?(:actions) ? 'pb-3' : 'pb-7'}" unless p.content_for?(:raw_body) %>">
+      <div class="<%= "pt-7 px-8 space-y-7 #{partial.content_for?(:actions) ? 'pb-3' : 'pb-7'}" unless partial.content_for?(:raw_body) %>">
         <div class="space-y-4 <%= '-mt-4' unless divider %>">
           <%= body %>
         </div>
       </div>
     <% end %>
 
-    <% if p.content_for? :actions || pagy %>
+    <% if partial.content_for? :actions || pagy %>
       <div class="pb-7 px-8 space-y-7">
         <div class="sm:flex">
           <div class="flex-1 space-x">
-            <%= p.content_for :actions %>
+            <%= partial.content_for :actions %>
           </div>
           <% if pagy && pagy.pages > 1 %>
             <div class="flex-0 mt-3 sm:mt-0">
@@ -54,15 +52,15 @@
     <% end %>
   </div>
 
-  <% if p.content_for? :footer %>
+  <% if partial.content_for? :footer %>
     <div class="py-4 px-8 bg-gray-50 border-t dark:bg-darkPrimary-900 dark:border-darkPrimary-600">
-      <%= p.content_for :footer %>
+      <%= partial.content_for :footer %>
     </div>
   <% end %>
 
-  <% if p.content_for? :raw_footer %>
+  <% if partial.content_for? :raw_footer %>
     <div class="bg-gray-50 dark:bg-darkPrimary-900">
-      <%= p.content_for :raw_footer %>
+      <%= partial.content_for :raw_footer %>
     </div>
   <% end %>
 </div>
diff --git a/app/views/themes/light/_cell.html.erb b/app/views/themes/light/_cell.html.erb
index 1ef20e5..576bb25 100644
--- a/app/views/themes/light/_cell.html.erb
+++ b/app/views/themes/light/_cell.html.erb
@@ -1,12 +1,10 @@
-<% yield p = np %>
-
 <% completion_percent ||= nil %>
 
 <div class="py-4 px-8 w-full space-y-3">
   <div class="flex space-x-4">
-    <% if p.content_for? :memberships %>
+    <% if partial.content_for? :memberships %>
       <div class="flex-0">
-        <%= p.content_for :memberships %>
+        <%= partial.content_for :memberships %>
       </div>
     <% end %>
 
@@ -14,13 +12,13 @@
       <div class="flex">
         <div class="flex-1 space-y-4 py-1">
           <div>
-            <%= p.content_for :title %>
+            <%= partial.content_for :title %>
           </div>
         </div>
 
-        <% if p.content_for? :actions %>
+        <% if partial.content_for? :actions %>
           <div class="flex-0">
-            <%= p.content_for :actions %>
+            <%= partial.content_for :actions %>
           </div>
         <% end %>
       </div>
@@ -31,9 +29,9 @@
         </div>
       <% end %>
 
-      <% if p.content_for? :status %>
+      <% if partial.content_for? :status %>
         <div class="<% "mt-2" if completion_percent %> uppercase text-xs text-gray-400">
-          <%= p.content_for :status %>
+          <%= partial.content_for :status %>
         </div>
       <% end %>
     </div>
diff --git a/app/views/themes/light/_page.html.erb b/app/views/themes/light/_page.html.erb
index e940a4b..57db3b9 100644
--- a/app/views/themes/light/_page.html.erb
+++ b/app/views/themes/light/_page.html.erb
@@ -1,12 +1,10 @@
-<% yield p = np %>
-
 <%= render 'account/shared/title' do |cp| %>
-  <% cp.content_for :title, p.content_for(:title) %>
-  <% cp.content_for :actions, p.content_for(:actions) %>
+  <% cp.content_for :title, partial.content_for(:title) %>
+  <% cp.content_for :actions, partial.content_for(:actions) %>
 <% end %>
 
 <%= render 'account/shared/notices' %>
 
 <div class="space-y-8 py-4 xl:py-8 xl:px-8">
-  <%= p.yield :body %>
+  <%= partial.yield :body %>
 </div>
diff --git a/app/views/themes/light/_title.html.erb b/app/views/themes/light/_title.html.erb
index 43655a0..5cb364c 100644
--- a/app/views/themes/light/_title.html.erb
+++ b/app/views/themes/light/_title.html.erb
@@ -1,14 +1,12 @@
-<% yield p = np %>
-
 <div class="flex flex-row items-center">
   <div class="flex-auto">
     <h1 class="font-semibold text-base dark:text-white">
-      <%= p.content_for(:title) %>
+      <%= partial.content_for(:title) %>
     </h1>
   </div>
   <div class="flex-auto text-right leading-none">
-    <% if p.content_for? :actions %>
-      <%= p.content_for :actions %>
+    <% if partial.content_for? :actions %>
+      <%= partial.content_for :actions %>
     <% end %>
   </div>
 </div>
diff --git a/app/views/themes/light/_well.html.erb b/app/views/themes/light/_well.html.erb
index 72b634b..fda3f97 100644
--- a/app/views/themes/light/_well.html.erb
+++ b/app/views/themes/light/_well.html.erb
@@ -1,25 +1,23 @@
-<% yield p = np %>
-
 <div class="border border-gray-300 dark:border-opacity-10 rounded-md py-4 px-5 bg-gray-50 dark:bg-opacity-10 space-y">
-  <% if p.content_for?(:title) || p.content_for?(:description) %>
+  <% if partial.content_for?(:title) || partial.content_for?(:description) %>
     <div class="space-y-2">
-      <% if p.content_for? :title %>
+      <% if partial.content_for? :title %>
         <h2 class="text-base font-semibold">
-          <%= p.content_for :title %>
+          <%= partial.content_for :title %>
         </h2>
       <% end %>
 
-      <% if p.content_for? :description %>
+      <% if partial.content_for? :description %>
         <p class="text-gray-400 font-light leading-normal">
-          <%= p.content_for :description %>
+          <%= partial.content_for :description %>
         </p>
       <% end %>
     </div>
   <% end %>
 
-  <% if p.content_for? :body %>
+  <% if partial.content_for? :body %>
     <div class="space-y">
-      <%= p.content_for :body %>
+      <%= partial.content_for :body %>
     </div>
   <% end %>
 </div>
diff --git a/app/views/themes/light/actions/_box.html.erb b/app/views/themes/light/actions/_box.html.erb
index a172802..ef494c5 100644
--- a/app/views/themes/light/actions/_box.html.erb
+++ b/app/views/themes/light/actions/_box.html.erb
@@ -1,6 +1,4 @@
-<% yield p = np %>
-
 <%= render 'account/shared/box', no_background: true, title_size: "text-2xs", title_padding: "pt-3 pb-3.5", border_top: true do |pp| %>
-  <% pp.content_for :title, p.yield(:title) %>
-  <% pp.content_for :table, p.yield(:table) %>
+  <% pp.content_for :title, partial.yield(:title) %>
+  <% pp.content_for :table, partial.yield(:table) %>
 <% end %>
diff --git a/app/views/themes/light/attributes/_base.html.erb b/app/views/themes/light/attributes/_base.html.erb
index b695be9..820923e 100644
--- a/app/views/themes/light/attributes/_base.html.erb
+++ b/app/views/themes/light/attributes/_base.html.erb
@@ -1,15 +1,13 @@
-<% yield p = np %>
-
 <% url ||= nil %>
 <% strategy ||= current_attributes_strategy || :none %>
 
 <% body = capture do %>
   <% if url.present? %>
     <% link_to url do %>
-      <%= p.content_for :body %>
+      <%= partial.content_for :body %>
     <% end %>
   <% else %>
-    <%= p.content_for :body %>
+    <%= partial.content_for :body %>
   <% end %>
 <% end %>
 
@@ -17,7 +15,7 @@
 <% when :label %>
   <div>
     <label class="block text-2xs font-semibold py-2 dark:text-white">
-      <%= p.content_for :heading %>
+      <%= partial.content_for :heading %>
     </label>
     <div class="dark:text-gray-400">
       <%= body %>
diff --git a/app/views/themes/light/breadcrumbs/_actions.html.erb b/app/views/themes/light/breadcrumbs/_actions.html.erb
index 8c40bc5..055b2c2 100644
--- a/app/views/themes/light/breadcrumbs/_actions.html.erb
+++ b/app/views/themes/light/breadcrumbs/_actions.html.erb
@@ -1,6 +1,4 @@
-<% yield p = np %>
-
-<% p.helpers do
+<% partial.helpers do
   def account_controller_name_with_namespace
     params[:controller].gsub(/^account\//, '')
   end
diff --git a/app/views/themes/light/commentary/_box.html.erb b/app/views/themes/light/commentary/_box.html.erb
index 744d0c2..c237a35 100644
--- a/app/views/themes/light/commentary/_box.html.erb
+++ b/app/views/themes/light/commentary/_box.html.erb
@@ -1,12 +1,10 @@
-<% yield p = np %>
-
 <div class="-m-0.5">
   <div class="border border-dashed rounded-lg border-yellow-500 bg-yellow-400 dark:bg-opacity-10 dark:border-yellow-200 dark:border-opacity-70 -m-3 p-3 xl:py-4 xl:px-4 xl:-mx-4">
-    <%= p.content_for :content %>
+    <%= partial.content_for :content %>
 
     <div class="py-3 px-3 space-y-2 pt-6">
       <p class="text-yellow-600 dark:text-yellow-200 font-light leading-normal">
-        <%= p.content_for :commentary %>
+        <%= partial.content_for :commentary %>
       </p>
     </div>
   </div>
diff --git a/app/views/themes/light/menu/_item.html.erb b/app/views/themes/light/menu/_item.html.erb
index 9b719e0..391e8e0 100644
--- a/app/views/themes/light/menu/_item.html.erb
+++ b/app/views/themes/light/menu/_item.html.erb
@@ -1,14 +1,12 @@
-<% yield p = np %>
-
 <% method ||= nil %>
 <% active ||= request.path == url %>
 
 <%= send (method ? :button_to : :link_to), url, class: "block group hover:text-white hover:no-underline hover-indent-child #{'bg-primary-900 dark:bg-black dark:bg-opacity-10' if active} text-white px-2 py-2 rounded-md dark:text-white", method: method do %>
   <div class="inline-block indent-child flex items-center">
     <!-- Heroicon name: home -->
-    <% if p.content_for? :icon %>
+    <% if partial.content_for? :icon %>
       <span class="mr-3 h-6 w-6 text-center text-primary-300 text-xl leading-6 dark:text-gray-400">
-        <%= p.content_for :icon %>
+        <%= partial.content_for :icon %>
       </span>
     <% end %>
     <%= label %>
diff --git a/app/views/themes/light/workflow/_box.html.erb b/app/views/themes/light/workflow/_box.html.erb
index 97cca72..555f1dc 100644
--- a/app/views/themes/light/workflow/_box.html.erb
+++ b/app/views/themes/light/workflow/_box.html.erb
@@ -1,5 +1,3 @@
-<% yield p = np %>
-
 <% width ||= "max-w-md" %>
 
 <div class="min-h-screen flex flex-col justify-center sm:py-12">
@@ -11,14 +9,14 @@
         </a>
 
         <h1 class="mt-6 text-center text-3xl font-semibold tracking-tight dark:text-white">
-          <%= p.yield :title %>
+          <%= partial.yield :title %>
         </h1>
 
         <%= render "shared/line" %>
       </div>
 
       <div class="electron-undraggable pt-5 space-y-5">
-        <%= p.content_for :body %>
+        <%= partial.content_for :body %>
       </div>
     </div>
   </div>

In #45 I'm making it such that we'll avoid auto-yielding if there's a manual yield in the partial. So that should make upgrades easier, and then people could use the script above.

Solved in #45 where we only auto-yield if there's no manual yield, and the update script is in the CHANGELOG for people to help themselves. I think that's enough coverage to skip needing a warning.