fix: Hugo 0.54+ breaks links to user profiles with non-ASCII usernames

* check if the Hugo generated author profile URL is valid
  * works around the Hugo bug, preventing invalid links
* rename `author` folder to `authors`
  * no need to GetPage authors/x and then GetPage author/x to check if
    user account was created
  * can just rename the folder and use `if .File` instead
  * more aligned with how Hugo's taxonomy system was designed
* refactor all author code

BREAKING CHANGE: rename `author` folder to `authors`

Fix #1064
This commit is contained in:
George Cushen committed 2019-05-05 14:13:49 +01:00
1 parent a40d7af8b8
commit 88e0459e68
10 files changed
+80 -88

No files matched your search

+2 -1
View File
@@ -8,6 +8,7 @@ weight = 20 # Order that this section will appear in.
title = "Biography"
# Choose the user profile to display
# This should be the username of a profile in your `content/author/` folder.
# This should be the username of a profile in your `content/authors/` folder.
# See https://sourcethemes.com/academic/docs/get-started/#introduce-yourself
author = "admin"
+++
@@ -1,21 +1,24 @@
{{/* Author profile page. */}}
{{ partial "header.html" . }}
{{ partial "navbar.html" . }}
{{/* Just display author name as title if user profile unavailable. */}}
{{ if not (site.GetPage (printf "/author/%s" (urlize .Title))) }}
{{/* If an account has not been created for this user, just display their name as the title. */}}
{{ if not .File }}
<div class="universal-wrapper pt-3">
<h1 itemprop="name">{{ .Title }}</h1>
</div>
{{ end }}
<section id="about" class="pt-5">
<section id="profile-page" class="pt-5">
<div class="container">
{{/* Only show About widget if a profile has been configured for this user. */}}
{{ $widget := "widgets/about.html" }}
{{ $params := dict "root" $ "page" . "author" .Title }}
{{ with site.GetPage (printf "/author/%s" (urlize .Title)) }}
{{/* Show the About widget if an account exists for this user. */}}
{{ if .File }}
{{ $widget := "widgets/about.html" }}
{{ $slug := delimit (last 1 (split (trim .File.Dir "/") "/")) "" }}{{/* Alternatively, use `index .Params.authors 0` */}}
{{ $params := dict "root" $ "page" . "author" $slug }}
{{ partial $widget $params }}
{{ end }}
{{end}}
{{ $query := where .Pages ".IsNode" false }}
{{ $count := len $query }}
@@ -35,6 +38,5 @@
{{ end }}
</section>
<!-- Page Footer -->
{{ partial "footer_container.html" . }}
{{ partial "footer.html" . }}
@@ -1,3 +1,5 @@
{{/* List of all authors. */}}
{{ partial "header.html" . }}
{{ partial "navbar.html" . }}
@@ -11,16 +13,8 @@
<ul>
{{ $paginator := .Paginate .Data.Pages }}
{{ range $k, $v := $paginator.Pages }}
{{ $person_page_path := (printf "/author/%s" (urlize $v.Title)) }}
{{ $person_page := site.GetPage $person_page_path }}
{{ $name := "" }}
{{ if $person_page }}
{{ $person := $person_page.Params }}
{{ $name = $person.name }}
{{ else }}
{{ $name = $v.Title | plainify }}
{{ end }}
<li><a href="{{ $v.Permalink }}">{{ $name }}</a></li>
{{ $name := $v.Params.name | default ($v.Title|plainify) }}
<li><a href="{{$v.Permalink}}">{{$name}}</a></li>
{{ end }}
</ul>
+2 -2
View File
@@ -3,8 +3,8 @@
{{- $pages := site.RegularPages -}}
{{- /* Add the index page of docs separately since it's not in RegularPages above. */ -}}
{{- $pages := $pages | union (where (where site.Pages "Kind" "section") "Type" "docs") -}}
{{- /* Add author pages to index so their bios can be searched. Hide empty `/author/` node. */ -}}
{{- $pages := $pages | union (where (where site.Pages "Section" "author") "Params.name" "!=" nil) -}}
{{- /* Add author pages to index so their bios can be searched. Hide empty `/authors/` node. */ -}}
{{- $pages := $pages | union (where (where site.Pages "Section" "authors") "Params.name" "!=" nil) -}}
{{- range $pages -}}
{{- /* Do not index drafts or private pages. */ -}}
+1 -1
View File
@@ -13,7 +13,7 @@
{{ $superuser_name := "" }}
{{ $superuser_username := "" }}
{{ $superuser_role := "" }}
{{ range first 1 (where (where site.Pages "Section" "author") "Params.superuser" true) }}
{{ range first 1 (where (where site.Pages "Section" "authors") "Params.superuser" true) }}
{{ $superuser_name = .Params.name }}
{{ $superuser_username = delimit (last 1 (split (substr .File.Dir 0 -1) "/")) "" }}
{{ $superuser_role = .Params.role }}
+45 -44
View File
@@ -1,59 +1,60 @@
{{/* Author profile box */}}
{{ if not (or (eq site.Params.profile false) (eq .Params.profile false)) }}
{{/* Display superuser if superuser exists and page authors are not explicitly specified. */}}
{{/* Otherwise, display first author if a profile for them exists. */}}
{{ $author_urlize := "" }}
{{ $author_urlized := "" }}
{{ if and (not .Params.authors) (.Scratch.Get "superuser_username") }}
{{ $author_urlize = (.Scratch.Get "superuser_username") }}
{{ $author_urlized = (.Scratch.Get "superuser_username") }}
{{ else }}
{{ $first_author := "" }}
{{ if .Params.authors }}
{{ $first_author = index .Params.authors 0 }}
{{ end }}
{{ $author_urlize = urlize $first_author }}
{{ $author_urlized = urlize $first_author }}
{{ end }}
{{ $person_page_path := (printf "/author/%s" $author_urlize) }}
{{ $person_page := site.GetPage $person_page_path }}
{{ with $person_page }}
{{ $link := printf "/authors/%s" $author_urlize | relURL }}
{{ $avatar := ($person_page.Resources.ByType "image").GetMatch "*avatar*" }}
<div class="media author-card" itemscope itemtype="http://schema.org/Person">
{{ if and site.Params.gravatar .Params.email }}
<img class="portrait mr-3" src="https://s.gravatar.com/avatar/{{ md5 .Params.email }}?s=200')" itemprop="image" alt="Avatar">
{{ else if $avatar }}
{{ $avatar_image := $avatar.Fill "250x250 Center" }}
<img class="portrait mr-3" src="{{ $avatar_image.RelPermalink }}" itemprop="image" alt="Avatar">
{{ end }}
{{ $taxonomy := "authors" }}
{{ $profile_page := site.GetPage (printf "/%s/%s" $taxonomy $author_urlized) }}
{{ with $profile_page }}
{{ $avatar := (.Resources.ByType "image").GetMatch "*avatar*" }}
<div class="media author-card" itemscope itemtype="http://schema.org/Person">
{{ if and site.Params.gravatar .Params.email }}
<img class="portrait mr-3" src="https://s.gravatar.com/avatar/{{ md5 .Params.email }}?s=200')" itemprop="image" alt="Avatar">
{{ else if $avatar }}
{{ $avatar_image := $avatar.Fill "250x250 Center" }}
<img class="portrait mr-3" src="{{ $avatar_image.RelPermalink }}" itemprop="image" alt="Avatar">
{{ end }}
<div class="media-body">
<h5 class="card-title" itemprop="name"><a href="{{ $link }}">{{ .Params.name }}</a></h5>
{{ with .Params.role }}<h6 class="card-subtitle">{{.}}</h6>{{end}}
{{ with .Params.bio }}<p class="card-text" itemprop="description">{{. | markdownify | emojify}}</p>{{end}}
<ul class="network-icon" aria-hidden="true">
{{ range .Params.social }}
{{ $pack := or .icon_pack "fas" }}
{{ $pack_prefix := $pack }}
{{ if in (slice "fab" "fas" "far" "fal") $pack }}
{{ $pack_prefix = "fa" }}
{{ end }}
{{ $link := .link }}
{{ $scheme := (urls.Parse $link).Scheme }}
{{ $target := "" }}
{{ if not $scheme }}
{{ $link = .link | relLangURL }}
{{ else if in (slice "http" "https") $scheme }}
{{ $target = "target=\"_blank\" rel=\"noopener\"" }}
{{ end }}
<li>
<a itemprop="sameAs" href="{{ $link | safeURL }}" {{ $target | safeHTMLAttr }}>
<i class="{{ $pack }} {{ $pack_prefix }}-{{ .icon }}"></i>
</a>
</li>
{{ end }}
</ul>
<div class="media-body">
<h5 class="card-title" itemprop="name"><a href="{{.RelPermalink}}">{{.Params.name}}</a></h5>
{{ with .Params.role }}<h6 class="card-subtitle">{{. | markdownify | emojify}}</h6>{{end}}
{{ with .Params.bio }}<p class="card-text" itemprop="description">{{. | markdownify | emojify}}</p>{{end}}
<ul class="network-icon" aria-hidden="true">
{{ range .Params.social }}
{{ $pack := or .icon_pack "fas" }}
{{ $pack_prefix := $pack }}
{{ if in (slice "fab" "fas" "far" "fal") $pack }}
{{ $pack_prefix = "fa" }}
{{ end }}
{{ $link := .link }}
{{ $scheme := (urls.Parse $link).Scheme }}
{{ $target := "" }}
{{ if not $scheme }}
{{ $link = .link | relLangURL }}
{{ else if in (slice "http" "https") $scheme }}
{{ $target = "target=\"_blank\" rel=\"noopener\"" }}
{{ end }}
<li>
<a itemprop="sameAs" href="{{ $link | safeURL }}" {{ $target | safeHTMLAttr }}>
<i class="{{ $pack }} {{ $pack_prefix }}-{{ .icon }}"></i>
</a>
</li>
{{end}}
</ul>
</div>
</div>
</div>
{{end}}
{{end}}
{{end}}{{/* Profile page block */}}
{{end}}{{/* Show profile block */}}
+12 -18
View File
@@ -1,23 +1,17 @@
{{/* If `authors` is set and is not empty. */}}
{{ if $.Params.authors }}
{{ $authorLen := len $.Params.authors }}
{{ if gt $authorLen 0 }}
{{ range $k, $v := $.Params.authors -}}
<span itemscope itemprop="author" itemtype="http://schema.org/Person">
<span itemprop="name">
{{ $link := (site.GetPage (printf "/authors/%s" (urlize $v))).RelPermalink }}
{{/* Display author list. */}}
{{ $person_page_path := (printf "/author/%s" (urlize $v)) }}
{{ $person_page := site.GetPage $person_page_path }}
{{ if $person_page }}
{{ $person := $person_page.Params }}
{{- printf "<a href=\"%s\">%s</a>" $link $person.name | safeHTML -}}
{{ $taxonomy := "authors" }}
{{ with .Param $taxonomy }}
{{ range $index, $value := . }}
{{- $profile_page := site.GetPage (printf "/%s/%s" $taxonomy (. | urlize)) -}}
{{- $name := $profile_page.Params.name | default ($value|markdownify) -}}
{{- if gt $index 0 }}, {{ end -}}
<span itemprop="author name" itemtype="http://schema.org/Person">
{{- with $profile_page -}}
<a href="{{.RelPermalink}}">{{$name}}</a>
{{- else -}}
{{- printf "<a href=\"%s\">%s</a>" $link ($v | markdownify) | safeHTML -}}
{{$name}}
{{- end -}}
</span>{{- /* This comment removes whitespace */ -}}
</span>
{{- if lt $k (sub $authorLen 1) -}}, {{ end }}
{{ end }}
{{ end }}
{{- end -}}
{{ end }}
+3 -3
View File
@@ -8,10 +8,10 @@
{{ $author = $page.Params.author }}
{{end}}
{{ $person_page_path := (printf "/author/%s" (urlize $author)) }}
{{ $person_page_path := (printf "/authors/%s" (urlize $author)) }}
{{ $person_page := site.GetPage $person_page_path }}
{{ if not $person_page }}
{{ errorf "Could not find an author page at `%s`. Please check the value of `author` in your About widget and create an associated author page if one does not already exist." $person_page_path }}
{{ errorf "Could not find an author page at `%s`. Please check the value of `author` in your About widget and create an associated author page if one does not already exist. See https://sourcethemes.com/academic/docs/page-builder/#about " $person_page_path }}
{{end}}
{{ $person := $person_page.Params }}
{{ $avatar := ($person_page.Resources.ByType "image").GetMatch "*avatar*" }}
@@ -30,7 +30,7 @@
<div class="portrait-title">
<h2 itemprop="name">{{ $person.name }}</h2>
{{ with $person.role }}<h3 itemprop="jobTitle">{{ . }}</h3>{{ end }}
{{ with $person.role }}<h3 itemprop="jobTitle">{{ . | markdownify | emojify }}</h3>{{ end }}
{{ range $person.organizations }}
<h3 itemprop="worksFor" itemscope itemtype="http://schema.org/Organization">