Sorted Map Iteration in Go Templates? - html

I'm building a website in Go, using the Hugo static site generator. What I'm trying to do is build a dynamic navigation bar for my web pages.
Here's what I'm doing:
In my config.yml file, I've defined a Map of links that I'd like to appear in my navbar -- here's what this file looks like:
baseurl: "https://www.rdegges.com/"
languageCode: "en-us"
title: "Randall Degges"
params:
navLinks: {"Twitter": "https://twitter.com/rdegges", "Facebook": "https://www.facebook.com/rdegges", "Google+": "https://plus.google.com/109157194342162880262", "Github": "https://github.com/rdegges"}
So, I've also got an index.html template in Hugo that contains a navbar which looks like this:
<nav>
<ul>
{{ range sort $title, $link := .Site.Params.navLinks }}
<li>{{ $title }}</li>
{{ end }}
</ul>
</nav>
This above code works correctly, with one exception: I'd like to order the results of my links instead of having them randomly ordered each time.
I know that Maps are not inherently structured in Go -- but is there a way to retain the original ordering of my navigation elements in some way?
Thanks for the help!

Go templates sort maps by key. If you want to force a specific order, then use a slice:
Here's the YAML:
baseurl: "https://www.rdegges.com/"
languageCode: "en-us"
title: "Randall Degges"
params:
navLinks:
- title: Twitter
url: https://twitter.com/rdegges
- title: Facebook
url: https://www.facebook.com/rdegges
... and the template:
<nav>
<ul>
{{ range $link := .Site.Params.navLinks }}
<li>{{ $link.title }}</li>
{{ end }}
</ul>
</nav>

Related

Hugo Data Templates: Where to create files and what to put in them?

I have a Hugo SSG website.
My JSON file is saved in: /data/source.json
I created a template file: /layouts/test.html that has this content:
<!-- Data is in /data/source.json -->
{{ range .Site.Data.source }}
{{ range .names }}
<!-- person_name -->
<p>{{ .identifier.person_name }}</p>
{{ end }}
{{ end }}
How do I render this .html content to the website?
The Hugo documentation here doesn't explain what I need to do after making the .html file.
It looks like you have two range operations when you need only one. You are not ranging over multiple source.json files, correct?
Assuming you have a file data/source.json like this:
{
"names": [
{
"identifier": {
"person_name": "Joe Wilson"
}
},
{
"identifier": {
"person_name": "Nancy Wilson"
}
}
]
}
Then it should be possible to render those names like this:
{{ range .Site.Data.source.names }}
<p>{{ .identifier.person_name }}</p>
{{ end }}
Add that to a layout in your themes/{theme-name}/layouts and it will render on the pages using that template.

Jekyll Collection Filter

I'm trying to grab a specific item from a collection called 'content' based on an id using where_exp, but for the life of me I can't get it to work. Here's the code:
filter:
{% assign var = site.content | where_exp:"content", "content.id == 'testId'" | first %}
frontmatter for post in collection:
---
layout: content
title: "This is the title"
image: "assets/photos/image.jpg"
id: "testId"
---
html:
<img class="full-width-poto" src="{{ var.image }}">
I can't figure out what I'm doing wrong.
Note, I've been referring to this post: Getting a specific item from a collection in Jekyll and https://riptutorial.com/jekyll/example/28446/accessing-a-specific-collection-item
Ok, I figured out my problem, just in case someone comes across this. For some reason I can't use the key 'id' for this...it must be hardcoded for something else.
I swapped in 'myid' and it works fine now...

build an includable template as string [django]

I want to build a list of clickable links for my nav, and because these are links to my site, I want to use the url-tag. I get a list of dictonaries which knows all names for the links and create a template string with them with this function:
def get_includable_template(links):
output = '<ul>'
for link in links:
output = output + '<li><a href="{% url' + get_as_link(link) + '%}>" + link['shown'] + '</a></li>'
output = output + '</ul>
links looks like this:
links = [
{'app': 'app1', 'view': 'index', 'shown': 'click here to move to the index'},
{'app': 'app2', 'view': 'someview', 'shown': 'Click!'}
]
get_as_link(link) looks like this:
def get_as_link(link):
return "'" + link['app'] + ':' + link['view'] + "'"
The first method will return a template, which looks like this (but it's all in the same code line):
<ul>
<li>click here to move to the index</li>'
<li>Click!</li>
</ul>
I want this to be interpreted as template and included to another template.
But how to include this?
Let's say, my other template looks like this:
{% extends 'base.html' %}
{% block title %}App 1 | Home{% endblock %}
{% block nav %}INCLUDE THE TEMPLATE HERE{% endblock %}
{% block content %}...{% endblock %}
What I have already tried:
make the template string a variable - doesn't work, because it doesn't interpret template language in variables (I couldn't find a template tag similar to safe which not only interprets HTML code but also template code.
Building HTMl code in my methods (Isn't best-practice at all, because I needed to use absolute paths)
Is there a good solution about this?
You are making this more complicated than it needs to be.
Firstly, it seems that the only reason you need this to be interpreted as a template is so that it parses the url tag. But there is already a way of creating links in Python code, and that is the reverse() function. You should use that instead.
Secondly, the way to dynamically generate content for use inside a template is to use a custom template tag.

Django - Shorten text content retrieved in html template

I would like to know how to shorten text content retrieved to get a preview instead of getting a block of text in the html template
From: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
To:
aaaaaaaaaaaaaaaaaaaaaaaaaaa....
The code that is used to retrieve the contents is :
<a class="list_content" href="/qna/view" onclick="document.forms['q_title_{{ q.id }}'].submit(); return false" title="{{ q.content }}">{{ q.content }} </a><br/>
Many thanks!
If you are using Django 1.4, truncatechars filter will be the best way to go:
{{ q.content|truncatechars:25 }}
Assuming that "q.content" is a string you could use the slice command:
{{ q.content|slice:":255" }}
truncatechars template filter for django 1.4

Create hyperlink in django template of object that has a space

I am trying to create a dynamic hyperlink that depends on a value passed from a function:
{% for item in field_list %}
<a href={% url index_view %}{{ item }}/> {{ item }} </a> <br>
{% endfor %}
The problem is that one of the items in field_list is "Hockey Player". The link for some reason is dropping everything after the space, so it creates the hyperlink on the entire "Hockey Player", but the address is
http://126.0.0.1:8000/Hockey
How can I get it to go to
http://126.0.0.1:8000/Hockey Player/
instead?
Use the urlencode filter.
{{ item|urlencode }}
But why are you taking the name? You should be passing the appropriate view and PK or slug to url which will create a suitable URL on its own.
Since spaces are illegal in URLs,
http://126.0.0.1:8000/Hockey Player/
is unacceptable. The urlencode filter will simply replace the space with %20, which is ugly/inelegant, even if it does kind of get the job done. A much better solution is to use a "slug" field on your model that represents a cleaned-up version of the title field (I'll assume it's called the title field). You want to end up with a clean URL like:
http://126.0.0.1:8000/hockey_player/
To make that happen, use something like this in your model:
class Player(models.Model):
title = models.CharField(max_length=60)
slug = models.SlugField()
...
If you want the slug field to be pre-populated in the admin, use something like this in your admin.py:
class PlayerAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
....
admin.site.register(Player,PlayerAdmin)
Now when you enter a new Player in the admin, if you type "Hockey Player" for the Title, the Slug field will become "hockey_player" automatically.
In the template you would then use:
{% for item in field_list %}
<a href={% url index_view %}{{ item.slug }}/> {{ item }} </a> <br>
{% endfor %}
There is this builtin filter .
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#urlencode
Although you should be using one of these
http://docs.djangoproject.com/en/dev/ref/models/fields/#slugfield