Help:Contributors

Create a contributor's profile page.

Whether moderator, content creator or developer, everyone who contributes to the website needs a personal profile page on our website. They are used in different ways. May it be a table of the contributors shown on the website or the metadata to see, which person contributed to which content.

For example in the header of the blog entry, the contributor’s name (title) is needed to show the reader more about the person who wrote the blog entry.

Spaces Announcement 🎉

Our community has grown to over 3500 members, and we are grateful for everyone who is bearing with us. Thanks Pythoneers!
As we grow, we want to provide space for more conversations. Keeping discussion on-topic in this room is the right thing to do, but off-topic conversation is fun -- and it builds a stronger community.

October 8, 2021  ·  1 min  ·  Matrix and Community
Blog Card from the "Home" page

The above example shows an entry, which features multiple contributors. To add the contributors to the blog entry the contributors variable is used. In this case, it was: contributors: ["Michael Sasser", "BrenBarn", "ilex", "James Belchamber"]

If you click on one of the contributors, marked with a red underline, you will see the contributor page of this user. For example, Michael’s contributor page is located in ./content/contributors/michael-sasser/ . It contains a file _index.md and a file michael_sasser_ava.svg:

  • _index.md is the file, which contains all text and references the image used.
  • michael_sasser_ava.svg is the image used in the contributor page. Please remember our image conventions . The filename convention in those images is my_user_ava.extention. In case the avatar was not set, but the matrix_identifier was, the avatar which was set in the Python room on Matrix will be used.

Location

DirectoryDescription
content/<Language>/contributors/The base directory of the contributors

Create a New Contributors Page

To create a new page, use the command npm run create -- 'contributors/<pageName>.md'. After that you can edit your newly created page, which is located in content/en/contributors/<pageName>.md.

Example

Create a new page foo:

$ npm run create -- 'contributors/foo.md'

> [email protected] create
> exec-bin node_modules/.bin/hugo/hugo new "contributors/foo.md"

Content "/home/username/path_to_repository/repository_root_directory/content/en/contributors/foo.md" created

Front Matter

The title in this case would be your name or your nickname preferably the on you use on Matrix.
Every Markdown file contains a header section, called front matter, in the YAML format to configure parts of the page or website. A contributor page needs the following variables in the front matter.
VariableTypeDescription
titlestrThe title of the page or ressource
descriptionstrThe page description, normally for SEO
datedatetimeThe datetime the page was created
lastmoddatetimeThe datetime the page was modified. Should be the same as date when the creating a new page
draftboolflase shows the page, true hides the page, as it does not exist
imageslist of strImages, which will be converted and moved to the static directory. Remember to add every image you used here
mathboolThis page contains LaTeX math. This option preloads the font and includes the KaTeX script in the script footer.
avatarstrAn image, which is used as avatar from images
matrix_identifierstrThe matrix user identifier e.g. "@michael:michaelsasser.org"
matrix_usernamestrThe matrix nickname e.g. "Michael Sasser"
matrix_moderatorbooltrue, when the user is a moderator; false, when not
website_contentbooltrue, when the user is a website content creator; false, when not
website_developerbooltrue, when the user is a website developer; false, when not
email_addressstrAn email address, which will be public in your contributor profile
gitlab_usernamestrThe GitLab username of that user e.g. "MichaelSasser"
github_usernamestrThe GitHub username of that user e.g. "MichaelSasser"
gitea_profile_urlstrThe URL to your Gitea profile e.g. "https://mygitea.org/MichaelSasser"
mastodon_profile_urlstrThe Mastodon URL of that user e.g. "https://fosstodon.org/@michaelsasser"
website_urlstrAn external website URL "https://MichaelSasser.org"
botboolThis user is a bot
You will find a complete list and how to use them inside the site in the Hugo docs →

The Datetime Type

The date and time according to ISO 8601 . The following table shows the extended format specified in ISO 8601 we use for our website to specify, when e.g. a page was created or edited. It has three parts:

  • the date
  • the time, including it's designator T
  • the timezone offset
We would prefere if you would use your local time together with the timezone offset (in this case it is mandatory), but you can also enter the time in UTC without the timezone offset.
ValueOptionalDescription
2021NoYear
07NoMonth
08NoDay of the month
TNoT is a designator, which indicates the start of the time representation
12NoHour
34NoMinute
56NoSecond
+ or -Yes+ for a positive or - a negative timezone offset
01YesTimezone offset in hours
02YesTimezone offset in minutes

Formatting Examples

The following example uses the values from the table to show the format. It does not use the actual UTC. If you are not using the timezone offset, you must calculate UTC yourself.

  • Example with timezone offset: 2021-07-08T12:34:56+01:02
  • Example without timezone offset: 2021-07-08T12:34:56

Header Example

Remember, the front matter is a YAML structure embedded into the Markdown file. The --- delimiters signal Hugo that this is a front matter in the YAML format. Here is a generated example, how the front matter might look like:

---
title: "MyTitle"
description: "A description of the page content"
date: 2021-10-08T14:48:42+01:00
lastmod: 2021-10-08T14:48:42+01:00
draft: false
images: ["avatar.svg" "foo.svg" "bar.svg"]
math: true
avatar: "avatar.svg"
matrix_identifier: "@user:matrix.org"
matrix_username: "UserName"
matrix_moderator: false
website_content: false
website_developer: false
email_address: "[email protected]"
gitlab_username: "UserName"
github_username: "UserName"
gitea_profile_url: "https://mygitea.org/UserName"
mastodon_profile_url: "https://domain.tld/@foo"
website_url: "https://domain.tld"
bot: true# This is an example for a comment in YAML
---

Make sure to create your profile page, when you contribute to the website. You don’t actually need to enter personal information about yourself. You can just enter your GitLab username and your matrix identifier. For the title your name is mandatory, but nickname would be sufficient too.

Code

Below you find the implementation of the layout.

HTML

Single Page Layout

Defined in layouts/contributors/single.html.

This code is licensed under the MIT license.
{{/* <!--

  Contributors Layout
  ===================

  Contributors: Michael Sasser
  Maintainer: Michael Sasser
  License: MIT
  Version: 1
  Type: Single

  LAYOUT: /layouts/contributors/single.html
  DOCS:   /content/<language>/wiki/Help:Layout_Contributors.md

  Description
  -----------

  The list layout page for the contributors.

  Changelog
  =========

  Version 1
  ---------

  Initial release

  -->
*/}}

{{ define "main" }}

  <!-- Store all posts this user made -->
  {{ $posts := newScratch }}

  {{ range $post := where .Site.RegularPages "Section" "blog" -}}

    <!--
         Compile a slice of posts written by that user in the $post scratch
         under the "posts" key.
    -->
    {{ range $contributor := $post.Params.contributors }}
      {{ if eq $contributor $.Title }}
        {{ $posts.Add "posts" (slice $post) }}
      {{ end }}
    {{ end }}
  {{ end }}


  <!-- Evaluate if a blog post section is added to the contributor page -->
  <!-- Only show posts, when the user is not a bot -->
  {{- $showBlogPosts := false -}}
  {{- if isset .Params "bot" -}}
    {{- if not .Params.bot -}}
      {{- $showBlogPosts = true -}}
    {{- end -}}
  {{- else -}}
    {{- $showBlogPosts = true -}}
  {{- end -}}
  <!-- In any case, if there are not posts, hide them -->
  {{ if not ($posts.Get "posts") }}
    {{- $showBlogPosts = false -}}
  {{- end -}}


  <!-- Contributor Card -->
  <section class="section section-sm container-fluid py-3">
    <div class="container">
      <div class="row justify-content-center text-center">
        <div class="col">
          <h1>{{- .Title -}}</h1>

          {{- if isset $.Params "pronouns" -}}
            <h2 class="text-secondary mt-0">({{- .Params.pronouns -}})</h2>
          {{- end -}}

          {{ $title := .Title }}

          {{ if isset .Params "avatar" }}
            <div class="mb-4">
              <img
                src="{{ .Params.avatar }}"
                alt="{{- .Title }} Avatar"
                width="256"
              />
            </div>
          {{- else -}}
            <!--
              If no avatar image was set, but the matrix_identifier was set, use
              that to display the avatar from matrix.org.
            -->
            {{- if isset .Params "matrix_identifier" -}}
              {{- $avatar := "" -}}
              {{ if isset $.Site.Data "matrix_users" }}
                {{- range $.Site.Data.matrix_users -}}
                  {{- if eq .userId $.Params.matrix_identifier -}}
                    {{- with .avatar -}}
                      {{- $avatar = . -}}
                    {{- end -}}
                  {{- end -}}
                {{- end -}}
              {{- end -}}
              {{- with $avatar -}}
                <div class="text-center mb-4">
                  <img
                    src="{{ printf "https://matrix.org/_matrix/media/r0/thumbnail/%s?width=64&height=64&method=scale" (substr  $avatar 6) }}"
                    alt="{{- $.Title }} Avatar"
                    width="256"
                  />
                </div>
              {{- end -}}
            {{ end }}
          {{ end }}


          <ul class="contributor-social">
            <!-- Matrix -->
            {{ if isset .Params "matrix_identifier" }}
              <li class="social-item">
                <a
                  href="https://app.element.io/#/user/{{- .Params.matrix_identifier -}}"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <i class="fa fa-matrix-org fa-lg"></i>
                </a>
              </li>
            {{ end }}


            <!-- GitLab -->
            {{ if isset .Params "gitlab_username" }}
              <li class="social-item">
                <a
                  href="https://gitlab.com/{{- .Params.gitlab_username -}}"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <i class="fa fa-gitlab fa-lg"></i>
                </a>
              </li>
            {{ end }}


            <!-- GitHub -->
            {{ if isset .Params "github_username" }}
              <li class="social-item">
                <a
                  href="https://github.com/{{- .Params.gitlab_username -}}"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <i class="fa fa-github fa-lg"></i>
                </a>
              </li>
            {{ end }}


            <!-- Gitea -->
            {{ if isset .Params "gitea_profile_url" }}
              <li class="social-item">
                <a
                  href="{{- .Params.gitea_profile_url -}}"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <i class="fa fa-gitea fa-lg"></i>
                </a>
              </li>
            {{ end }}


            <!-- Mastodon -->
            {{ if isset .Params "mastodon_profile_url" }}
              <li class="social-item">
                <a
                  href="{{- .Params.mastodon_profile_url -}}"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <i class="fa fa-mastodon fa-lg"></i>
                </a>
              </li>
            {{ end }}


            <!-- Email -->
            {{ if isset .Params "email_address" }}
              <li class="social-item">
                <a
                  href="mailto://{{- .Params.email_address -}}"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <i class="fa fa-at fa-lg"></i>
                </a>
              </li>
            {{ end }}


            <!-- Website -->
            {{ if isset .Params "website_url" }}
              <li class="social-item">
                <a
                  href="{{- .Params.website_url -}}"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  <i class="fa fa-globe fa-lg"></i>
                </a>
              </li>
            {{ end }}
          </ul>
        </div>
      </div>
    </div>
  </section>

  <!-- Content -->
  <section class="section section-sm pt-4 bg-light container-fluid">
    <div class="container">
      <div class="row justify-content-center">
        <div class="col-lg-8">
          <!-- Lead -->
          {{ if isset .Params "lead" }}
            <p class="lead" style="text-align: center">
              {{ .Params.lead | safeHTML }}
            </p>
          {{ else }}
            {{ if eq .Params.matrix_moderator true }}
              <p class="lead" style="text-align: center">
                {{- i18n "hi-im" }} {{ .Params.title }},
                {{ i18n "a-member-of-the-moderation-team" -}}.
              </p>
            {{ else if eq .Params.website_contributor true }}
              <p class="lead" style="text-align: center">
                {{- i18n "hi-im" }} {{ .Params.title }},
                {{ i18n "a-contributor-to-this-project" -}}.
              </p>
            {{ end }}
          {{ end }}
          <div>{{ .Content }}</div>
        </div>
      </div>
    </div>
  </section>

  <!-- Blog Posts -->
  {{- if $showBlogPosts -}}
    <section class="section section-sm pt-4 container-fluid">
      <div class="container">
        <div class="row justify-content-center text-center">
          <div class="col-10">
            <h2 class="h3 mt-3 mb-5 text-center">
              {{- i18n "my-latest-blog-posts" -}}
            </h2>
            <div class="card-list">
              <div class="row ">
                {{ range first 6 ($posts.Get "posts") -}}
                  <div class="col-lg-6 col-md-12">
                    {{ partial "main/blog-post-list-layout.html" . -}}
                  </div>
                {{ end -}}
              </div>
            </div>
          </div>
          <!-- Pagination -->
        </div>
      </div>
    </section>
  {{ end }}
{{ end }}

List Page Layout

Defined in layouts/contributors/list.html.

This code is licensed under the MIT license.
{{/*<!--

  Contributors Layout
  ===================

  Contributors: Michael Sasser
  Maintainer: Michael Sasser
  License: MIT
  Version: 1
  Type: List

  LAYOUT: /layouts/contributors/list.html
  DOCS:   /content/<language>/wiki/Help:Layout_Contributors.md

  Description
  -----------

  The list layout page for the contributors.

  Changelog
  =========

  Version 1
  ---------

  Initial release

-->*/}}

{{ define "main" }}
  <div class="container">
    <div class="row justify-content-center">
      <div class="col">
        <article>
          <h1 class="text-center">{{ .Title }}</h1>
          <p class="text-center lead">{{ .Params.lead | safeHTML }}</p>
          <div class="text-center mb-5">{{ .Content }}</div>
          <div class="row mb-2 justify-content-center">
            {{ range .Data.Pages.ByDate -}}

              {{ $avatar_name := "" }}
              {{ $avatar := "" }}

              {{ if and (ne .Params.avatar nil) (isset .Params "avatar")}}
                <!-- avatar_name e.g. "foo.svg" -->
                {{ $avatar_name = .Params.avatar }}
                <!-- .Path is deprecated and reused for a canonical source path
                     The following constructor is used to archive an equivalent
                     behavior of $path as .Path was used before.
                -->
                {{ $path := "" }}
                {{ with .File }}
                  {{ $path = .Path }}
                {{ else }}
                  {{ $path = .Path }}
                {{ end }}
                <!-- avatar_path e.g. "/path/to/" -->
                {{ $avatar_path := path.Dir $path }}
                <!-- avatar e.g. "/path/to/foo.svg" -->
                {{ $avatar = $avatar_name | printf "/%s/%s" $avatar_path | printf "%s" }}
              {{ end }}

              <div class="col-xxl-4 col-lg-6 col-md-12">
                <div
                  class="
                    row
                    g-0
                    border
                    rounded
                    overflow-hidden
                    flex-md-row
                    mb-4
                    h-500
                    position-relative
                  "
                >
                  <div class="col p-4 flex-column position-static">
                    {{ if eq .Params.bot true -}}
                      <span class="badge text-bg-warning">Bot</span>
                    {{ end }}
                    {{ if eq .Params.matrix_moderator true -}}
                      <span class="badge text-bg-success">Moderator</span>
                    {{ end }}
                    {{ if eq .Params.matrix_ex_moderator true -}}
                      <span class="badge text-bg-success">Ex Moderator</span>
                    {{ end }}
                    {{ if eq .Params.website_developer true -}}
                      <span class="badge text-bg-primary">Website</span>
                    {{ end }}
                    {{ if eq .Params.website_content true -}}
                      <span class="badge text-bg-danger">Content</span>
                    {{ end }}
                    <h5 class="mb-0 mt-3">{{ .Params.title }}</h5>
                    <small class="pb-2 d-flex text-muted">
                      Since {{ .PublishDate.Format "Jan 2, 2006" }}
                    </small>
                    <p class="card-text mb-auto">
                      {{ if isset .Params "lead"}}
                        {{ truncate 80 " [...]" .Params.lead }}
                      {{ else }}
                        {{ if eq .Params.matrix_moderator true }}
                          Hi, I’m {{ .Params.title }}, a member of the moderation team.
                        {{ else if eq .Params.website_contributor true }}
                          Hi, I’m {{ .Params.title }}, a contributor to this website.
                        {{ end }}
                      {{ end }}
                    </p>
                    <a href="{{ .RelPermalink }}" class="stretched-link"></a>
                  </div>
                  <div class="col-auto">
                    {{ if ne $avatar_name "" }}
                      <img
                        class="img-fluid lazyload blur-up"
                        src="{{ $avatar | safeHTML }}"
                        alt="{{ .Params.title }} Avatar"
                        width="256"
                        height="256"
                      />
                      <!--
                        If no image was set, but the matrix_identifier was set, use
                        that to display the avatar from matrix.org.
                      -->

                    {{- else if isset .Params "matrix_identifier" -}}
                      {{- $avatar := "" -}}
                      <!--
                        Temporary store matrix identifier and title in a variable to
                        use them after range.
                      -->
                      {{ $matrix_user_identifier := .Params.matrix_identifier }}
                      {{ $user_title := .Params.title}}
                      {{ if isset $.Site.Data "matrix_users" }}
                        {{- range $.Site.Data.matrix_users -}}
                          {{- if eq .userId $matrix_user_identifier -}}
                            {{- with .avatar -}}
                              {{- $avatar = . -}}
                            {{- end -}}
                          {{- end -}}
                        {{- end -}}
                      {{- end -}}

                      {{- with $avatar -}}
                        <img
                          class="img-fluid lazyload blur-up"
                          src='{{ printf "https://matrix.org/_matrix/media/r0/thumbnail/%s?width=64&height=64&method=scale" (substr  $avatar 6) }}'
                          alt="{{ $user_title }} Avatar"
                          width="256"
                          height="256"
                        />
                      {{- end -}}
                    {{ else }}
                      <svg
                        class="bd-placeholder-img"
                        width="256"
                        height="256"
                        xmlns="http://www.w3.org/2000/svg"
                        role="img"
                        aria-label="Placeholder: Thumbnail"
                        preserveAspectRatio="xMidYMid slice"
                        focusable="false"
                      >
                        <title>Missing Thumbnail</title>
                        <rect width="100%" height="100%" fill="#55595c"></rect>
                        <text x="40%" y="43%" fill="#eceeef" dy=".3em">Missing</text>
                        <text x="36%" y="57%" fill="#eceeef" dy=".3em">Thumbnail</text>
                      </svg>
                    {{end}}
                  </div>
                </div>
              </div>
            {{ end -}}
          </div>
        </article>
      </div>
    </div>
  </div>
{{ end }}

Archetype

Defined in archetypes/contributors.md.

This code is licensed under the MIT license.
---
title: "{{ replace .Name "-" " " | title }}"
pronouns: ""
description: ""
lead: ""

date: {{ .Date }}
lastmod: {{ .Date }}

images: ["{{ .Name | urlize }}.jpg"]
avatar: ""

matrix_identifier: ""
matrix_username: ""

email_address: ""
gitlab_username: ""
github_username: ""
gitea_profile_url: ""
mastodon_profile_url: ""
website_url: ""

bot: false
matrix_moderator: flase
website_content: false
website_developer: false

draft: true
---
Top