Skip to content

Commit

Permalink
Move site author configuration to params
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeyklay committed Apr 14, 2024
1 parent 77b73fc commit 23d7728
Show file tree
Hide file tree
Showing 13 changed files with 219 additions and 44 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
7 changes: 0 additions & 7 deletions exampleSite/config/_default/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,6 @@ sitemap:
filename: sitemap.xml
priority: 0.5

author:
name: John Doe
email: [email protected]
github: john_doe
twitter: john_doe
location: 'Kyiv, Ukraine'

# For more see https://gohugo.io/getting-started/configuration-markup/
markup:
defaultMarkdownHandler: goldmark
Expand Down
11 changes: 9 additions & 2 deletions exampleSite/config/_default/params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ keywords:

# A "copyright"-line to be added to RSS/Atom files.
# "&copy;" and "{year}" will be replaced by © and the current year.
copyright: 'Copyright &copy; 2019-{year} John Doe'
copyright: 'Copyright &copy; 2019-{year} Serghei Iakovlev'

# Colour scheme. Options: red, orange, magenta, cyan, blue, brown
colorScheme: ''
Expand Down Expand Up @@ -88,6 +88,13 @@ seo:
# you have to set `googleAnalytics` param in config.yaml file.
anonymizeIp: true

author:
name: Serghei Iakovlev
email: [email protected]
github: sergeyklay
twitter: egreps
location: 'Wrocław, Poland'

social:
# Array of Facebook Page Admin IDs for Domain Insights
facebookAdminIds: []
Expand All @@ -96,7 +103,7 @@ social:
facebookId: ''

# Twitter username for the website
twitter: john_doe
twitter: egreps

# Configure search engine
search:
Expand Down
12 changes: 7 additions & 5 deletions layouts/_default/home.humanstxt.txt
Original file line number Diff line number Diff line change
@@ -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 */
Expand All @@ -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 }}
5 changes: 3 additions & 2 deletions layouts/_default/list.atom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}">
Expand All @@ -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 "&copy;" "©" }}
<rights>{{ $copyright | plainify }}</rights>{{ end }}
<generator uri="https://gohugo.io" version="{{ hugo.Version }}">Hugo</generator>{{ if ne $siteLastMod "" }}
Expand Down
3 changes: 2 additions & 1 deletion layouts/_default/list.feed.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 "&copy;" "©" }}
<copyright>{{ $copyright | plainify }}</copyright>{{ end }}{{ if ne $siteLastMod "" }}
Expand Down
6 changes: 4 additions & 2 deletions layouts/_default/list.jsonfeed.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 }},
Expand All @@ -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 }}
Expand Down
6 changes: 4 additions & 2 deletions layouts/partials/author.html
Original file line number Diff line number Diff line change
@@ -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) }}
Expand All @@ -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 -}}
6 changes: 4 additions & 2 deletions layouts/partials/schema.org/article.html
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 }}
Expand Down
34 changes: 34 additions & 0 deletions layouts/partials/site-author.html
Original file line number Diff line number Diff line change
@@ -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 -}}
74 changes: 74 additions & 0 deletions tests/feed-atom.spec.js
Original file line number Diff line number Diff line change
@@ -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('');
});
42 changes: 21 additions & 21 deletions tests/feeds.spec.js → tests/feed-rss.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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
Expand All @@ -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('');
});
Loading

0 comments on commit 23d7728

Please sign in to comment.