Golang: custom template function "capture" - function

I want to write template function like Smarty's capture.
How can I capture html inside
{{capture}}
...
{{/capture}}
How to do this?

{{define "T1"}}ONE{{end}}
{{define "T2"}}TWO{{end}}
{{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
{{template "T3"}}
ONE TWO

You would do it in the application: Use a template for the HTML snippet you want to capture, render it, save it to a string and use it in subsequent template rendering.

Related

Content Projection with Go HTML Templates [duplicate]

How do I get nested templates like Jinja has in the python runtime. TBC what I mean is how do I have a bunch of templates inherit from a base templates, just filing in blocks of the base templates, like Jinja/django-templates does. Is it possible using just html/template in the standard library.
If that is not a possibility, what are my alternatives. Mustache seems to be an option but would I then be missing out on those nice subtle features of html/template like the context sensitive escaping etc.? What other alternatives are ther?
(Environment: Google App Engin, Go runtime v1, Dev - Mac OSx lion)
Thanks for reading.
Yes it is possible. A html.Template is actually a set of template files. If you execute a defined block in this set, it has access to all the other blocks defined in this set.
If you create a map of such template sets on your own, you have basically the same flexibility that Jinja / Django offers. The only difference is that the html/template package has no direct access to the file system, so you have to parse and compose the templates on your own.
Consider the following example with two different pages ("index.html" and "other.html") that both inherit from "base.html":
// Content of base.html:
{{define "base"}}<html>
<head>{{template "head" .}}</head>
<body>{{template "body" .}}</body>
</html>{{end}}
// Content of index.html:
{{define "head"}}<title>index</title>{{end}}
{{define "body"}}index{{end}}
// Content of other.html:
{{define "head"}}<title>other</title>{{end}}
{{define "body"}}other{{end}}
And the following map of template sets:
tmpl := make(map[string]*template.Template)
tmpl["index.html"] = template.Must(template.ParseFiles("index.html", "base.html"))
tmpl["other.html"] = template.Must(template.ParseFiles("other.html", "base.html"))
You can now render your "index.html" page by calling
tmpl["index.html"].Execute("base", data)
and you can render your "other.html" page by calling
tmpl["other.html"].Execute("base", data)
With some tricks (e.g. a consistent naming convention of your template files), it's even possible to generate the tmpl map automatically.
note, when you execute your base template, you must pass values down to the child templates, here I simply pass ".", so that everything is passed down.
template one displays {{.}}
{{define "base"}}
<html>
<div class="container">
{{.}}
{{template "content" .}}
</div>
</body>
</html>
{{end}}
template two displays {{.domains}} that's passed into the parent.
{{define "content"}}
{{.domains}}
{{end}}
Note, if we used {{template "content"}} instead of {{template "content" .}}, .domains wouldn't be accessible from the content template.
DomainsData := make(map[string]interface{})
DomainsData["domains"] = domains.Domains
if err := groupsTemplate.ExecuteTemplate(w, "base", DomainsData); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
having worked with other template packages, now a days I mostly work with standard html/template package, I guess I was naive to not appreciate the simplicity it provides and other goodies. I use a very similar approach to accepted answer with following changes
you don't need to wrap your layouts with additional base template, a template block is created for every parsed file so in this case it is redundant, I also like to use the block action provided in new version of go, which allows you to have default block content in case you don't provide one in child templates
// base.html
<head>{{block "head" .}} Default Title {{end}}</head>
<body>{{block "body" .}} default body {{end}}</body>
and you page templates can be the same as
// Content of index.html:
{{define "head"}}<title>index</title>{{end}}
{{define "body"}}index{{end}}
// Content of other.html:
{{define "head"}}<title>other</title>{{end}}
{{define "body"}}other{{end}}
now to execute the templates you need to call it like so
tmpl["index.html"].ExecuteTemplate(os.Stdout, "base.html", data)
Use Pongo, which is a super-set of Go Templates that supports the {{extends}} and {{block}} tags for template inheritance, just like Django.
I've been coming back to this answer for days, finally bit the bullet and wrote a small abstraction layer / pre processor for this. It basically:
Adds the 'extends' keyword to templates.
Allows overriding 'define' calls (thus default values for greggory are possible)
Allows non defined 'template' calls, they just give an empty string
Sets the default value of . in 'template' calls to . of the parent
https://github.com/daemonl/go_sweetpl

Passing html as a template variable django

I am passing some html to my template like this passDict["problemText"] = <p> Some html</p>
return render(response,'main/base.html',passDict). And then displaying {{problemText}} in my html file.I get <p> Some html</p> as my text and not Some html in a paragraph like i want.
It needs to be marked as safe.
Use the safe filter.
{{ problemText|safe }}
Or use the mark_safe() method.
from django.utils.safestring import mark_safe
problemText = mark_safe("<p>Some html</p>")
Read the documentation on the safe filter and mark_safe().

Go template/html pass variable to nested template [duplicate]

We can define template name via {{define "home"}}, and then load it in other (parent) template via {{template "home"}}.
How I can load template via variable value {{template .TemplateName}}. Or it's impossible?
Unfortunately you can't.
The syntax of the {{template}} action:
{{template "name"}}
The template with the specified name is executed with nil data.
{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.
The name of the template to be included is a constant string, it is not a pipeline which could vary during execution based on parameters.
If the allowed syntax would be:
{{template pipeline}}
then you could use something like {{template .TemplName}} but since the syntax only allows a constant string, you can't.
Reasoning from Rob why dynamic template invocation is not allowed (source):
We want the template language to be statically analyzable so the context of a template's invocation is clear, checkable, and lockdownable. If an invocation point is totally dynamic, this can't be done. Similarly, if a template can belong to multiple sets, its context can differ between sets in a way that would require all sets to be analyzed simultaneously. Since both these constraints are easy to work around if you want to, at the cost of losing those static checks in a higher-level package, it seemed wise to control the situation in the base template implementation. A higher-level package, such as a hypothetical HTML-only wrapper, can guarantee no workarounds more easily if the constraints are clear.
Alternative #1: Execute Includable Template First
What you can do is execute the template you would want to include first, and insert the result where you want to include it. You can use special types not to escape the result of the inner template when inserting, for example html.HTML in case of HTML templates.
See this example:
func main() {
t := template.Must(template.New("t").Parse(t))
template.Must(t.New("t1").Parse(t1))
params := struct {
Name string
Value interface{}
}{"t1", nil}
b := bytes.Buffer{}
t.ExecuteTemplate(&b, params.Name, nil)
params.Value = template.HTML(b.String())
t.Execute(os.Stdout, params)
}
const t = `<html><body>
Now I will include template with name: {{.Name}}
{{.Value}}
</body>/html>`
const t1 = `I'm template <b>t1</b>.`
Output:
<html><body>
Now I will include template with name: t1
I'm template <b>t1</b>.
</body>/html>
Try it on the Go Playground.
The result of template t1 was inserted unescaped. If you leave out template.HTML:
params.Value = b.String()
t1 would be inserted escaped, like this:
<html><body>
Now I will include template with name: t1
I'm template <b>t1</b>.
</body>/html>
Alternative #2: Restructure Templates
You can restructure your templates not to be in situations where you would want to include a template with varying names.
Example: you might want to create pages where you have a page template something like this:
<html><body>
Title, headers etc.
{{template .Page}}
Footers
</body></html>
You can restructure it to be something like this:
header template:
<html><body>
Title, headers, etc.
footer template:
Footers
</body></html
And your page templates would include header and footer like this:
{{template "header" .}}
Page content comes here.
{{template "footer" .}}
Alternative #3: Use {{if}} action and predefined names
If you know the template names prior and it is not an exhausting list, you can use the {{if}} template action to include the desired template. Example:
{{if eq .Name "page1"}}
{{template "page1" .}}
{{else if eq .Name "page2"}}
{{template "page2" .}}
...
{{end}}
Alternative #4: Modifying the static template text
The idea here is that you could modify the static text of the outer template manually and insert the name of the inner template you want to include.
The downside of this method is that after inserting the name of the inner template, you have to re-parse the template, so I don't recommend this.

Add textContent to HTML via MediaWiki template

I have created a MediaWiki template named by the Hebrew letter א (template:א). Its content is:
<code></code>
I call it by {{א|SOME_textContent}}.
Desired state
I desire to show a single-line code iside regular text, for example:
הסימן הזה = הינו סימן שוויון
My problem
My problem is that after I save a page with the above template call, I get an empty <code> tag content ().
My question
Why do I get empty <code> tag content (), instead getting SOME_textContent (the input I gave in call after the vertical bar (|))?
Update - I tried this but didn't get desired state
Template page code:
<code>{{{1}}}</code>
Template page output:
{{{1}}}
Article page code:
{{א|=}}
Article page output:
{{{1}}}
By definition, everything inside code tag will not be parsed, so your parameter is interpreted as string.
Instead of using html markup <code>, use parser function #tag like so:
{{#tag:code | { { phone code area: 970}, { phone code area: 961}, { phone code area: 98} } }}
So your template will look like:
<includeonly>{{#tag:code| {{{1}}} }}</includeonly>
A template won't magically insert its parameters unless you tell it. The correct template content would be
<code>{{{1}}}</code>

reusing handlebars & panini partials with different data

I've a number of 'building blocks' I've created of my own to use when templating a site and I'm wondering how I could use Panini to re-use partials on the same page, with different data.
Say for example I have a partial which basically adds a h1 tag followed by a single p tag but I want to be able to re-use that same partial on the same page with different data each time.
This is the content of the partial file for example;
<h1> {{ h1Header }}</h1>
<p> {{ pParagraph }} </p>
The Frontmatter data in the Index file;
---
h1Header: Hello!
pParagraph: This is some text.
---
And this to call the partial into action;
{{> partial }}
Unless I'm doing something fundamentally wrong the way I'm using it at the moment would mean I'd have to create several different partials for each possible outcome.
I was wondering if there was some way of sending arguments etc. If someone can point me in the right direction with even the simplest of examples just to get a feel of what I can do and what to look into I'd be grateful.
You can pass data to your partials passing a context or parameters to your partial. You can pass different data every-time you render the partial, according to the manual.
Having a partial called test:
<h1>{{foo}}</h1>
You can render it with specific data:
{{> test foo="bar"}}
{{> test foo="foobar"}}
Which results in
<h1>foo</h1>
<h1>foobar</h1>