Render and Children

GoHT composes templates with @render and @children.

  • @render calls another template and passes any required parameters.
  • Nested content under @render is passed to the rendered template.
  • @children renders nested content that was passed by the caller.

These directives work in Haml, Slim, and EGO templates. EGO uses command tags such as <%@render ... %> and <%@children %>.

@render

Use @render when one template should call another template.

@haml Page(title string) {
	!!!
	%html
		%head
			%title= title
		%body
			%main
				=@children
}

@haml HomePage() {
	=@render Page("Home")
		%p Welcome home.
}

The same pattern in Slim:

@slim HomePageSlim() {
	= @render Page("Home")
		p Welcome home.
}

And in EGO:

@ego HomePageEgo() {
	<%@render Page("Home") { %>
		<p>Welcome home.</p>
	<% } %>
}

The parameters passed to @render are the parameters of the generated Go template function. If Page is generated as func Page(title string) *PageTemplate, then @render Page("Home") calls that generated function and renders the returned template.

Nested render content and @children

Nested content under @render remains in the calling template’s scope. The rendered template chooses where that content appears by using @children.

@haml ArticleLayout(title string) {
	%article
		%h1= title
		.content
			=@children
}

@haml ArticlePage(author string) {
	- summary := "Nested content can use local variables."
	=@render ArticleLayout("Composition")
		%p.byline Written by #{author}
		%p= summary
}

Rendered output from ArticlePage("Sam") is shaped like:

<article>
  <h1>Composition</h1>
  <div class="content">
    <p class="byline">Written by Sam</p>
    <p>Nested content can use local variables.</p>
  </div>
</article>

Slim uses the same = @render and = @children directives:

@slim ArticleLayoutSlim(title string) {
	article
		h1= title
		.content
			= @children
}

EGO uses command tags:

@ego ArticleLayoutEgo(title string) {
	<article>
		<h1><%= title %></h1>
		<div class="content">
			<%@children %>
		</div>
	</article>
}

Nested content with WithChildren

children is the built-in slot that @children renders. Fill it from Go with WithChildren(...) instead of nesting content under @render when you’re composing by hand:

panel := Panel().WithChildren(Notice("Saved."))

See Slots for named slots, which give a layout several independent content regions instead of a single children region.