<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="258240" data-post-id="258240">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chrismccord" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chrismccord/120/24233_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chrismccord
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Phoenix</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Note that verified routes work just fine with the localized routes, provided the user constructs them:</p>
<p>From the ex_cldr_routes default path structure:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">~p"/pages_#{@locale}/#{@page}"
</code></pre>
<p>But your library also generates the explicit locale helpers, so the user calls those when they are in areas specific to that locale (<code>page_de_path(...</code>. So that usecase simply becomes writing the actual verified path:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">~p"/pages_de/#{@page}"
</code></pre>
<p>And for convenience, your library currently providers a <code>LocalizedHelpers</code> module, so it could also provide the same kind of thing which wraps the canonical ~p:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">localized_path(@locale, ~p"/pages/#{@page"})
</code></pre>
<p>So I’m not seeing the issue with verified routes. In fact, I actually think it’s a big win to simply write the paths vs helpers when that’s all the user needs, (<code>~p"/pages_de/#{@page}"</code> vs <code>Routes.pages_de_path(@conn, @page)</code> and the <code>localized_path</code> macro would also still be quite nice.</p>
<p>Lastly, your library users can still use helpers (by not passing <code>helpers: false</code> to Phoenix.Router) and use all the existing functionality if they so choose <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="258240" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/dynamically-construct-path-by-action-and-helper-name/49412/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-258240" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="258240"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="258250" data-post-id="258250">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Chris, thanks for chiming in. I’ve no issues with verified routes (other than the small nit that it recfactoring routes also requires refactoring code). And if route helpers aren’t going away any time soon then there is less urgency for me to find an alternative implementation.</p>
<p>What I haven’t got conceptually clear in my head is that <code>~p</code> is a compile time verification and helpers are a runtime (sort of) verification. I need to inspect the implementation of <code>~p</code> but I’m assuming for now it returns an <code>iodata</code> type that still allows runtime interpolation into the path.</p>
<p>I’m interested to investigate your suggested <code>localized_path(@locale, ~p"/pages/#{@page"})</code> approach.  What would happen if I do:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">~p[/Gettext.dgettext("routes", "pages")/#{@page}]
</code></pre>
<p>That’s the rough equivalent of what my library does today, except it does the translation at compile time generating the required routes for all configured locales. And then at runtime there is no overhead doing translation - my localised helpers are only deciding which of the explicit locale helpers to call.</p>
<p>It would be very unusual for <code>ex_cldr_routes</code> user code to call <code>~p"/pages_de/#{@page}"</code> given that doing so requires explicitly determination of the current locale, deciding the canonical route, translating the route segments and interpolating. That’s basically a lot of boilerplate that the library is trying hard to simplify in the interests of a good developer experience.</p>
<p>My goals for localisation are (and have always been) that it should have immaterial impact on performance, be no more complex the non-localised code and be as compatible as possible at the API level with existing Elixir code.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="258250" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/dynamically-construct-path-by-action-and-helper-name/49412/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-258250" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="258250"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="258272" data-post-id="258272">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chrismccord" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chrismccord/120/24233_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chrismccord
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Phoenix</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="kip" data-post="13" data-topic="49412">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/48/1440_2.png" class="avatar"> kip:</div>
<blockquote>
<p>And if route helpers aren’t going away any time soon then there is less urgency for me to find an alternative implementation.</p>
</blockquote>
</aside>
<p>If they went away it wouldn’t be until Phoenix 2.0, of which there is currently no timeline or planned milestones. There would probably also be a separate lib that adds them back for legacy apps, but we’re not close to worry about that at the moment.</p>
<aside class="quote no-group" data-username="kip" data-post="13" data-topic="49412">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/48/1440_2.png" class="avatar"> kip:</div>
<blockquote>
<p>It would be very unusual for <code>ex_cldr_routes</code> user code to call <code>~p"/pages_de/#{@page}"</code> given that doing so requires explicitly determination of the current locale</p>
</blockquote>
</aside>
<p>Agree, I was just keying off where the ex_cldr docs start by showing the different route helpers.</p>
<aside class="quote no-group quote-modified" data-username="kip" data-post="13" data-topic="49412">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/48/1440_2.png" class="avatar"> kip:</div>
<blockquote>
<p>’m interested to investigate your suggested <code>localized_path(@locale, ~p"/pages/#{@page"})</code> approach. What would happen if I do:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">~p[/#{Gettext.dgettext("routes", "pages")}/#{@page}]
</code></pre>
</blockquote>
</aside>
<p>That works, but you want to verify the static segments at compile time, so I would instead build the interpolation ast so it produces:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">~p[/pages_#{locale}/#{@page}]
</code></pre>
<p>You could also inject a conditional branch that reads the runtime value and does two different ~p’s. Btw, ~p itself simply returns a string at runtime, but your macro would rewrite the <code>{:sigil_p, _, _}</code> ast.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="258272" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/dynamically-construct-path-by-action-and-helper-name/49412/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-258272" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="258272"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="258280" data-post-id="258280">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-Phoenix-Core-Team" data-username="chrismccord" data-post="14" data-topic="49412">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chrismccord/48/24233_2.png" class="avatar"> chrismccord:</div>
<blockquote>
<p>That works, but you want to verify the static segments at compile time, so I would instead build the interpolation ast so it produces:</p>
</blockquote>
</aside>
<p>That’s the tricky bit. With localised routes, assuming a configuration of locales <code>:es</code>, <code>:de</code> and <code>:en</code>, and the router has:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyApp.Router do
  use Phoenix.Router
  import Phoenix.LiveView.Router
  use MyApp.Cldr.Routes

  localize do
    get "/pages/:page", PageController, :show
  end
</code></pre>
<p>The there are actually three routes generated:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">get "/pages/:page", PageController, :show, private: %{locale: :en}
get "/paginas/:page", PageController, :show, private: %{locale: :es}
get "/seiten/:page", PageController, :show, private: %{locale: :de}
</code></pre>
<p>You’ll see that localised routes isn’t only (or even often) about interpolating the locale into the route - that would be an exception in many cases. Its more about translating the path segments (this relates a lot to SEO and overall customer engagement).</p>
<p>Using helpers, a single helper function can decide what path to generate based upon the locale at runtime.  And of course route recognition happens as normal, no special handling required.</p>
<p>With the <code>~p</code> sigil, I don’t know that its possible to have compile-time route verification given the the path to be returned cannot be known until runtime since it is based upon the locale.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="258280" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/dynamically-construct-path-by-action-and-helper-name/49412/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-258280" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="258280"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="258283" data-post-id="258283">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="LostKobrakai" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/LostKobrakai/120/3072_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  LostKobrakai
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Translations are available at compile time, so I feel like it should be possible to figure out the language dependent segments at compile time and then return something akin to this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># ~x"/pages/#{@page}"
case @locale do
  :en -&gt; ~p"/pages/#{@page}"
  :es -&gt; ~p"/paginas/#{@page}"
  :de -&gt; ~p"/seiten/#{@page}"
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="258283" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/dynamically-construct-path-by-action-and-helper-name/49412/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-258283" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="258283"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="258284" data-post-id="258284">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chrismccord" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chrismccord/120/24233_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chrismccord
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Phoenix</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Exactly! This is what I meant about branching</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="258284" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/dynamically-construct-path-by-action-and-helper-name/49412/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-258284" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="258284"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="258285" data-post-id="258285">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Ahh, the fog is lifting :-). Thank <a class="mention" href="/u/lostkobrakai" rel="nofollow">@LostKobrakai</a>, that makes sense. And is a whole lot cleaner than the helper approach (which in all transparency was a mind-bending pain to make work well for localisation).</p>
<p>Thanks to you and <a class="mention" href="/u/chrismccord" rel="nofollow">@chrismccord</a> for having the patience to get my brain back in the right place.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="258285" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/dynamically-construct-path-by-action-and-helper-name/49412/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-258285" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="258285"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="267603" data-post-id="267603">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="BartOtten" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/BartOtten/120/25440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  BartOtten
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>One of the reasons for generating those mind bending helpers from the original ones was to be future proof as I didn’t have to keep Router code in sync with upstream. Any helper added by the Phoenix team would also automatically be supported by the localization lib. It didn’t age well <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="267603" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/dynamically-construct-path-by-action-and-helper-name/49412/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-267603" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="267603"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>