فهرست منبع

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
George Cushen 6 سال پیش
والد
کامیت
88e0459e68

+ 0 - 0
exampleSite/content/author/admin/_index.md → exampleSite/content/authors/admin/_index.md


+ 0 - 0
exampleSite/content/author/admin/avatar.jpg → exampleSite/content/authors/admin/avatar.jpg


+ 2 - 1
exampleSite/content/home/about.md

@@ -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"
 +++

+ 11 - 9
layouts/author/list.html → layouts/authors/list.html

@@ -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" . }}

+ 4 - 10
layouts/author/terms.html → layouts/authors/terms.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
layouts/index.json

@@ -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
layouts/partials/header.html

@@ -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
layouts/partials/page_author.html

@@ -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
layouts/partials/page_metadata_authors.html

@@ -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
layouts/partials/widgets/about.html

@@ -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">