Переглянути джерело

feat(user): add author profile system

- Add author taxonomy to config
- Restructure user data
- Add user profile pages
- Refactor author profile box
- Refactor author link in page metadata to point to author profile page
- Enable About widget to be re-used for different users

BREAKING CHANGES
See issue below and v4 release note for details

See #752
George Cushen 6 роки тому
батько
коміт
ab7e896227

+ 46 - 101
exampleSite/config.toml

@@ -49,60 +49,6 @@ enableGitInfo = false
   extensions = ["backslashLineBreak"]
 
 [params]
-  # AUTHOR SETUP
-
-  # Your details.
-  name = "Lena Smith"
-  role = "Professor of Artificial Intelligence"
-
-  # Organizations/Affiliations.
-  #   Separate multiple entries with a comma, using the form: `[ {name="Org1", url=""}, {name="Org2", url=""} ]`.
-  organizations = [ { name = "Stanford University", url = "" } ]
-
-  gravatar = false  # Get your avatar from Gravatar.com? (true/false)
-  avatar = "portrait.jpg"  # Specify an avatar image (in `static/img/` folder) or delete value to disable avatar.
-
-  # Details for the Contact Widget
-  email = "test@example.org"
-  address = "Building 1 Room 1, Stanford University, California, 90210, USA"
-  office_hours = """
-  Monday 10:00 to 13:00<br>
-  Wednesday 09:00 to 10:00<br>
-  Otherwise email to book an appointment
-  """
-  phone = "888 888 88 88"
-  skype = "echo123"
-  telegram = ""
-  keybase = ""  # Your keybase.io username.
-
-  # Enter an optional link for booking appointments (e.g. calendly.com).
-  appointment_url = ""
-
-  # Discussion link (e.g. link to a forum, mailing list, or chat).
-  #   Uncomment line below to use.
-  #   discussion = { name = "Discuss", url = "https://discourse.gohugo.io" }
-
-  # Enable/disable map in Contact widget.
-  # To show your address on a map in the contact widget, you need to enter your latitude, longitude and choose
-  # a map provider below.
-  # To use Google Maps, set `map = 1` and enter your API key that can be obtained here:
-  #   https://developers.google.com/maps/documentation/javascript/get-api-key
-  # To use OpenStreetMap tiles, set `map = 2`.
-  # To use OpenStreetMap on a high traffic site, set `map = 3` and enter your API key that can be obtained here:
-  #   https://www.mapbox.com/studio/account/tokens
-  # To get your coordinates, right-click on Google Maps and choose "What's here?". The coords will show up at the bottom.
-  #
-  # Map provider:
-  #   0: No map
-  #   1: Google Maps
-  #   2: OpenStreetMap (Mapnik)
-  #   3: OpenStreetMap (Mapbox)
-  map = 0
-  map_api_key = ""
-  latitude = "37.4275"
-  longitude = "-122.1697"
-  zoom = 15
-
   # SITE SETUP
 
   # Color theme.
@@ -184,11 +130,55 @@ enableGitInfo = false
   #   Anonymize IP in Google Analytics (if enabled)
   privacy_pack = false
 
+  # Get user avatars from Gravatar.com? (true/false)
+  gravatar = false
+
   # Link custom CSS and JS assets
   #   (relative to /static/css and /static/js respectively)
   custom_css = []
   custom_js  = []
 
+  # Contact Widget setup
+    email = "test@example.org"
+    address = "Building 1 Room 1, Stanford University, California, 90210, USA"
+    office_hours = """
+    Monday 10:00 to 13:00<br>
+    Wednesday 09:00 to 10:00<br>
+    Otherwise email to book an appointment
+    """
+    phone = "888 888 88 88"
+    skype = "echo123"
+    telegram = ""
+    keybase = ""  # Your keybase.io username.
+
+    # Enter an optional link for booking appointments (e.g. calendly.com).
+    appointment_url = ""
+
+    # Discussion link (e.g. link to a forum, mailing list, or chat).
+    #   Uncomment line below to use.
+    #   discussion = { name = "Discuss", url = "https://discourse.gohugo.io" }
+
+    # Enable/disable map in Contact widget.
+    # To show your address on a map in the contact widget, you need to enter your latitude, longitude and choose
+    # a map provider below.
+    # To use Google Maps, set `map = 1` and enter your API key that can be obtained here:
+    #   https://developers.google.com/maps/documentation/javascript/get-api-key
+    # To use OpenStreetMap tiles, set `map = 2`.
+    # To use OpenStreetMap on a high traffic site, set `map = 3` and enter your API key that can be obtained here:
+    #   https://www.mapbox.com/studio/account/tokens
+    # To get your coordinates, right-click on Google Maps and choose "What's here?". The coords will show up at the bottom.
+    #
+    # Map provider:
+    #   0: No map
+    #   1: Google Maps
+    #   2: OpenStreetMap (Mapnik)
+    #   3: OpenStreetMap (Mapbox)
+    map = 0
+    map_api_key = ""
+    latitude = "37.4275"
+    longitude = "-122.1697"
+    zoom = 15
+
   # Publication types.
   #   Used to categorize publications.
   #   The index of the publication type in the list is used as its unique numerical identifier.
@@ -242,51 +232,6 @@ enableGitInfo = false
     #   2 = Stream
     talk_format = 2
 
-  # Social/Academic Networking
-  #
-  # Icon pack "fab" includes the following social network icons:
-  #
-  #   twitter, weibo, linkedin, github, facebook, pinterest, google-plus,
-  #   youtube, instagram, soundcloud
-  #
-  #   For email icon, use "fas" icon pack, "envelope" icon, and
-  #   "mailto:your@email.com" as the link.
-  #
-  #   Full list: https://fontawesome.com/icons
-  #
-  # Icon pack "ai" includes the following academic icons:
-  #
-  #   cv, google-scholar, arxiv, orcid, researchgate, mendeley
-  #
-  #   Full list: https://jpswalsh.github.io/academicons/
-
-  [[params.social]]
-    icon = "envelope"
-    icon_pack = "fas"
-    link = "#contact"  # For a direct email link, use "mailto:test@example.org".
-
-  [[params.social]]
-    icon = "twitter"
-    icon_pack = "fab"
-    link = "https://twitter.com/GeorgeCushen"
-
-  [[params.social]]
-    icon = "google-scholar"
-    icon_pack = "ai"
-    link = "https://scholar.google.co.uk/citations?user=sIwtMXoAAAAJ"
-
-  [[params.social]]
-    icon = "github"
-    icon_pack = "fab"
-    link = "https://github.com/gcushen"
-
-  # Link to a PDF of your resume/CV from the About widget.
-  # To enable, copy your resume/CV to `static/files/cv.pdf` and uncomment the lines below.
-  # [[params.social]]
-  #   icon = "cv"
-  #   icon_pack = "ai"
-  #   link = "files/cv.pdf"
-
 # Navigation Links
 #   To link a homepage widget, specify the URL as a hash `#` followed by the filename of the
 #     desired widget in your `content/home/` folder.
@@ -353,6 +298,7 @@ enableGitInfo = false
   tag = "tags"
   category = "categories"
   publication_type = "publication_types"
+  author = "authors"
 
 # Languages
 #   Create a [languages.X] block for each language you want, where X is the language ID.
@@ -367,8 +313,7 @@ enableGitInfo = false
 #  languageCode = "zh-Hans"
 #  title = "Chinese website title..."
 #  [languages.zh.params]
-#    name = "Your name in Chinese..."
-#    role = "Your role in Chinese..."
+#    description = "Site description in Chinese..."
 #  [[languages.zh.menu.main]]
 #    name = "Wo"
 #    url = "#about"

+ 93 - 0
exampleSite/content/author/admin/_index.md

@@ -0,0 +1,93 @@
++++
+# Display name
+name = "Nelson Bighetti"
+
+# Is this the primary user of the site?
+superuser = true
+
+# Role/position
+role = "Professor of Artificial Intelligence"
+
+# Organizations/Affiliations
+#   Separate multiple entries with a comma, using the form: `[ {name="Org1", url=""}, {name="Org2", url=""} ]`.
+organizations = [ { name = "Stanford University", url = "" } ]
+
+# Short bio (displayed in user profile at end of posts)
+bio = "My research interests include distributed robotics, mobile computing and programmable matter."
+
+# Enter email to display Gravatar (if Gravatar enabled in Config)
+email = ""
+
+# List (academic) interests or hobbies
+interests = [
+  "Artificial Intelligence",
+  "Computational Linguistics",
+  "Information Retrieval"
+]
+
+# List qualifications (such as academic degrees)
+[[education.courses]]
+  course = "PhD in Artificial Intelligence"
+  institution = "Stanford University"
+  year = 2012
+
+[[education.courses]]
+  course = "MEng in Artificial Intelligence"
+  institution = "Massachusetts Institute of Technology"
+  year = 2009
+
+[[education.courses]]
+  course = "BSc in Artificial Intelligence"
+  institution = "Massachusetts Institute of Technology"
+  year = 2008
+
+# Social/Academic Networking
+#
+# Icon pack "fab" includes the following social network icons:
+#
+#   twitter, weibo, linkedin, github, facebook, pinterest, google-plus,
+#   youtube, instagram, soundcloud
+#
+#   For email icon, use "fas" icon pack, "envelope" icon, and
+#   "mailto:your@email.com" as the link.
+#
+#   Full list: https://fontawesome.com/icons
+#
+# Icon pack "ai" includes the following academic icons:
+#
+#   cv, google-scholar, arxiv, orcid, researchgate, mendeley
+#
+#   Full list: https://jpswalsh.github.io/academicons/
+
+[[social]]
+  icon = "envelope"
+  icon_pack = "fas"
+  link = "#contact"  # For a direct email link, use "mailto:test@example.org".
+
+[[social]]
+  icon = "twitter"
+  icon_pack = "fab"
+  link = "https://twitter.com/GeorgeCushen"
+
+[[social]]
+  icon = "google-scholar"
+  icon_pack = "ai"
+  link = "https://scholar.google.co.uk/citations?user=sIwtMXoAAAAJ"
+
+[[social]]
+  icon = "github"
+  icon_pack = "fab"
+  link = "https://github.com/gcushen"
+
+# Link to a PDF of your resume/CV from the About widget.
+# To enable, copy your resume/CV to `static/files/cv.pdf` and uncomment the lines below.
+# [[social]]
+#   icon = "cv"
+#   icon_pack = "ai"
+#   link = "files/cv.pdf"
+
++++
+
+Nelson Bighetti is a professor of artificial intelligence at the Stanford AI Lab. His research interests include distributed robotics, mobile computing and programmable matter. He leads the Robotic Neurobiology group, which develops self-reconfiguring robots, systems of self-organizing robots, and mobile sensor networks.
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate. 

+ 0 - 0
exampleSite/static/img/portrait.jpg → exampleSite/content/author/admin/avatar.jpg


+ 7 - 34
exampleSite/content/home/about.md

@@ -1,40 +1,13 @@
 +++
 # About/Biography widget.
-widget = "about"
-active = true
+widget = "about"  # Do not modify this line!
+active = true  # Activate this widget? true/false
+weight = 5  # Order that this section will appear in.
 date = 2016-04-20T00:00:00
 
-# Order that this section will appear in.
-weight = 5
+title = "Biography"
 
-# List your academic interests.
-[interests]
-  interests = [
-    "Artificial Intelligence",
-    "Computational Linguistics",
-    "Information Retrieval"
-  ]
-
-# List your qualifications (such as academic degrees).
-[[education.courses]]
-  course = "PhD in Artificial Intelligence"
-  institution = "Stanford University"
-  year = 2012
-
-[[education.courses]]
-  course = "MEng in Artificial Intelligence"
-  institution = "Massachusetts Institute of Technology"
-  year = 2009
-
-[[education.courses]]
-  course = "BSc in Artificial Intelligence"
-  institution = "Massachusetts Institute of Technology"
-  year = 2008
- 
+# Choose the user profile to display
+# This should be the username of a profile in your `content/author/` folder.
+author = "Admin"
 +++
-
-# Biography
-
-Lena Smith is a professor of artificial intelligence at the Stanford AI Lab. Her research interests include distributed robotics, mobile computing and programmable matter. She leads the Robotic Neurobiology group, which develops self-reconfiguring robots, systems of self-organizing robots, and mobile sensor networks.
-
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate. 

+ 1 - 1
exampleSite/content/post/getting-started/index.md

@@ -7,7 +7,7 @@ lastmod = 2018-01-13T00:00:00
 draft = false
 
 # Authors. Comma separated list, e.g. `["Bob Smith", "David Jones"]`.
-authors = []
+authors = ["Admin"]
 
 tags = ["Academic"]
 summary = "Create a beautifully simple website or blog in under 10 minutes."

+ 29 - 0
layouts/author/list.html

@@ -0,0 +1,29 @@
+{{ partial "header.html" . }}
+{{ partial "navbar.html" . }}
+{{ partial "page_header.html" . }}
+
+<section id="about" class="home-section">
+  <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)) }}
+      {{ partial $widget $params }}
+    {{ end }}
+    <div class="article-widget">
+      <div class="hr-light"></div>
+      <h3>{{ i18n "related" }}</h3>
+      <ul>
+        {{ range .Pages }}
+        <li>
+          <a href="{{ .Permalink }}">{{ .Title }}</a>
+        </li>
+        {{ end }}
+      </ul>
+    </div>
+  </div>
+</section>
+
+<!-- Page Footer -->
+{{ partial "footer_container.html" . }}
+{{ partial "footer.html" . }}

+ 3 - 2
layouts/index.json

@@ -1,9 +1,10 @@
 {{- /* Generate the search index. */ -}}
 {{- $index := slice -}}
 {{- $pages := where .Site.RegularPages "Section" "!=" "home" -}}
+{{- /* 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") -}}
-{{- /* TODO: Add author pages to index so their bios can be searched. */ -}}
-{{- /* $pages := $pages | union (where (where .Site.Pages "Kind" "taxonomy") "taxonomyTerm" "author") */ -}}
+{{- /* Add author pages to index so their bios can be searched. */ -}}
+{{- $pages := $pages | union (where $.Site.Pages "Section" "author") -}}
 
 {{- range $pages -}}
   {{- /* Do not index drafts or private pages. */ -}}

+ 15 - 2
layouts/partials/header.html

@@ -7,9 +7,22 @@
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="generator" content="Source Themes Academic {{ .Site.Data.academic.version }}">
   {{ .Hugo.Generator }}
-  {{ with .Site.Params.name }}<meta name="author" content="{{ . }}">{{ end }}
 
   {{ $scr := .Scratch }}
+
+  {{/* Attempt to load superuser. */}}
+  {{ $superuser_name := "" }}
+  {{ $superuser_username := "" }}
+  {{ $superuser_role := "" }}
+  {{ range first 1 (where (where $.Site.Pages "Section" "author") "Params.superuser" true) }}
+    {{ $superuser_name = .Params.name }}
+    {{ $superuser_username = .File.ContentBaseName }}
+    {{ $superuser_role = .Params.role }}
+  {{ end }}
+  {{ $scr.Set "superuser_username" $superuser_username }}{{/* For access from page_author.html. */}}
+
+  {{ with $superuser_name }}<meta name="author" content="{{ . }}">{{ end }}
+
   {{/* Generate page description. */}}
   {{ $desc := "" }}
   {{ if .Params.summary }}
@@ -21,7 +34,7 @@
   {{ else if .Site.Params.description }}
     {{ $desc = .Site.Params.description }}
   {{ else }}
-    {{ $desc = .Site.Params.role }}
+    {{ $desc = $superuser_role }}
   {{ end }}
   <meta name="description" content="{{ $desc }}">
 

+ 27 - 13
layouts/partials/page_author.html

@@ -1,24 +1,38 @@
 {{ if not (or (eq .Site.Params.profile false) (eq .Params.profile false)) }}
 
-{{ $author := "" }}
-{{ if .Params.authors }}
-  {{ $author = index .Params.authors 0 }}
+{{/* Display superuser if superuser exists and page authors are not explicitly specified. */}}
+{{/* Otherwise, display first author if a profile for them exists. */}}
+
+{{ $author_urlize := "" }}
+{{ if and (not .Params.authors) (.Scratch.Get "superuser_username") }}
+  {{ $author_urlize = (.Scratch.Get "superuser_username") }}
+{{ else }}
+  {{ $first_author := "" }}
+  {{ if .Params.authors }}
+    {{ $first_author = index .Params.authors 0 }}
+  {{ end }}
+  {{ $author_urlize = urlize $first_author }}
 {{ end }}
 
-{{/* Display site author if page authors not explicitly specified or if first page author is site author. */}}
-{{ if or (not .Params.authors) (eq $author $.Site.Params.name) }}
+{{ $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 $.Site.Params.gravatar }}
-  <img class="portrait mr-3" src="https://s.gravatar.com/avatar/{{ md5 $.Site.Params.email }}?s=200')" itemprop="image" alt="Avatar">
-  {{ else if $.Site.Params.avatar }}
-  <img class="portrait mr-3" src="{{ (printf "img/%s" $.Site.Params.avatar) | relURL }}" itemprop="image" alt="Avatar">
+  {{ 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="{{ "/" | relLangURL }}">{{ $.Site.Params.name }}</a></h5>
-    {{ with $.Site.Params.role }}<h6 class="card-subtitle">{{.}}</h6>{{end}}
-    {{ with $.Site.Params.bio }}<p class="card-text" itemprop="description">{{. | markdownify | emojify}}</p>{{end}}
+    <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 $.Site.Params.social }}
+      {{ range .Params.social }}
       {{ $pack := or .icon_pack "fas" }}
       {{ $pack_prefix := $pack }}
       {{ if in (slice "fab" "fas" "far" "fal") $pack }}

+ 5 - 1
layouts/partials/page_metadata.html

@@ -8,7 +8,11 @@
   <div>
     {{ range $k, $v := $.Params.authors -}}
     <span itemscope itemprop="author" itemtype="http://schema.org/Person">
-      <span itemprop="name">{{- $v | markdownify -}}</span>
+      <span itemprop="name">
+        {{with $.Site.GetPage (printf "/authors/%s" $v) }}{{ printf "<a href=\"%s\">" .RelPermalink | safeHTML }}{{end}}
+        {{- $v | markdownify -}}
+        {{with $.Site.GetPage (printf "/authors/%s" $v) }}{{ printf "</a>" | safeHTML }}{{end}}
+      </span>
     </span>
     {{- if lt $k (sub $authorLen 1) -}}, {{ end }}
     {{ end }}

+ 31 - 21
layouts/partials/widgets/about.html

@@ -1,31 +1,38 @@
 {{ $ := .root }}
 {{ $page := .page }}
 
+{{ $author := "" }}
+{{ if .author }}
+  {{ $author = .author }}
+{{ else }}
+  {{ $author = $page.Params.author }}
+{{end}}
+
+{{ $person_page_path := (printf "/author/%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 }}
+{{end}}
+{{ $person := $person_page.Params }}
+{{ $avatar := ($person_page.Resources.ByType "image").GetMatch "*avatar*" }}
+
 <!-- About widget -->
 <div class="row" itemprop="author" itemscope itemtype="http://schema.org/Person" itemref="{{ if $.Site.Params.email }}person-email{{ end }}{{ if $.Site.Params.phone }} person-telephone{{ end }}{{ if $.Site.Params.address}} person-address{{ end }}">
   <div class="col-12 col-lg-4">
     <div id="profile">
 
       {{ if $.Site.Params.gravatar }}
-      <img class="portrait" src="https://s.gravatar.com/avatar/{{ md5 $.Site.Params.email }}?s=200')" itemprop="image" alt="Avatar">
-      {{ else if $.Site.Params.avatar }}
-      <img class="portrait" src="{{ (printf "img/%s" $.Site.Params.avatar) | relURL }}" itemprop="image" alt="Avatar">
+      <img class="portrait" src="https://s.gravatar.com/avatar/{{ md5 $person.email }}?s=200')" itemprop="image" alt="Avatar">
+      {{ else if $avatar }}
+      {{ $avatar_image := $avatar.Fill "250x250 Center" }}
+      <img class="portrait" src="{{ $avatar_image.RelPermalink }}" itemprop="image" alt="Avatar">
       {{ end }}
 
       <div class="portrait-title">
-        <h2 itemprop="name">{{ $.Site.Params.name }}</h2>
-        {{ with $.Site.Params.role }}<h3 itemprop="jobTitle">{{ . }}</h3>{{ end }}
+        <h2 itemprop="name">{{ $person.name }}</h2>
+        {{ with $person.role }}<h3 itemprop="jobTitle">{{ . }}</h3>{{ end }}
 
-        {{/* Support legacy `organization` option. */}}
-        {{ if $.Site.Params.organization }}
-        <h3 itemprop="worksFor" itemscope itemtype="http://schema.org/Organization">
-          {{ with $.Site.Params.organization_url }}<a href="{{ . }}" target="_blank" itemprop="url" rel="noopener">{{ end }}
-            <span itemprop="name">{{ $.Site.Params.organization }}</span>
-          {{ if $.Site.Params.organization_url }}</a>{{ end }}
-        </h3>
-        {{ end }}
-
-        {{ range $.Site.Params.organizations }}
+        {{ range $person.organizations }}
         <h3 itemprop="worksFor" itemscope itemtype="http://schema.org/Organization">
           {{ with .url }}<a href="{{ . }}" target="_blank" itemprop="url" rel="noopener">{{ end }}
           <span itemprop="name">{{ .name }}</span>
@@ -34,10 +41,10 @@
         {{ end }}
       </div>
 
-      <link itemprop="url" href="{{ $.Site.BaseURL }}">
+      <link itemprop="url" href="{{ .Permalink }}">
 
       <ul class="network-icon" aria-hidden="true">
-        {{ range $.Site.Params.social }}
+        {{ range $person.social }}
         {{ $pack := or .icon_pack "fas" }}
         {{ $pack_prefix := $pack }}
         {{ if in (slice "fab" "fas" "far" "fal") $pack }}
@@ -63,22 +70,25 @@
   </div>
   <div class="col-12 col-lg-8" itemprop="description">
 
-    {{ $page.Content }}
+    {{/* Only display widget title in explicit instances of about widget, not in author pages. */}}
+    {{ if and $page.Params.widget $page.Title }}<h1>{{ $page.Title | markdownify | emojify }}</h1>{{ end }}
+
+    {{ $person_page.Content }}
 
     <div class="row">
 
-      {{ with $page.Params.interests }}
+      {{ with $person.interests }}
       <div class="col-md-5">
         <h3>{{ i18n "interests" | markdownify }}</h3>
         <ul class="ul-interests">
-          {{ range .interests }}
+          {{ range . }}
           <li>{{ . | markdownify | emojify }}</li>
           {{ end }}
         </ul>
       </div>
       {{ end }}
 
-      {{ with $page.Params.education }}
+      {{ with $person.education }}
       <div class="col-md-7">
         <h3>{{ i18n "education" | markdownify }}</h3>
         <ul class="ul-edu fa-ul">