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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <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 class="user-title">
									<span>Creator of Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="KP123" data-post="12" data-topic="69966" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/k/278dde/48.png" class="avatar"> KP123:</div>
<blockquote>
<p>Would a syntax like <a href="https://hexdocs.pm/temple/Temple.html" rel="noopener nofollow ugc">Temple</a> be possible for what you have in mind?</p>
</blockquote>
</aside>
<p>Yes, something similar to Temple would technically be possible for Hologram in the future. The core of what Hologram’s <code>template/0</code> does is generate an anonymous function that:</p>
<ol>
<li>Receives variables (state and props)</li>
<li>Returns a nested Elixir data structure representing the DOM</li>
<li>Can be transpiled to JavaScript for virtual DOM rendering</li>
</ol>
<p>So theoretically, different template syntaxes could be implemented as long as they produce this same kind of anonymous function with the proper nested data structure.</p>
<p>However, implementing this right now would be quite challenging because the template system is tightly coupled with the compiler. Decoupling these systems would require significant refactoring that’s not on my immediate roadmap.</p>
<p>Also, this has the same challenges I mentioned in my <a href="https://forum.elixirforum.com/t/hologram-roadmap-unveiled-the-path-to-elixirconf-2025-and-beyond/69966/8" rel="nofollow">earlier reply</a> about supporting HEEX syntax.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="359262" 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/hologram-roadmap-unveiled-the-path-to-elixirconf-2025-and-beyond/69966/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-359262" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359262"
                     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 #22"></div>
  </section>
</div>
    <div class="postbit" id="359263" data-post-id="359263">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <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 class="user-title">
									<span>Creator of Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="KP123" data-post="21" data-topic="69966" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/k/278dde/48.png" class="avatar"> KP123:</div>
<blockquote>
<p>Another thought about syntax but a different perspective. You might not want to directly tie UI building to HTML at all. I’m unsure as to the scope of your project but if your goal is apps written in Elixir running anywhere you may want to take a leaf out of this weeks Javascript framework, <a href="https://lynxjs.org/guide/ui/elements-components.html" rel="noopener nofollow ugc">Lynx</a>, by ByteDance. Have a simplified set of tags that can be remapped to platform specific UI at runtime. It’s similar to how LiveView Native’s views works. If you come up with a good solution for marking accessibility you should be able to figure out how to map a generic <code>&lt;text&gt;</code> to <code>&lt;h1&gt;, &lt;p&gt;, etc</code> (perhaps <a href="https://developer.apple.com/documentation/swiftui/view-accessibility" rel="noopener nofollow ugc">Apple’s accessibility modifiers</a> can be of inspiration)</p>
</blockquote>
</aside>
<p>Thanks for the suggestions <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"> Yeah, I heard about Lynx a couple days ago on Theo’s channel, seems like a cool solution!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="359263" 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/hologram-roadmap-unveiled-the-path-to-elixirconf-2025-and-beyond/69966/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-359263" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359263"
                     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 #23"></div>
  </section>
</div>
    <div class="postbit" id="359266" data-post-id="359266">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="bartblast" data-post="22" data-topic="69966">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/48/17647_2.png" class="avatar"> bartblast:</div>
<blockquote>
<p>I meant that it would be confusing if we supported multiple syntaxes (e.g., Holo and HEEx), especially in such early stages ot the project. This could potentially confuse users.</p>
</blockquote>
</aside>
<p>Oh, that I understand - people may think the HEEx syntax is supported - makes sense.</p>
<aside class="quote no-group" data-username="bartblast" data-post="22" data-topic="69966">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/48/17647_2.png" class="avatar"> bartblast:</div>
<blockquote>
<p>The action may be handled by some parent component, and as a result, props to some of its nested children may change.</p>
</blockquote>
</aside>
<p>Oh sorry, where is a problem here? I was thinking that if you change parent state (which you use to render children) then children would be recreated (with new state), right? For example every time you change <code>options</code> in parent and use them in <code>for</code> syntax then the generated child components using values from said <code>options</code> should be initialised again with new state (options value).</p>
<p>Looks like you explain an <code>update</code> of child component and call <code>template</code> function without <code>init</code> (on update). If so I don’t see why redraw happen if you have outdated state? I would expect that such child is recreated instead. The biggest issue then would be a terminate callback implementation to be able to do some cleanup in some rare cases. Did I miss something? Would that be inefficient?</p>
<aside class="quote no-group" data-username="bartblast" data-post="22" data-topic="69966">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/48/17647_2.png" class="avatar"> bartblast:</div>
<blockquote>
<p>Unfortunately, that’s a much more complex situation.</p>
</blockquote>
</aside>
<p>I see, thanks! <img src="https://forum.elixirforum.com/images/emoji/apple/+1.png?v=15" title=":+1:" class="emoji" alt=":+1:" loading="lazy" width="20" height="20"></p>
<p>Sorry for all that questions, but you have introduced some “magic” here and there … For example looks like I wrongly assumed that the result of <code>template</code> function is transpiled instead of the whole function by compiler (right)? When I run the skeleton project and enter the page inspector with empty HTML template (just runtime is added) I don’t even see any <code>script</code> tag in the <code>DOM</code>, but there are 2 in the network tab. Everything is very hidden and therefore hard to follow.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="359266" 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/hologram-roadmap-unveiled-the-path-to-elixirconf-2025-and-beyond/69966/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-359266" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359266"
                     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 #24"></div>
  </section>
</div>
    <div class="postbit" id="359379" data-post-id="359379">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <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 class="user-title">
									<span>Creator of Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Eiji" data-post="25" data-topic="69966">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/eiji/48/36743_2.png" class="avatar"> Eiji:</div>
<blockquote>
<p>Oh sorry, where is a problem here? I was thinking that if you change parent state (which you use to render children) then children would be recreated (with new state), right? For example every time you change <code>options</code> in parent and use them in <code>for</code> syntax then the generated child components using values from said <code>options</code> should be initialised again with new state (options value).</p>
<p>Looks like you explain an <code>update</code> of child component and call <code>template</code> function without <code>init</code> (on update). If so I don’t see why redraw happen if you have outdated state? I would expect that such child is recreated instead. The biggest issue then would be a terminate callback implementation to be able to do some cleanup in some rare cases. Did I miss something? Would that be inefficient?</p>
</blockquote>
</aside>
<p>When props change, the component is not reinitialized - this is similar to how both LiveView and modern JS frameworks work. Components persist across renders, and only their props are updated. You’re right that the goal is similar to LiveView’s <code>update</code> function, though I prefer a more declarative approach where components can listen for specific prop changes. One key difference is that LiveView’s update doesn’t have access to previous prop values, only the new ones.</p>
<aside class="quote no-group" data-username="Eiji" data-post="25" data-topic="69966">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/eiji/48/36743_2.png" class="avatar"> Eiji:</div>
<blockquote>
<p>Sorry for all that questions, but you have introduced some “magic” here and there … For example looks like I wrongly assumed that the result of <code>template</code> function is transpiled instead of the whole function by compiler (right)? When I run the skeleton project and enter the page inspector with empty HTML template (just runtime is added) I don’t even see any <code>script</code> tag in the <code>DOM</code>, but there are 2 in the network tab. Everything is very hidden and therefore hard to follow.</p>
</blockquote>
</aside>
<p>No worries at all, I’m here to explain and answer your questions!</p>
<p>I appreciate your inquisitiveness. It’s important to note that I don’t expect users to understand these implementation details. In fact, the goal of Hologram is to let developers focus on shipping features without worrying about the underlying boilerplate they’d otherwise have to write.</p>
<p>If you’re interested in understanding what’s happening with the scripts, you can check out the UI.Runtime module here:</p>
<p><a href="https://github.com/bartblast/hologram/blob/master/lib/hologram/ui/runtime.ex" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/bartblast/hologram/blob/master/lib/hologram/ui/runtime.ex</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="359379" data-batch-url="/posts/batch_likers">
                        4
                      </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/hologram-roadmap-unveiled-the-path-to-elixirconf-2025-and-beyond/69966/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-359379" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359379"
                     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>