I recently migrated my personal website from a React template to a Hugo PaperMod site. This decision was motivated by the simplicity Hugo offers: creating a clean, functional site without the need to write and maintain extensive HTML or JavaScript code. However, when I wanted to add my list of publications, I ran into a challenge.

Initially, Hugo seemed to only support Markdown files, which meant I would have to manually create a Markdown list of my publications. This was not only tedious but also presented a maintenance issue. Each time I published something new, I’d either have to update the Markdown file manually or risk having an outdated publication list—a common issue on many researchers’ websites.

I thought, There must be a way to integrate my ORCID publication list. Enter Hugo Layouts.

Hugo Layouts are a powerful and simple way to build HTML templates, which are then populated with content from your Markdown files. They provide the flexibility of JavaScript, making them a great tool for tasks like this. Here’s how to use them:

Steps

  1. Create a publications.html file in your hugo project, located in layouts/_default/.

  2. Copy and paste this code in the file:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    
    {{ define "main" }}
    <h1>My Publications</h1>
    </br>
    <div id="publications">Loading...</div>
    <script>
    const orcid = "{{ .Params.orcid }}"
    fetch(`https://pub.orcid.org/v3.0/${orcid}/works`, {
        headers: { Accept: "application/json" },
    })
        .then((response) => {
            if (!response.ok) {
                throw new Error(`ORCID API returned HTTP ${response.status}`)
            }
            return response.json()
        })
        .then((data) => {
        const publications = data.group
            .map((work) => {
            const summary =
                work && work["work-summary"] && work["work-summary"][0]
                ? work["work-summary"][0]
                : {}
            const title =
                (summary &&
                summary.title &&
                summary.title.title &&
                summary.title.title.value) ||
                "Untitled"
            const journalTitle =
                (summary && summary["journal-title"] && summary["journal-title"].value) ||
                " "
            const externalUrl =
                (summary && summary.url && summary.url.value) || null
            const publicationYear =
                (summary &&
                summary["publication-date"] &&
                summary["publication-date"]["year"] &&
                summary["publication-date"]["year"].value) ||
                " "
            const link =
                externalUrl && externalUrl !== "#"
                ? `<a href="${externalUrl}" target="_blank" rel="noopener"><strong>${title}</strong></a>`
                : `<strong>${title}</strong>`
            return `
            <li>
                ${link}<br>
                <i>${publicationYear}${
                journalTitle != " " ? ", " : ""
            }${journalTitle}</i>
            </li>
            `
            })
            .join("")
        document.getElementById(
            "publications"
        ).innerHTML = `<ul>${publications}</ul>`
        })
        .catch((error) => {
        console.error("Failed to load publications:", error)
        document.getElementById("publications").textContent =
            "Failed to load publications."
        })
    </script>
    {{ end }}
    
  3. Create a publications.md in your content directory:

    1
    2
    3
    4
    5
    6
    
    ---
    title: "Publications"
    layout: "publications"
    summary: "My publications based on my ORCID"
    orcid: "0000-0002-1825-0097"
    ---
    
  4. If everything worked, head over to your Publications subpage.