I'm trying to order items in a menu but It's not working out for me. I've tried to following according to their docs but it doesn't work at all.
In my header:
{{ range .Site.Data.Menu }}
<li>
<a href="{{ .URL | absURL }}"
{{ if and ( isset . "Title" ) ( ne .Title "" ) }} title="{{ .Title }}"{{ end }}>
{{ if and ( isset . "IconClass" ) ( ne .IconClass "" ) }}
<i class="fa {{ .IconClass }}"></i>
{{ end }}
{{ .Name }}
</a>
</li>
{{ end }}
menu.toml
[home]
Name = "Home"
Title = "Home"
URL = "/home"
weight = 1
[apparatus]
Name = "Apparatus"
URL = "/apparatus"
weight = 2
[deliveries]
Name = "Deliveries"
URL = "/deliveries"
weight = 3
[command]
Name = "Command"
URL = "/command"
weight = 4
[ambulance]
Name = "Ambulance"
URL = "/ambulance"
weight = 5
[service]
Name = "Service"
URL = "/service"
weight = 6
[about]
Name = "about"
URL = "/about"
weight = 7
[contact]
Name = "Contact"
URL = "/contact"
weight = 8
The menu ends up in a seemingly random order. How do I order them the way I want them?
I had the same problem and solved it by using negative numbers for the weight attribute.
Weight is the default sort for menus in Hugo. Some variations below:
{{ range .Site.Data.Menu.Sort }}
{{ range .Site.Data.Menu.ByName }}
{{ range .Site.Data.Menu.ByName.Reverse }}
{{ range .Site.Data.Menu.ByName.Limit 10 }}
{{ range .Site.Data.Menu.ByWeight }}
Change the line:
{{ range .Site.Data.Menu }}
by:
{{ range sort .Site.Data.Menu "Weight"}}
That solved the problem for me.
Related
how to filter post in Hugo by category taxonomy
I am having three main category like web, Linux and networking and i want to display recent 3 post of the category.
Please someone tell me how to do that.
Last 3 posts from 3 categories
{{ $p := where site.RegularPages "Type" "posts" }}
{{ $p = where $p "Params.categories" "intersect" (slice "web" "Linux" "networking" }}
{{ range first 3 $p }}
<h2>{{ .Title }}</h2>
{{ end }}
Source: https://discourse.gohugo.io/t/list-down-posts-from-multiple-categories/36701
Last 3 posts from 1 category
{{ $p := where site.RegularPages "Type" "posts" }}
{{ $p = where $p "Params.categories" "intersect" (slice "web") }}
{{ range first 3 $p }}
<h2>{{ .Title }}</h2>
{{ end }}
Source: https://discourse.gohugo.io/t/show-posts-by-category-not-working/33690
I have the following data structure working in a HUGO site
Data in local appearances.json file:
{
"events":[ {
"name": "title three",
"date": "7/02/2022",
"url": "http://some.com"
},
{
"name": "title one",
"date": "5/01/2022",
"url": "http://some.com"
},
{
"name": "title two",
"date": "7/01/2022",
"url": "http://some.com"
}]
}
Partial page:
<div class="row listrecent">
{{ range .Site.Data.appearances.events }}
{{- partial "list-partials/appearancebox.html" . -}}
{{end}}
</div>
output:
However, I would like to sort the contents of the array by "date", preferably with the newest event at the top - i.e the first block visible should be "title three"
I have tried various sort methods with some success but I cannot seem to combine sorting by date and converting the stringified date.
I could ensure the JSON is in the correct order but that seems fragile to me.
The solution in the end was this:
{{ $events := slice }}
{{ range .Site.Data.appearances.events }}
{{ $event := . }}
{{ $parsedEvent := dict }}
{{ range $k, $v := $event }}
{{ if eq $k "date" }}
{{ $parsedEvent = merge $parsedEvent (dict $k (time $v)) }}
{{ else }}
{{ $parsedEvent = merge $parsedEvent (dict $k $v) }}
{{ end }}
{{ end }}
{{ $events = $events | append $parsedEvent }}
{{ end }}
<div class="row listrecent">
{{ range sort $events "date" "desc" }}
{{ if (.date.After now) }}
{{- partial "list-partials/appearancebox.html" . -}}
{{ end }}
{{end}}
</div>
If anyone has a cleaner way then I am all ears!
Presuming that your json is "events.json", then go for the code below:
<ul>
{{ range sort $json.events "date" "desc" }}
<li>
<b>
{{ .name }}
</b>
<br>
{{ .date }}
</li>
{{ end }}
</ul>
The above solution is working check my branch repo
I'm not near my dev set-up, so this will be psuedo code and concepts, but:
https://gohugo.io/functions/range/#readout <- not very detailed.
https://gohugo.io/functions/sort/#readout <- Much more data.
So, something like:
Authors: {{ range sort .Site.Params.authors }}{{ .firstName }} {{ end }}
(example given in link 2 above).
So concept/psuedo, I believe:
{{ range sort .Site.Data.etc.etc. "date" }}
This would sort by ascending (again, not sure the final output for a date field, also due to the fact I believe you have date as a string, which I understand, it's json, but meaning, it's not going to give you expected output. so you might have to convert that field to a date object or data sortable concept as opposed to a string.
https://gohugo.io/functions/format/#use-local-and-utc
Might be of assistance for that.
Again, not near my compu/dev setup, but the above should work. The key being the sort command.
I need to accomplish a layout with a link to next and previous post and a counter marking the actual post, bad representation ahead:
<previousPost 10/100 nextPost>
I put everything to work, except the mention of the current post number:
{{ $posts := (where .Site.RegularPages "Section" "==" "news") }}
{{ $postCount := len $posts }}
{{ $postCount }}
{{ if .PrevInSection }}
Prev Post
{{ end }}
{{ I have no idea }}/{{ $postCount }}
{{ if .NextInSection }}
Next Post
{{ end }}
But I have no clue on how to find the value of the page in the netxInSection context. I'm thinking about changing my code to a range and use the index to mark the current page but I think that should be a smarter way.
Thanks!
After some head banging on the wall I found a way to do it...
{{ range $index, $element := (where .Site.RegularPages "Type" "news" ).Reverse }}
{{ if eq . $ }}
{{- $.Scratch.Set "currentItem" (add $index 1) }}
{{ end }}
{{end}}
{{ $posts := (where .Site.RegularPages "Section" "==" "news") }}
{{ $postCount := len $posts }}
{{ if .PrevInSection }}
prev
{{ else }}
prev
{{ end }}
<div class="page-navigation__counter">
{{ $.Scratch.Get "currentItem" }}/{{ $postCount }}
</div>
{{ if .NextInSection }}
next
{{ else }}
next
{{ end }}
I try to access the content of the first entry of a Taxonomy. I can get the basic fields like {{.Name}} with the following code:
<ul>
{{ range $key := .Site.Taxonomies.tags.ByCount }}
<li>
{{ with index .Pages 0 }}
{{ .Name }} <-- Name of the first post
{{end}}
{{ .Name }} ({{ .Count }})</li>
{{ end }}
</ul>
But how do I access a custom field of the first content item within the taxonomy?
The fields can be accessed by using {{ .Params }}.
I would like to hide any duplicate occurences of a date that shows in my calendar. I currently have a calendar widget, that has dates that looks like this...
9 {{ EVENT DATA }}
MON {{ EVENT DATA }}
9 {{ EVENT DATA }}
MON {{ EVENT DATA }}
9 {{ EVENT DATA }}
MON {{ EVENT DATA }}
10 {{ EVENT DATA }}
TUE {{ EVENT DATA }}
11 {{ EVENT DATA }}
WED {{ EVENT DATA }}
12 {{ EVENT DATA }}
THURS {{ EVENT DATA }}
I would like it to look like this
9 {{ EVENT DATA }}
MON {{ EVENT DATA }}
{{ EVENT DATA }}
{{ EVENT DATA }}
{{ EVENT DATA }}
{{ EVENT DATA }}
10 {{ EVENT DATA }}
TUE {{ EVENT DATA }}
11 {{ EVENT DATA }}
WED {{ EVENT DATA }}
12 {{ EVENT DATA }}
THURS {{ EVENT DATA }}
Where the n+1 occurence of a date is hidden. I am familiar with using !$first, but I would like to figure out how to do !$first of matching str. Anyone have any experience?
Here is a jsfiddle I am playing with. any help is mega appreciated!
jsfiddle attempt with ng-class
You could do an AngularJS filter which marks the first items in the collection of repeated ones and then use it in your ng-repeat.
The idea is to iterate over the collection and the first time an item is found set a property on it (isFirst) as true, and show the day only if that condition exist. Like this:
app.filter('myFilter', function() {
return function(collection, key) {
var output = [],
keys = [];
angular.forEach(collection, function(item) {
var ikey = item[key];
if (keys.indexOf(ikey) === -1) {
keys.push(ikey);
item['isFirst'] = true;
}
output.push(item);
});
console.log(output);
return output;
};
});
Then in your ng-repeat...
<div class="row individualMeetingRow" ng-repeat="meeting in user.meeting | myFilter:'start_time' | orderBy:['start_time']">
<!-- code omitted for brevity -->
<!-- HERE -->
<div class="col-sm-6" ng-show=meeting.isFirst>
<p>{{ meeting.start_time | date : "d"}}</p>
<p>{{ meeting.start_time | date : "EEE"}}</p>
</div>
<div class="col-sm-6 pull-right">
<p>{{ meeting.title}}</p>
<p>{{ meeting.address_country}}</p>
</div>
Where myFilter is the name of the just-created filter and 'start_time' is the criteria you use in order to match the items (and see which one is repeated).
See full example here.
Rather than hiding based on first duplicate start time you can group element on the basis of start time and loop and iterate them in angularjs.
eg. for your meeting array your convert your array as like below:
var oldStartTime = 0;
var mainMeetingList= [];
var oldObj = {
startTime: "",
meetings: []
};
meeting.forEach(function(obj, index) {
if(oldStartTime != obj.start_time) {
oldObj = {
start_time: obj.start_time,
meetings: [obj]
};
oldStartTime = obj.start_time;
mainMeetingList.push(oldObj);
} else {
oldObj.meetings.push(obj);
}
});
Now you can iterate mainMeetingList array based on start_time and show all meetings for that start time.
<div class="row individualMeetingRow" ng-repeat="meetingObj in mainMeetingList orderBy:['start_time']">
<div class="col-2">
<p>{{ meetingObj .start_time | date : "d"}}</p>
<p ng-repeat="mt in meetingObj.meetings orderBy:['start_time']">{{ mt.start_time | date : "EEE"}}</p>
</div>
</div>
Also $first will match to only first element of array. what if there is 2 meeting on 10th. Then it will not match with first because it is duplicate for 4th element. this can be repeated onward. So I think you should not use first.
I have found $first description on angularjs site is as below:
$first boolean true if the repeated element is first in the iterator.