diff options
| -rw-r--r-- | CHANGELOG.md | 18 | ||||
| -rw-r--r-- | exampleSite/config/_default/config.yaml | 7 | ||||
| -rw-r--r-- | exampleSite/config/_default/params.yaml | 11 | ||||
| -rw-r--r-- | layouts/_default/home.humanstxt.txt | 12 | ||||
| -rw-r--r-- | layouts/_default/list.atom.xml | 5 | ||||
| -rw-r--r-- | layouts/_default/list.feed.xml | 3 | ||||
| -rw-r--r-- | layouts/_default/list.jsonfeed.json | 6 | ||||
| -rw-r--r-- | layouts/partials/author.html | 6 | ||||
| -rw-r--r-- | layouts/partials/schema.org/article.html | 6 | ||||
| -rw-r--r-- | layouts/partials/site-author.html | 34 | ||||
| -rw-r--r-- | tests/feed-atom.spec.js | 74 | ||||
| -rw-r--r-- | tests/feed-rss.spec.js (renamed from tests/feeds.spec.js) | 42 | ||||
| -rw-r--r-- | tests/humans.spec.js | 39 |
13 files changed, 219 insertions, 44 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b3e4913..085f44b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ``` {{ $siteLastMod := partial "site-last-mod.html" . }} ``` +- Introduced a new partial template `site-author.html` to handle site author + information more consistently across Hugo versions. This change accommodates + the deprecation of `site.Author` in favour of `site.Params.author` for Hugo + versions equal to or greater than 0.124.0. Usage: + ``` + {{ $siteAuthor := partial "site-author.html" . }} + + {{ with $siteAuthor.name }} {{ . }} {{ end }} + {{ with $siteAuthor.email }} {{ . }} {{ end }} + {{ with $siteAuthor.github }} {{ . }} {{ end }} + {{ with $siteAuthor.twitter }} {{ . }} {{ end }} + {{ with $siteAuthor.location }} {{ . }} {{ end }} + ``` ### Changed @@ -37,6 +50,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `<updated>` tag. - In `list.feed.xml`, replaced `site.LastChange` with `$siteLastMod` in the `<lastBuildDate>` tag. +- Updated `humans.txt`, Atom feed, RSS feed, JSON feed, author partial, and + schema.org Article template to use the `site-author.html` partial for + retrieving site author information. +- Moved site author configuration from `config.yaml` to `params.yaml` to align + with the recommended usage of `site.Params.author`. ### Fixed diff --git a/exampleSite/config/_default/config.yaml b/exampleSite/config/_default/config.yaml index 3941f28..eda82ea 100644 --- a/exampleSite/config/_default/config.yaml +++ b/exampleSite/config/_default/config.yaml @@ -133,13 +133,6 @@ sitemap: filename: sitemap.xml priority: 0.5 -author: - name: John Doe - email: john@example.com - github: john_doe - twitter: john_doe - location: 'Kyiv, Ukraine' - # For more see https://gohugo.io/getting-started/configuration-markup/ markup: defaultMarkdownHandler: goldmark diff --git a/exampleSite/config/_default/params.yaml b/exampleSite/config/_default/params.yaml index bf6c79a..12a00b0 100644 --- a/exampleSite/config/_default/params.yaml +++ b/exampleSite/config/_default/params.yaml @@ -15,7 +15,7 @@ keywords: # A "copyright"-line to be added to RSS/Atom files. # "©" and "{year}" will be replaced by © and the current year. -copyright: 'Copyright © 2019-{year} John Doe' +copyright: 'Copyright © 2019-{year} Serghei Iakovlev' # Colour scheme. Options: red, orange, magenta, cyan, blue, brown colorScheme: '' @@ -88,6 +88,13 @@ seo: # you have to set `googleAnalytics` param in config.yaml file. anonymizeIp: true +author: + name: Serghei Iakovlev + email: egrep@protonmail.ch + github: sergeyklay + twitter: egreps + location: 'Wrocław, Poland' + social: # Array of Facebook Page Admin IDs for Domain Insights facebookAdminIds: [] @@ -96,7 +103,7 @@ social: facebookId: '' # Twitter username for the website - twitter: john_doe + twitter: egreps # Configure search engine search: diff --git a/layouts/_default/home.humanstxt.txt b/layouts/_default/home.humanstxt.txt index 0d3efe9..23286fe 100644 --- a/layouts/_default/home.humanstxt.txt +++ b/layouts/_default/home.humanstxt.txt @@ -1,11 +1,12 @@ -{{- with site.Author.name }} +{{- $siteAuthor := partial "site-author.html" . -}} +{{- with $siteAuthor.name }} /* TEAM */ Author: {{ . }} -{{- with site.Author.email }}{{ printf "\n Contact: %s" . }}{{ end }} -{{- with site.Author.github }}{{ printf "\n GitHub: @%s" . }}{{ end }} -{{- with site.Author.twitter }}{{ printf "\n Twitter: @%s" . }}{{ end }} -{{- with site.Author.location }}{{ printf "\n From: %s" . }}{{ end }} +{{- with $siteAuthor.email }}{{ printf "\n Contact: %s" . }}{{ end }} +{{- with $siteAuthor.github }}{{ printf "\n GitHub: @%s" . }}{{ end }} +{{- with $siteAuthor.twitter }}{{ printf "\n Twitter: @%s" . }}{{ end }} +{{- with $siteAuthor.location }}{{ printf "\n From: %s" . }}{{ end }} {{- end }} /* SITE */ @@ -15,3 +16,4 @@ Doctype: HTML5 Standards: HTML5, CSS3, Open Graph protocol, Schema.org Components: Hugo, Ed Theme, Lunr.js + Hugo version: {{ site.Hugo.Version }} diff --git a/layouts/_default/list.atom.xml b/layouts/_default/list.atom.xml index 67ff79b..edc133b 100644 --- a/layouts/_default/list.atom.xml +++ b/layouts/_default/list.atom.xml @@ -15,6 +15,7 @@ {{- $pages = $pages | first $limit -}} {{- $siteLastMod := partial "site-last-mod.html" . -}} +{{- $siteAuthor := partial "site-author.html" . -}} {{- safeHTML "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" }} <feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="{{ site.LanguageCode }}" xml:base="{{ site.BaseURL }}"> @@ -28,10 +29,10 @@ {{- end -}} {{- end }} {{ $logo := resources.Get (site.Params.assets.logo | default "/img/open-graph-logo.png") }}{{ $logo = $logo.Resize "96x96" }}<icon>{{ $logo.Permalink | absURL }}</icon> - <logo>{{ $logo.Permalink | absURL }}</logo>{{ with site.Author.name }} + <logo>{{ $logo.Permalink | absURL }}</logo>{{ with $siteAuthor.name }} <author> {{ printf `<name type="html"><![CDATA[%s]]></name>` . | safeHTML }} - {{ with site.Author.email }}<email>{{ . | html }}</email>{{ end }} + {{ with $siteAuthor.email }}<email>{{ . | html }}</email>{{ end }} </author>{{ end }}{{ with site.Params.Copyright }}{{ $copyright := replace . "{year}" now.Year }}{{ $copyright = replace $copyright "©" "©" }} <rights>{{ $copyright | plainify }}</rights>{{ end }} <generator uri="https://gohugo.io" version="{{ hugo.Version }}">Hugo</generator>{{ if ne $siteLastMod "" }} diff --git a/layouts/_default/list.feed.xml b/layouts/_default/list.feed.xml index 2bc3cb7..ae4366b 100644 --- a/layouts/_default/list.feed.xml +++ b/layouts/_default/list.feed.xml @@ -15,6 +15,7 @@ {{- $pages = $pages | first $limit -}} {{- $siteLastMod := partial "site-last-mod.html" . -}} +{{- $siteAuthor := partial "site-author.html" . -}} {{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }} <rss version="2.0" @@ -47,7 +48,7 @@ {{- end -}} {{- end }} {{ with site.Params.description }}{{ printf `<description type="html"><![CDATA[%s]]></description>` . | safeHTML }}{{ end }} - <generator>Hugo {{ hugo.Version }}</generator>{{ with site.Author.name }} + <generator>Hugo {{ hugo.Version }}</generator>{{ with $siteAuthor.name }} {{ printf `<dc:creator type="html"><![CDATA[%s]]></dc:creator>` . | safeHTML }}{{ end }}{{ with site.LanguageCode }} <language>{{ . }}</language>{{ end }}{{ with site.Params.Copyright }}{{ $copyright := replace . "{year}" now.Year }}{{ $copyright = replace $copyright "©" "©" }} <copyright>{{ $copyright | plainify }}</copyright>{{ end }}{{ if ne $siteLastMod "" }} diff --git a/layouts/_default/list.jsonfeed.json b/layouts/_default/list.jsonfeed.json index f6b89cc..29c9bf4 100644 --- a/layouts/_default/list.jsonfeed.json +++ b/layouts/_default/list.jsonfeed.json @@ -14,6 +14,8 @@ {{- $limit := site.Params.feedSize | default 25 -}} {{- $pages = $pages | first $limit -}} +{{- $siteAuthor := partial "site-author.html" . -}} + { "version": "https://jsonfeed.org/version/1.1", "title": {{ (partial "title.html" .) | htmlUnescape | jsonify }}, @@ -23,9 +25,9 @@ {{- $logo := resources.Get (site.Params.assets.logo | default "/img/open-graph-logo.png") }}{{ $logo = $logo.Resize "96x96" }} "icon": {{ $logo.Permalink | jsonify }}, "favicon": {{ $logo.Permalink | jsonify }}, - {{ with site.Author.name }}"authors": [ + {{ with $siteAuthor.name }}"authors": [ { - "name": {{ . | jsonify }}{{ with site.Author.twitter }}, + "name": {{ . | jsonify }}{{ with $siteAuthor.twitter }}, "url": {{ (printf "https://twitter.com/%s" . ) | jsonify }}{{ end }} } ],{{ end }} diff --git a/layouts/partials/author.html b/layouts/partials/author.html index 2bfddb3..4ca1209 100644 --- a/layouts/partials/author.html +++ b/layouts/partials/author.html @@ -1,3 +1,5 @@ +{{- $siteAuthor := partial "site-author.html" . -}} + {{- /* First, check for current page author(s) */}} {{- if .Params.author }} {{- $author_type := (printf "%T" .Params.author) }} @@ -7,6 +9,6 @@ {{- .Params.author }} {{- end }} {{- /* Otherwise, get site authors */}} -{{- else if site.Author.name }} - {{- site.Author.name }} +{{- else if $siteAuthor.name }} + {{- $siteAuthor.name }} {{- end -}} diff --git a/layouts/partials/schema.org/article.html b/layouts/partials/schema.org/article.html index fcec66b..f4112b6 100644 --- a/layouts/partials/schema.org/article.html +++ b/layouts/partials/schema.org/article.html @@ -13,6 +13,8 @@ {{- $logo := resources.Get (site.Params.assets.logo | default "/img/open-graph-logo.png") -}} {{- $logo = $logo.Resize "96x96" }} +{{- $siteAuthor := partial "site-author.html" . }} + <script type="application/ld+json" id="schema-data"> { "@context": "https://schema.org", @@ -51,10 +53,10 @@ ], {{- end }} {{- else }} - {{- with site.Author.name }} + {{- with $siteAuthor.name }} "author": { "@type": "Person", - "name": {{ . }}{{ with site.Author.twitter }}, + "name": {{ . }}{{ with $siteAuthor.twitter }}, "url": "https://twitter.com/{{ . }}"{{ end }} }, {{- end }} diff --git a/layouts/partials/site-author.html b/layouts/partials/site-author.html new file mode 100644 index 0000000..1ddd06c --- /dev/null +++ b/layouts/partials/site-author.html @@ -0,0 +1,34 @@ +{{- /* + +This partial is used to get the site author information. + +In Hugo v0.124.0, the site.Author variable was deprecated. Instead, it is recommended to use +the "author" parameters in the site configuration file. + +This partial checks for the presence of author information in both site.Author and site.Params.author. +If both are present, preference is given to site.Params.author. + +The result is stored in the $siteAuthor variable and returned by the partial. + +Usage: + + {{ $siteAuthor := partial "site-author.html" . }} + + {{ with $siteAuthor.name }} {{ . }} {{ end }} + {{ with $siteAuthor.email }} {{ . }} {{ end }} + {{ with $siteAuthor.github }} {{ . }} {{ end }} + {{ with $siteAuthor.twitter }} {{ . }} {{ end }} + {{ with $siteAuthor.location }} {{ . }} {{ end }} + +For more information, see: https://github.com/gohugoio/hugo/releases/tag/v0.124.0 +*/ -}} + +{{- $siteAuthor := dict "name" "" "email" "" "github" "" "twitter" "" "location" "" -}} + +{{- if site.Params.author -}} + {{- $siteAuthor = merge $siteAuthor site.Params.author -}} +{{- else if site.Author -}} + {{- $siteAuthor = merge $siteAuthor site.Author -}} +{{- end -}} + +{{- return $siteAuthor -}} diff --git a/tests/feed-atom.spec.js b/tests/feed-atom.spec.js new file mode 100644 index 0000000..7e23328 --- /dev/null +++ b/tests/feed-atom.spec.js @@ -0,0 +1,74 @@ +'use strict'; + +// @ts-check +const { test, expect } = require('@playwright/test'); +const jsdom = require('jsdom'); +const { JSDOM } = jsdom; + +test('atom feed has correct updated field', async ({ page }) => { + await page.goto('/feeds/feed.atom.xml'); + + // Get the content of the page + const content = await page.content(); + + // Create a new JSDOM instance + const dom = new JSDOM(content, { contentType: 'text/xml' }); + + // Get the global window object + const { window } = dom; + + // Get the updated field + const updatedField = window.document.querySelector('feed > updated'); + + // Check if the updated field exists + expect(updatedField).not.toBeNull(); + + // Check if the updated field is not empty + expect(updatedField.textContent).not.toBe(''); + + // Check if the updated field has the correct format + const dateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:Z|[+-]\d{2}:\d{2})$/; + expect(updatedField.textContent).toMatch(dateRegex); +}); + +test('atom feed has correct author information', async ({ page }) => { + await page.goto('/feeds/feed.atom.xml'); + + // Get the content of the page + const content = await page.content(); + + // Create a new JSDOM instance + const dom = new JSDOM(content, { contentType: 'text/xml' }); + + // Get the global window object + const { window } = dom; + + // Get the author element + const authorElement = window.document.querySelector('feed > author'); + + // Check if the author element exists + expect(authorElement).not.toBeNull(); + + // Get the name element + const nameElement = authorElement.querySelector('name'); + + // Check if the name element exists + expect(nameElement).not.toBeNull(); + + // Check if the name element has the correct type attribute + expect(nameElement.getAttribute('type')).toBe('html'); + + // Check if the name element has the correct text content + expect(nameElement.textContent).not.toBeNull(); + expect(nameElement.textContent.trim()).not.toBe(''); + + // Get the email element + const emailElement = authorElement.querySelector('email'); + + // Check if the email element exists + expect(emailElement).not.toBeNull(); + + // Check if the email element has the correct text content + expect(emailElement.textContent).not.toBeNull(); + expect(emailElement.textContent.trim()).not.toBe(''); +}); diff --git a/tests/feeds.spec.js b/tests/feed-rss.spec.js index e3291c3..2927140 100644 --- a/tests/feeds.spec.js +++ b/tests/feed-rss.spec.js @@ -5,8 +5,8 @@ const { test, expect } = require('@playwright/test'); const jsdom = require('jsdom'); const { JSDOM } = jsdom; -test('atom feed has correct updated field', async ({ page }) => { - await page.goto('/feeds/feed.atom.xml'); +test('rss feed has correct lastBuildDate field', async ({ page }) => { + await page.goto('/feeds/feed.rss.xml'); // Get the content of the page const content = await page.content(); @@ -17,21 +17,21 @@ test('atom feed has correct updated field', async ({ page }) => { // Get the global window object const { window } = dom; - // Get the updated field - const updatedField = window.document.querySelector('feed > updated'); + // Get the lastBuildDate field + const lastBuildDateField = window.document.querySelector('rss > lastBuildDate'); - // Check if the updated field exists - expect(updatedField).not.toBeNull(); + // Check if the lastBuildDate field exists + expect(lastBuildDateField).not.toBeNull(); - // Check if the updated field is not empty - expect(updatedField.textContent).not.toBe(''); + // Check if the lastBuildDate field is not empty + expect(lastBuildDateField.textContent.trim()).not.toBe(''); - // Check if the updated field has the correct format - const dateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:Z|[+-]\d{2}:\d{2})$/; - expect(updatedField.textContent).toMatch(dateRegex); + // Check if the lastBuildDate field has the correct format + const dateRegex = /^[A-Za-z]{3}, \d{2} [A-Za-z]{3} \d{4} \d{2}:\d{2}:\d{2} [+-]\d{4}$/; + expect(lastBuildDateField.textContent).toMatch(dateRegex); }); -test('rss feed has correct lastBuildDate field', async ({ page }) => { +test('rss feed has correct author information', async ({ page }) => { await page.goto('/feeds/feed.rss.xml'); // Get the content of the page @@ -43,16 +43,16 @@ test('rss feed has correct lastBuildDate field', async ({ page }) => { // Get the global window object const { window } = dom; - // Get the lastBuildDate field - const lastBuildDateField = window.document.querySelector('rss > lastBuildDate'); + // Get the dc:creator element + const creatorElement = window.document.querySelector('rss > dc\\:creator'); - // Check if the lastBuildDate field exists - expect(lastBuildDateField).not.toBeNull(); + // Check if the dc:creator element exists + expect(creatorElement).not.toBeNull(); - // Check if the lastBuildDate field is not empty - expect(lastBuildDateField.textContent.trim()).not.toBe(''); + // Check if the dc:creator element has the correct type attribute + expect(creatorElement.getAttribute('type')).toBe('html'); - // Check if the lastBuildDate field has the correct format - const dateRegex = /^[A-Za-z]{3}, \d{2} [A-Za-z]{3} \d{4} \d{2}:\d{2}:\d{2} [+-]\d{4}$/; - expect(lastBuildDateField.textContent).toMatch(dateRegex); + // Check if the dc:creator element has the correct text content + expect(creatorElement.textContent).not.toBeNull(); + expect(creatorElement.textContent.trim()).not.toBe(''); }); diff --git a/tests/humans.spec.js b/tests/humans.spec.js new file mode 100644 index 0000000..2acf7e0 --- /dev/null +++ b/tests/humans.spec.js @@ -0,0 +1,39 @@ +'use strict'; + +// @ts-check +const { test, expect } = require('@playwright/test'); + +test('humans.txt contains expected information', async ({ page }) => { + await page.goto('/humans.txt'); + + // Get the content of the page + const content = await page.content(); + + // Define the expected fields + const expectedFields = [ + 'Author:', + 'Contact:', + 'GitHub:', + 'Twitter:', + 'From:', + 'Last update:', + 'Language:', + 'Doctype:', + 'Standards:', + 'Components:', + 'Hugo version:' + ]; + + // Check if each expected field is present in the content + for (const field of expectedFields) { + expect(content).toContain(field); + } + + // Check if the content contains non-empty values for each field + for (const field of expectedFields) { + const regex = new RegExp(`${field}\\s+(.+)`, 'g'); + const match = regex.exec(content); + expect(match).not.toBeNull(); + expect(match[1].trim()).not.toBe(''); + } +}); |
