<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="285425" data-post-id="285425">
  <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>I think the concept missing is some form of tags, which at least allow for unique identification (e.g. link a vs link b). HTML on the message could be that, but usually that’s to low level for what you want translators to deal with – at least without also postprocessing the translated message. HTML also often includes things, which are supposed to be dynamic and are therefore not great for being put on a message string.</p>
<p>From a library standpoint it would be great if the returned value would support more than a translated string, but also a list or map of sorts, so translations can be interspersed with markup. E.g. with heex you want as much markup to be statically known as possible, so diffs can be optimized, while only the pieces of text in between should be dynamic.</p>
<p>I also think there’s might be opportunities to integrate gettext on an even lower level with the heex engine.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="285425" 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/how-to-create-an-i18n-able-link/55030/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-285425" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="285425"
                     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="285431" data-post-id="285431">
  <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>Could you given an example of what that might look like from a developer point of view?</p>
<p>Gettext messages are quite simple so I’m not sure it’s easy to get more low level.</p>
<p>Unicode message format, which has its own flaws being addressed by the MFWG of Unicode and which has nearly completed a new standard, is at least a formal grammar so there is room to work at the AST level if that helps this kind of situation.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="285431" 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/how-to-create-an-i18n-able-link/55030/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-285431" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="285431"
                     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="285437" data-post-id="285437">
  <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>Let me try that with some xml like format.</p>
<p><code>"There are &lt;link_a&gt;%{n} new&lt;/link_a&gt; topics remaining."</code></p>
<p>At best the API would return something like <code>["There are ", {:link_a, [], "12 new"}, " topics remaining"]</code>, so I as a developer can then iterate the pieces like e.g.:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Enum.map_join(translation, "", fn 
  {:link_a, _, inner} -&gt; link(inner, href: "…")
  text -&gt; text
)
</code></pre>
<p>Or there could be some integration with heex, which is able to build up heex at compile time, which properly marks only dynamic pieces as dynamic, but any html, which might be static between all translations – in this example the link markup – is correctly detected as static for the template.</p>
<p>Essentially this is building an intermediate markup language to mediate between the developer concerns and translator concerns.</p>
<p>As a developer I care for:</p>
<ul>
<li>Finely split content requiring translation from content managed by the code.
<ul>
<li>things like urls or classes don’t belong in translated content</li>
</ul>
</li>
<li>Being able to incorporate translated content back into the places where they’re needed.</li>
<li>APIs to go beyond string concatination. HTML in dynamic strings means something like heex will miss it at compile time.</li>
</ul>
<p>As a translator I don’t want to deal with implementation details. I don’t care where a link goes, I just need to make sure the correct text will be linked. I also want some help in making sure my translations don’t violate the tags used when parsing, like <code>&lt;/link_a&gt;%{n} new&lt;link_a&gt;</code> would be detected as incorrect. I also think any markup language used for something like that should be as simple as it can be.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="285437" 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/how-to-create-an-i18n-able-link/55030/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-285437" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="285437"
                     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="285453" data-post-id="285453">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’d go with the %{connectez_vous} too. As long as that key is available, the translators will be able to put it all together.</p>
<p>The second option looks ugly but only because of the gettext syntax, so it might not be that bad. I do use something like this with react-i18next, but as the Trans component has an idea about xml it looks better:</p>
<pre><code>    &lt;Trans i18nKey="aze:agree_terms"
      components={{
        a: &lt;Button theme={xxx} link onClick={yyy} /&gt;
      }}
    /&gt;

"agree_terms": "I agree to &lt;a&gt;Terms &amp; Conditions&lt;/a&gt;",
</code></pre>
<p>Note: I called it “a” because it’s a link but it can be anything, and the lib will match between that “a” component and “&lt;a&gt;”,“&lt;/a&gt;”,“&lt;a/&gt;” tags in the string.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="285453" 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/how-to-create-an-i18n-able-link/55030/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-285453" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="285453"
                     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="308620" data-post-id="308620">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="saveman71" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/saveman71/120/30174_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  saveman71
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Conclusion of our implementation choice:</p>
<p>We’ll go with the “simple” approach that describes open/close tags in the translation, an implementation is here: <a href="https://gist.github.com/angelikatyborska/cebc3de03c08307edebf6054ed09ff5f" class="inline-onebox" rel="noopener nofollow ugc">A custom `gettext_with_link` macro for easily putting inline links into gettext strings · GitHub</a> (scroll down for our version, all credits go to the original author).</p>
<p>For now, we’ll sanitize the result at runtime but ideally we’d like to sanitize our PO files at compile time, I’ve opened an issue in that sense on the gettext repo: <a href="https://github.com/elixir-gettext/gettext/issues/380" class="inline-onebox" rel="noopener nofollow ugc">Allow to transform messages at compile time · Issue #380 · elixir-gettext/gettext · GitHub</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="308620" 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/how-to-create-an-i18n-able-link/55030/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-308620" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="308620"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-solved cat-solved" title="Marked as solution"></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>