LE: Upon revisiting your question, I realized my initial interpretation was incorrect. I have revised the answer and hope it aligns with your intended query this time.
If you are looking to add a CSS
class to an item while iterating through multiple items on the same page, refer to the previous answer below.
For adding a class based on an item's position in a global list on its own page, consider implementing the following approach.
Organizing the list & sorting
Gather all items in the $allPosts
variable. By default, they are usually sorted by .Date
in descending order (newest first). To customize the order or criteria, utilize the sort
function.
{{ $allPosts := where site.RegularPages "Type" "posts" }}
{{ $allPostsByDate := sort $allPosts ".Date" "asc" }}
Identifying specific pages
Determine which items are unique. For the first and last items, you can utilize built-in functions such as first
and last
, which return arrays containing one element each (the respective page).
{{ $firstPost := index (first 1 $allPostsByDate) 0 }}
{{ $lastPost := index (last 1 $allPostsByDate) 0 }}
Comparing with the current page
Ensure that all code snippets are included within a template like single.html
, which runs for every page. Verify whether the current page matches any of the special ones using their .Permalink
s to compare.
{{ if eq $firstPost.Permalink $.Permalink }} first-post {{ end }}
{{ if eq $lastPost.Permalink $.Permalink }} last-post {{ end }}
Total Integration
To visualize the complete list and differentiate them visually.
{{ $allPosts := where site.RegularPages "Type" "posts" }}
{{ $allPostsByDate := sort $allPosts ".Date" "asc" }}
{{ $firstPost := index (first 1 $allPostsByDate) 0 }}
{{ $lastPost := index (last 1 $allPostsByDate) 0 }}
{{/* on the single page */}}
{{ .Title }} —
{{ if eq $firstPost.Permalink $.Permalink }} first-post {{ end }}
{{ if eq $lastPost.Permalink $.Permalink }} last-post {{ end }}
<br><br>
{{/* on a list */}
{{ range $allPostsByDate }}
<a href="{{ .Permalink }}">{{ .Title }}</a>
{{ if eq $firstPost.Permalink .Permalink }} first-post {{ end }}
{{ if eq $lastPost.Permalink .Permalink }} last-post {{ end }}
<br>
{{ end }}
Previous Solution
Utilizing Hugo's last Function
Your syntax might contain a typo. Consider substituting the question mark with a dot. If the $
variable pertains to Hugo, then the error may be due to passing a PageState
instead of an array to the last
function. Adjust the code as follows:
{{ $last_posts := last 1 . }}
{{ $last_post := index $last_posts 0 }}
{{//or}}
{{ range $last_posts }}
{{ //access last post here }}
{{ . }}
{{ end }}
Applying the len Function in Hugo
To retrieve the last index by considering an array's length, leverage Hugo's len
function.
{{ $last_index := (len .) - 1 }}
{{ last_post := index . $last_index }}
Incorporating CSS Styling
Omit custom treatment for first and last posts in templates by utilizing CSS pseudo-classes like those for :first-child()
and :last-child()
. Implement a .posts
class for the posts container and apply styles in your stylesheet accordingly.
.posts:first-child {
/* style the first post */
border-top: 1px dashed red;
}
.posts:last-child {
/* style the last post */
border-bottom: 1px dashed black;
}
This method shifts computation to the client side but works efficiently for distinguishing first and last posts visually.