So I just noticed that when I try to access something from .Site itself inside a range block it returns as null/blank.
Here's an example:
<div class="row weekday">
{{ .Site.Data.company.social_media.whatsapp }}
{{ range $entry := sort .Site.Data.events "order" "asc" }}
<div class="col-sm-6 col-md-4 col-lg-4">
{{ .Site.Data.company.social_media.whatsapp }}
{{ partial "events_detail.html" (dict "entry" $entry) }}
</div>
{{ end }}
</div>
The first .Site.Data.company.social_media.whatsapp (before the range) renders a phone number.
The second .Site.Data.company.social_media.whatsapp (after the range) do not renders anything.
This same behavior happens in the partial events_detail.html. If I try to access the .Site from inside of the partial scope it renders a null. I also tried to pass it along on the (dict ...) but no lucky.
What Am I missing here?
I was missing how Hugo manage the scopes for the dot. You read a more in-depth explanation about this (and other important concepts) here:
https://regisphilibert.com/blog/2018/02/hugo-the-scope-the-context-and-the-dot/
In Resume is (extracted from the link above):
The root context, the one available to you in your
baseof.html and layouts will always be the Page context. Basically
everything you need to build this page is in that dot. .Title,
.Permalink, .Resources, you name it.
Even your site’s informations is stored in the page context with .Site
ready for the taking.
But in Go Template the minute you step into a function you lose that
context as your precious dot or context is replaced by the function’s
own… dot.
(...)
Same goes here, once you’ve opened an iteration with range the context
is the whatever item the cursor is pointing to at the moment. You will
lose your page context in favor of the the range context.
{{ range .Data.Pages }}
{{/* Here the dot is that one page 'at cursor'. */}}
{{ .Permalink }}
{{ end }}
Luckily Hugo stores the root context of a template file in a $ so no
matter how deeply nested you are within with or range, you can always
retrieve the top context. In basic template file, it will generally be
your page.
{{ with .Title }}
{{/* Dot is .Title */}}
<h1>{{ . }}</h1>
{{/* $ is the top level page */}}
<h3>From {{ $.Title }}</h3>
{{ end }}
Related
I’m working with this tutorial which has the following lines:
{% set user_link %}
<span class="user_popup">
<a href="{{ url_for('main.user', username=post.author.username) }}">
{{ post.author.username }}
</a>
</span>
{% endset %}
{{ _('%(username)s said %(when)s',
username=user_link, when=moment(post.timestamp).fromNow()) }}
It looks this was specifically because he uses Babel translate, which he talks about on his blog.
My question is, how can I make this work when I strip all the Babel code out, because I don’t need any translation, specifically the bit after end set.
This is the sort of thing I tried but could never get the replacement correct:
{{username, username=user_link }} said {{when,when=moment(post.timestamp).fromNow())}}
{{ user_link }} said {{ moment(post.timestamp).fromNow() }}
The arguments after the string define the replacement map for the different keywords, so:
%(username)s will be replaced by user_link, because username=user_link
$(when)s will be replaced by moment(post.timestamp).fromNow(), because when=moment(post.timestamp).fromNow()
The s ending the $(placeholder)s is there to indicate that the placeholder should be considered as a string.
I just started learning django for a few day. Django's templating system looks fascinating. but currently I am facing an issue.
I need to print this kind of text in my webpage multiple times through template.
She {{ was }} a very {{ helpful }} and {{ attractive}} girl.
But whenever I try to use this in template, it thinks those words are variable thaI am referring, and vanishes them from the output due to not getting a value. So the output becomes,
She a very and girl.
I completely understand that this is the intended behaviour, but in some case I am trying to tell the rendering engine to render that as it is. Is there any filter or workaround??
[ I have to use them inside the template, and they can't be passed through variables as string]
You can use the verbatim template tag, which will stop rendering what is inside the tag. See docs here.
{% verbatim %}
She {{ was }} a very {{ helpful }} and {{ attractive}} girl.
{% endverbatim %}
I have the following template code:
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ article.title }}</h3>
</div>
<div class="panel-body">
{{ article.content }} <!--will display the full text-->
</div>
I intend to show the first 200 characters of the content, like:
{{ article.content|length=200 }}
How to achieve such a constrain on the text.
There are two template filters here that are useful: slice and truncatechars.
slice limits an iterable (here a string) to a given number, for example:
{{ variable | slice:":200" }}
whereas truncatechars does approximately the same, except that in case the string is longer than the upper bound (here 200), it will slice to the upperbound minus three, and add an ellise:
{{ variable | truncatechars:"200" }}
For a smaller upperbound, to demonstrate the difference, for a string variable = "foobarqux" we would get:
{{ variable | slice:":6" }} # foobar
{{ variable | truncatechars:"6" }} # foo...
The two thus differ: the latter gives a textual hint that there is actually more content. Of course it depends on the specific situation which filter suits your needs.
A nice thing is that you can emulate truncatechars in terms of slice:
{{ variable | truncatechars:":6" }}
is equivalent to:
{% if variable|length > 6 %}{{ variable|slice:":3" }}...{% else %}{{ variable }}{% endif %}
But it is of course not the most elegant solution: in case you want truncatechars behavior, it is better to use the specific filter.
You can use truncatechars filter:
{{ article.content|truncatechars:200 }}
I've got this template that parses multiple items of a slice onto the page. It does that really well.
However, I now want to use the very same template to parse a single value of the slice, based on the range index. The slice is used in multiple files so I can't just .Execute it like Slice[1:2]
{{ $bpi := .Index}}
{{ range $i, $elmt := .Slice }}
{{ if $bpi.Equals $i }}
<div>{{ .SliceContent }}</div>
{{ end }}
{{ end }}
From what I've read is that the template isn't ment for computation, but if you've got a range index and if-statements in the html/template package it seems to me that I must be doing something wrong. I can write a FuncMap ofcourse, no problemo. But it doesn't seem right to me given these facts.
I am using something like this to conditionally include a default image or the first from a supplied slice of pictures. So I think this will provide you with the basis to do what you want. I check the slice has values, pulling the Nth item using the {{index .Slice n}} syntax as follows:
{{ $idx := 2}}
{{if .Pictures}}
<img src="{{if .Pictures}}{{index .Pictures $idx}}{{end}}" alt="supplied first picture">
{{else}}
<img src="http://fpoimg.com/200x200?text=Placeholder(FPOimg.com)" alt="default picture">
{{end}}
Therefore you can do the following:
{{ $bpi := .Index}}
{{ if .Slice }}
{{ index .Slice $bpi }}
{{ end }}
I fail to access a value that I stored in the session:
views.py
...
request.session['content_lang_code'] = request.GET.get('lang')
base.html template
</body>
<p>Hello {{ request.user.username }} your selected content language is:
session.content_language_code {{ session.content_language_code }} <br>
request.session.content_language_code {{ request.session.content_language_code }}
</p>
While the username is rendered, content_language_code is not. The debugger shows that content_language_code is in session._session. I tried session.get('content_language_code') as well, but that did no work either.
What is the correct way to retrieve a session attribute from within a template?
(debug screen shot at http://lcrfiles.hoerbe.at/stuff/screenshot2013-03-29.png)
You put it in the session with the key content_lang_code but are trying to access it with a different key content_language_code. If you change {{ request.session.content_language_code }} to {{ request.session.content_lang_code }} it should work.