Hugo inquired about the process of including a class specifically for the final post

I've set up my baseof.html file to add the class first-post to the body tag in order to style the first post differently from the rest, especially when paginated:

<body class="
{{ with where site.RegularPages "Type" "posts" }}
{{ $first_post = index . 0 }}
{{ if eq $first_post $ }}
first-post
{{ end }}
{{ end }}
">

Now I'm wondering how to achieve the same for the last post. When I tried using the code below, I encountered an error saying “can’t iterate over *hugolib.pageState”:

<body class="
{{ with where site.RegularPages "Type" "posts" }}
{{ $last_post := last 1 $ }}
{{ if eq $last_post $ }}
last-post
{{ end }}
{{ end }}
">

For more details on the last function, check out the documentation: https://gohugo.io/functions/last/

Answer №1

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 .Permalinks 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.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to initiate a new animation from the current position?

Here is my custom box: <div class="customBox"></div> It features a unique animation: .customBox{ animation:right 5s; animation-fill-mode:forwards; padding:50px; width:0px; height:0px; display:block; background-color:bla ...

Overlap one element entirely with another

Currently, I am working on a way for an element called overlayElement to completely cover another element known as originalElement. The overlayElement is an iFrame, but that detail may not be significant in this scenario. My goal is to ensure that the over ...

The fixed div width suddenly switches to 100% without warning

I'm struggling with a basic design issue. My goal is to align the purple div next to the yellow div. Both of these divs are nested inside the white div, and the white div is enclosed within the blue div. When I float the yellow and purple divs to the ...

Highlighting table rows on mouseover using CSS

I am trying to add a hover effect to my table rows, but when I apply the CSS styles for this behavior, the rows start wrapping. Here's a comparison of how the table rows look before and after applying the styles. You can see the wrapping issue in the ...

Issue with Angular 9 Json pipe not showing decimal values

My JSON data looks like this: this.data = {"eoiStatistics": [ { "dateRange": { "explicitStartDate": "1997-01-01T00:00:00", "explicitEndDate": "2019-07-01T00:00:00" }, "outstandingApplicationCount": 0.0, "pendingApplicationCount": 24.0, " ...

Combining labels over multiple lines using lower division

I have a setup where I am using two DIVs, one positioned below the other. The top DIV contains a Multiline Label that dynamically generates data. However, when the data in the label exceeds a certain length, it does not create space and instead overlaps w ...

Is there a way to position text at the bottom of a card?

Looking to showcase multiple articles on a single page? I utilized Bootstrap 5 cards to create a visually appealing layout. While everything turned out as I hoped, the only issue I'm facing is that the "read more" link is not positioned at the bottom ...

The issue of CSS not being applied to HTML content after being inserted via AJAX has been encountered

I've successfully implemented AJAX to retrieve specific page content from a database, but now I'm facing an issue: When it comes to the 'Contact' page, the form retrieved from the database (as HTML) is not applying the CSS styles I hav ...

Exploring PHP Queries with Div Classes

I'm in desperate need of assistance. I'm currently working on putting together a website and pulling data from a mysql database. The specific div that I'm trying to populate is provided below. The issue I'm facing is how do I integrate ...

In the Swiper function of JavaScript within a Django template, the occurrence of duplicate elements (products) is being generated

Experimenting with displaying products in a Django template, I decided to utilize the Swiper js class. This allowed me to showcase the products within a div, complete with navigation buttons for scrolling horizontally. However, when testing this setup wit ...

Is it possible to design and implement Materialize CSS inputs without relying on Materialize CSS?'

Is there a method to implement Materialize CSS input elements that include placeholders and icons without directly using the Materialize CSS framework? I prefer not to mix frameworks in order to avoid potential conflicts, as I am already utilizing anothe ...

Reduce the width beyond the necessary limit

I'm struggling to adjust the width of an image to match it with the card size without stretching it or breaking the layout. Most solutions I've come across recommend using inline-block, but this doesn't work well for smaller images. It seems ...

Any tips on showing inline input within an li element?

HTML Code: <div id="choices"> <ul> <li> <label for="input_size">Input Size</label> <input type="text" id="input_size"> </li> <li> ...

Using single-line ellipsis with the Material-UI select and option components

I have a TableHead Component with multiple columns. Among them is a <Select> element that allows users to filter the table content based on one of four statuses. I am trying to implement an ellipsis at the end of the option string if it exceeds its c ...

Could we customize the appearance of the saved input field data dropdown?

I'm currently working on styling a form that includes an input field. The challenge I'm facing is that the input field needs to be completely transparent. Everything works fine with the input field until I start typing, which triggers the browser ...

Uncover the HTML tag associated with specific text on a webpage with the help of selenium

<div class="searchSummary floatL"> <span>18</span> results for "gloves" </div> Can someone assist me in using Selenium to extract the 'span' tag containing '18'? I am trying to specifically retrieve the 'sp ...

What is the best way to specify the dimensions of an image with CSS or Bootstrap?

I am facing some challenges while building my website. The ideal look of the page is represented by home_page_ideal. The issue arises with the small boxed image on the top left corner. Once I scroll to the top, the page displays as home_page_issue. The CSS ...

Is it possible to adjust the position of my React button using numerical values (##px) without success?

I'm facing an issue with positioning my button to the right. Despite my best efforts, I haven't been able to move it more than a few positions. In summary, here are the scenarios I've encountered while trying to solve this problem: When I ...

Looking to replicate a Modal that I designed, but unsure which elements need altering in order to achieve this. I am hoping to create three duplicates of the Modal

This modal is functioning perfectly, and now I want to replicate the same modal three times on a single page. I require three distinct buttons on the same page to trigger these separate modals. At this point, I am unsure which attributes need modification ...

Is there a way to relocate the play again button below the box?

How can I ensure that my "Play Again" button moves up to align perfectly under the black border box? The black border box is styled with a class named .foot .button { background: rgb(247, 150, 192); background: radial-gradient(circle, rgba(247, 1 ...