Back

MooseDog Studios

Here in Vermont, Convention Takes A Back Seat To Quality

MooseDog Studios Autumn Hero Picture

File Last Modified Is Available

Published: Jun 8, 2023 Updated: Mar 1, 2024

This is a long-standing standalone feature-wish in Eleventy, publishing directly to a file both the date published and the date last updated. I'm biased, but I almost always look for this info at the top of any blog post I'm about to read. Context like this is important if I'm to read further.

As referenced in another article of mine, I have come up with a solution that works for each individual post, so...

On To The Show

NB that I use a base layout for blog posts stashed up in Eleventy's _includes/layouts directory. The front matter in this file is primarily focused on the JSON-LD aspect:

/_includes/layouts/blog.njk
---
eleventyComputed:
  meta:
    "@type": "Website"
    "name": "Selfless Studios"
    "description": "Web Development For You"
    "url": "https://selfless.com{{ page.url }}"
    "logo": "https://selfless.com/img/selfless-logo.png"
    "contactPoint":
      "@type": "ContactPoint"
      "name": "Seam McLovin"
      "email": "sean@selfless.com"
      "telephone": "+1802697231"
      "contactType": "Web Developer"
---

...and is thus included in the final built file for every single blog post. Moving ahead, let's look at...

Shortcode Magic

Of course, shortcodes are created in your .eleventy.js file. Let's use the power of Node JS to query your operating system, which does store the last modified metadata.

.eleventy.js
//
  // find the last modified file info to publish as "Updated" on a blog list page or on the post itself
  //
  eleventyConfig.addNunjucksShortcode("lastModifiedShortCode", function(fileNameWithPath) {

    //
    // let's use Node JS to find all the file's OS specific metadata
    //
    let stats = fs.statSync(fileNameWithPath);

    //
    // zero in on a date object
    //
    let statsDate = stats.mtime;

    //
    // and format said date object
    //
    let formattedDate = `${statsDate.getUTCMonth()+1}/${statsDate.getUTCDate()}/${statsDate.getUTCFullYear()}`;

    //
    // and send the formatted date off to be published via shortcode
    //
    return `${formattedDate}`;
  });

All that's left is to propagate your desired information out into your files. For example, let's start with the blog list page:

my-list-of-blog-posts.njk
<section class="blog-list-items">
    {% for post in posts %}
      <div class="blog-list-item">
        <a href="{{ post.url | url }}" class="blog-list-item-link">{{ post.data.title }}</a>
        <p class="blog-list-item-dates">Published: {{ post.data.date | dateFormat }}</p>
        <p class="blog-list-item-dates">Updated: {% lastModifiedShortCode post.inputPath %}</p>
        <p class="blog-list-item-excerpt">{{ post.data.excerpt }}</p>
      </div>
    {% endfor %}
  </section>

And the quick implementation on any blog post:

my-enlightening-blog-post.njk
<section class="blog-dates">
    <small class="blog-small">Published: {{ date | dateFormat }}</small>
    <small class="blog-small">Updated: {% lastModifiedShortCode page.inputPath %}</small>
  </section>

And moving ahead, a little extra must be done to get this valuable information into the JSON-LD data for each blog post. The problem is that the final formatted date is different from what one publishes to a web page. Specifically, it must be of the format yyyy-mm-dd. So we need to create a copy of the above shortcode in your .eleventy.js but with a different name, and a different date format:

.eleventy.js
// let's call this shortcode "lastModifiedShortCode"
//
// this one line below being the only difference with the previous "lastModifiedShortCode" shortcode
//
// let formattedDate = `${statsDate.getUTCMonth()+1}/${statsDate.getUTCDate()}/${statsDate.getUTCFullYear()}`;
//
let otherFormattedDate = `${otherStatsDate.getUTCFullYear()}-${otherStatsDate.getUTCMonth()+1}-${otherStatsDate.getUTCDate()}`;

And the frontmatter for each blog post contains the following:

my-enlightening-blog-post.njk
---
eleventyComputed:
  meta:
    "datePublished": "2023-06-04"
    "dateModified": "{% lastModifiedShortCode page.inputPath %}"
---

And finally, it's entirely feasable to incorporate this data into a sitemap.xml file in eleventy.

sitemap.njk
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  {% for page in collections.all %}
    {% if not page.data.draft %}
    <url>
      <loc>https://moosedog.io{{ page.url | url }}</loc>
      <lastmod>{% lastModifiedShortCode page.inputPath %}</lastmod>
      <changefreq>{{ page.data.changeFreq if page.data.changeFreq else "monthly" }}</changefreq>
    </url>
    {% endif %}
  {% endfor %}
</urlset>

So To Recap

TOP

SHARE