NAV

Intro

DOI

Semantic Web for Hugo adds structured data and linked data into a Hugo-powered website. Through it search engines can easily read the data of a Hugo-powered website and establish relationships between objects. This enables search engines to intelligently store information about a website and use it to increase a website’s exposure in search results.

For this project, we chose to implement Schema.org’s Vocabulary by adding JSON-LD markup automatically. In areas where custom input is required, we took advantage of Hugo’s shortcode feature.

Latest version: v1.1.3: codeberg migration released on 2022-12-31.

History

Features

These are the currently supported Schema.org Types:

Installation

Hugo module method

  1. In your hugo config file add the following:
[module]
  [[module.imports]]
    path = "codeberg.org/yelosan/hugo-semantic-web"
module:
  imports:
    - path: codeberg.org/yelosan/hugo-semantic-web
{
  "module": {
    "imports": [
      {
        "path": "codeberg.org/yelosan/hugo-semantic-web"
      }
    ]
  }
}
  1. Add this in /layouts/_default/baseof.html (or whichever is appropriate):
{{ $semwebcss := resources.Get "css/semweb-style.css" }}
{{ $semwebstyle := $semwebcss | resources.Minify }}
<link rel="stylesheet" href="{{ $semwebstyle.RelPermalink }}" media="all" type="text/css" />
  1. Initialize your project as a module:
hugo mod init your-site-name-or-link-to-repo
  1. Download Hugo Semantic Web module
hugo mod get codeberg.org/yelosan/hugo-semantic-web
  1. Proceed to the next step.

We recommend installing the Semantic Web for Hugo project by taking advantage of the Hugo module feature. This method ensures your project will always use the latest release of Semantic Web for Hugo.

Follow the steps on the right (or below if viewing in mobile).

To update

To update the Semantic Web for Hugo module run this while in your project’s root: hugo mod get -u codeberg.org/yelosan/hugo-semantic-web

git submodule method

  1. Add this in your config file:
theme = ["hugo-semantic-web", "your-theme"]
theme:
  - hugo-semantic-web
  - your-theme
{
  "theme": [
    "hugo-semantic-web",
    "your-theme"
  ]
}
  1. In your project’s root folder:
git submodule add https://codeberg.org/yelosan/hugo-semantic-web.git themes/hugo-semantic-web
  1. Then initialize the Semantic Web for Hugo submodule:
git submodule update --init --recursive themes/hugo-semantic-web
  1. Add this in /layouts/_default/baseof.html (or whichever is appropriate):
{{ $semwebcss := resources.Get "css/semweb-style.css" }}
{{ $semwebstyle := $semwebcss | resources.Minify }}
<link rel="stylesheet" href="{{ $semwebstyle.RelPermalink }}" media="all" type="text/css" />
  1. Proceed to the next step.

The git submodule method is our second recommendation. This method also makes it easier to update the Semantic Web for Hugo module.

Follow the steps on the right (or below if viewing in mobile).

To update

While in your project’s root run this command: git submodule update --init --recursive themes/hugo-semantic-web

git clone method

  1. Add this in your config file:
theme = ["hugo-semantic-web", "your-theme"]
theme:
  - hugo-semantic-web
  - your-theme
{
  "theme": [
    "hugo-semantic-web",
    "your-theme"
  ]
}
  1. In your project’s root folder:
git clone https://codeberg.org/yelosan/hugo-semantic-web.git themes/hugo-semantic-web
  1. Add this in /layouts/_default/baseof.html (or whichever is appropriate):
{{ $semwebcss := resources.Get "css/semweb-style.css" }}
{{ $semwebstyle := $semwebcss | resources.Minify }}
<link rel="stylesheet" href="{{ $semwebstyle.RelPermalink }}" media="all" type="text/css" />
  1. Proceed to the next step.

git clone is the simplest git method to add a module in your Hugo-powered project.

Follow the steps on the right (or below if viewing in mobile).

To update

In the Semantic Web for Hugo folder (cd themes/hugo-semantic-web) run this command: git pull.

Download method

  1. Add this in your config file:
theme = ["hugo-semantic-web", "your-theme"]
theme:
  - hugo-semantic-web
  - your-theme
{
  "theme": [
    "hugo-semantic-web",
    "your-theme"
  ]
}
  1. Download the latest release here.
  1. Extract the file in your project’s /themes/ folder, it should be: themes/hugo-semantic-web/
  1. Add this in /layouts/_default/baseof.html (or whichever is appropriate):
{{ $semwebcss := resources.Get "css/semweb-style.css" }}
{{ $semwebstyle := $semwebcss | resources.Minify }}
<link rel="stylesheet" href="{{ $semwebstyle.RelPermalink }}" media="all" type="text/css" />
  1. Proceed to the next step.

We do not recommend this method. If you prefer to lock to a specific version or include Semantic Web for Hugo in your theme distribution, the Hugo Module method can do both better.

However, if this method best suits your workflow, you can follow the steps on the right (or below if viewing in mobile).

To update

  1. Check regularly the project’s repository for updates.
  2. Download the latest release here.
  3. If you did not modify any of the Semantic Web for Hugo files, delete the /hugo-semantic-web/ folder located in your project’s /themes/ folder.
  4. Extract the latest release in /themes/hugo-semantic-web/.

Types

Organization

id = ""
foundingdate = ""
knowslanguages = ["", ""]
legalname = ""
slogan = ""
taxid = ""
vatid = ""
alternatenames = ["", ""]
description = ""
name = ""
sameas = ["", ""]
url = ""

[[brands]]
  id = ""
  logo = ""
  name = ""
  url = ""
  iswebsite = false
[[brands]]
  id = ""
  logo = ""
  name = ""
  url = ""
  iswebsite = false

[[founders]]
  id = ""
  name = ""
  sameas = [""]
  url = ""
[[founders]]
  id = ""
  name = ""
  sameas = [""]
  url = ""

[[images]]
  caption = ""
  url = ""
  islogo = false
[[images]]
  caption = ""
  url = ""
  islogo = false
id: ''
foundingdate: ''
knowslanguages:
  - ''
  - ''
legalname: ''
slogan: ''
taxid: ''
vatid: ''
alternatenames:
  - ''
  - ''
description: ''
name: ''
sameas:
  - ''
  - ''
url: ''
brands:
  - id: ''
    logo: ''
    name: ''
    url: ''
    iswebsite: false
  - id: ''
    logo: ''
    name: ''
    url: ''
    iswebsite: false
founders:
  - id: ''
    name: ''
    sameas:
      - ''
    url: ''
  - id: ''
    name: ''
    sameas:
      - ''
    url: ''
images:
  - caption: ''
    url: ''
    islogo: false
  - caption: ''
    url: ''
    islogo: false
{
  "id": "",
  "foundingdate": "",
  "knowslanguages": [
    "",
    ""
  ],
  "legalname": "",
  "slogan": "",
  "taxid": "",
  "vatid": "",
  "alternatenames": [
    "",
    ""
  ],
  "description": "",
  "name": "",
  "sameas": [
    "",
    ""
  ],
  "url": "",
  "brands": [
    {
      "id": "",
      "logo": "",
      "name": "",
      "url": "",
      "iswebsite": false
    },
    {
      "id": "",
      "logo": "",
      "name": "",
      "url": "",
      "iswebsite": false
    }
  ],
  "founders": [
    {
      "id": "",
      "name": "",
      "sameas": [
        ""
      ],
      "url": ""
    },
    {
      "id": "",
      "name": "",
      "sameas": [
        ""
      ],
      "url": ""
    }
  ],
  "images": [
    {
      "caption": "",
      "url": "",
      "islogo": false
    },
    {
      "caption": "",
      "url": "",
      "islogo": false
    }
  ]
}

Configurable parameters

Person

Create a Person file in /data/persons/

id = ""
additionalnames = [""]
jobtitle = [""]
knowslanguages = [""]
taxid = ""
vatid = ""
description = ""
mainentityofpage = ""
name = ""
sameas = [""]
url = ""

[[affiliations]]
  id = ""
  name = ""
  url = ""
[[affiliations]]
  id = ""
  name = ""
  url = ""

[[brands]]
  id = ""
  logo = ""
  name = ""
  url = ""
  iswebsite = false
[[brands]]
  id = ""
  logo = ""
  name = ""
  url = ""
  iswebsite = false

[spouse]
  id = ""
  name = ""
  url = ""

[[worksfor]]
  id = ""
  name = ""
  url = ""
[[worksfor]]
  id = ""
  name = ""
  url = ""

[[images]]
  caption = ""
  url = ""
  isphoto = false
[[images]]
  caption = ""
  url = ""
  isphoto = false
id: ''
additionalnames:
  - ''
jobtitle:
  - ''
knowslanguages:
  - ''
taxid: ''
vatid: ''
description: ''
mainentityofpage: ''
name: ''
sameas:
  - ''
url: ''
affiliations:
  - id: ''
    name: ''
    url: ''
  - id: ''
    name: ''
    url: ''
brands:
  - id: ''
    logo: ''
    name: ''
    url: ''
    iswebsite: false
  - id: ''
    logo: ''
    name: ''
    url: ''
    iswebsite: false
spouse:
  id: ''
  name: ''
  url: ''
worksfor:
  - id: ''
    name: ''
    url: ''
  - id: ''
    name: ''
    url: ''
images:
  - caption: ''
    url: ''
    isphoto: false
  - caption: ''
    url: ''
    isphoto: false
{
  "id": "",
  "additionalnames": [
    ""
  ],
  "jobtitle": [
    ""
  ],
  "knowslanguages": [
    ""
  ],
  "taxid": "",
  "vatid": "",
  "description": "",
  "mainentityofpage": "",
  "name": "",
  "sameas": [
    ""
  ],
  "url": "",
  "affiliations": [
    {
      "id": "",
      "name": "",
      "url": ""
    },
    {
      "id": "",
      "name": "",
      "url": ""
    }
  ],
  "brands": [
    {
      "id": "",
      "logo": "",
      "name": "",
      "url": "",
      "iswebsite": false
    },
    {
      "id": "",
      "logo": "",
      "name": "",
      "url": "",
      "iswebsite": false
    }
  ],
  "spouse": {
    "id": "",
    "name": "",
    "url": ""
  },
  "worksfor": [
    {
      "id": "",
      "name": "",
      "url": ""
    },
    {
      "id": "",
      "name": "",
      "url": ""
    }
  ],
  "images": [
    {
      "caption": "",
      "url": "",
      "isphoto": false
    },
    {
      "caption": "",
      "url": "",
      "isphoto": false
    }
  ]
}

Configurable parameters

WebContent

There are no configurable parameters for WebContent. It relies on what is available in WebSite, WebPage, and Article.

WebSite

Add this in your [hugo|params|config] file:

[params]
  keywords = ["", ""]
  description = ""
  images = ["", ""]

  [params.semweb]
    org = ""
    isblog = false

    issn = ""
    acquirelicensepage = ""
    copyrightholder = ""
    copyrightnotice = ""
    creator = ""
    credittext = ""
    datefirstpublished = ""
    license = ""
    publisher = ""
    sameas = [""]

    [[params.semweb.persons]]
      person = ""
      id = ""
      name = ""
      url = ""
      description = ""
    [[params.semweb.persons]]
      person = ""
      id = ""
      name = ""
      url = ""
      description = ""
params:
  keywords:
    - ''
    - ''
  description: ''
  images:
    - ''
    - ''
  semweb:
    org: ''
    isblog: false
    issn: ''
    acquirelicensepage: ''
    copyrightholder: ''
    copyrightnotice: ''
    creator: ''
    credittext: ''
    datefirstpublished: ''
    license: ''
    publisher: ''
    sameas:
      - ''
    persons:
      - person: ''
        id: ''
        name: ''
        url: ''
        description: ''
      - person: ''
        id: ''
        name: ''
        url: ''
        description: ''
{
  "params": {
    "keywords": [
      "",
      ""
    ],
    "description": "",
    "images": [
      "",
      ""
    ],
    "semweb": {
      "org": "",
      "isblog": false,
      "issn": "",
      "acquirelicensepage": "",
      "copyrightholder": "",
      "copyrightnotice": "",
      "creator": "",
      "credittext": "",
      "datefirstpublished": "",
      "license": "",
      "publisher": "",
      "sameas": [
        ""
      ],
      "persons": [
        {
          "person": "",
          "id": "",
          "name": "",
          "url": "",
          "description": ""
        },
        {
          "person": "",
          "id": "",
          "name": "",
          "url": "",
          "description": ""
        }
      ]
    }
  }
}

Configurable frontmatter parameters

WebPage

There are no configurable parameters for Type:WebPage. The properties and related data automatically adjusts depending on the Page Kind.

Article

frontmatter parameters

title = ""
description = ""

date = ""
lastmod = ""
expirydate = ""

categories = ["", ""]
tags = ["", ""]
keywords = ["", ""]

images = ["", ""]
videos = ["", ""]

license = ""
acquirelicensepage = ""

[[author]]
  person = ""
  id = ""
  name = ""
  sameas = ""
  url = ""
[[author]]
  person = ""
  id = ""
  name = ""
  sameas = ""
  url = ""
title: ''
description: ''
date: ''
lastmod: ''
expirydate: ''
categories:
  - ''
  - ''
tags:
  - ''
  - ''
keywords:
  - ''
  - ''
images:
  - ''
  - ''
videos:
  - ''
  - ''
license: ''
acquirelicensepage: ''
author:
  - person: ''
    id: ''
    name: ''
    sameas: ''
    url: ''
  - person: ''
    id: ''
    name: ''
    sameas: ''
    url: ''
{
  "title": "",
  "description": "",
  "date": "",
  "lastmod": "",
  "expirydate": "",
  "categories": [
    "",
    ""
  ],
  "tags": [
    "",
    ""
  ],
  "keywords": [
    "",
    ""
  ],
  "images": [
    "",
    ""
  ],
  "videos": [
    "",
    ""
  ],
  "license": "",
  "acquirelicensepage": "",
  "author": [
    {
      "person": "",
      "id": "",
      "name": "",
      "sameas": "",
      "url": ""
    },
    {
      "person": "",
      "id": "",
      "name": "",
      "sameas": "",
      "url": ""
    }
  ]
}

Configurable frontmatter parameters

Listed are only the parameters which are useful for building Semantic Web and Linked Data. There are other default Hugo frontmatter parameters which are required, recommended, or optional.

BlogPosting

This Type relies on the isblog parameter in your config file. See Type: WebSite above for information.

ImageObject

This Type takes advantage of Hugo’s shortcode feature. We created a new shortcode called image.

The image shortcode uses the style from Embed Responsively. This means that the images will use 100% of box it is contained in and when the view is smaller, it will adjust.

Aside:

{{< image >}} shortcode

{{< image
  height=""
  width=""
  class=""
  style=""
  type=""

  isrepresentativeofpage=false

  src=""
  link=""
  linkrel="noopener"
  thumbnailurl=""

  title=""
  caption=""
  alt=""
  embeddedtextcaption=""
  inlanguage=""

  datecreated=""
  datepublished=""

  objheight=""
  objwidth=""

  infoalign=""

  licensecode=""
  licenseurl=""
  licensename=""

  acquirelicensepage=""
  copyrightnotice=""
  credittext=""

  attribto=""
  attriburl=""
  attribrel="noopener"

  cc0country=""
  cc0countrycode=""
  cc0countryurl=""

  contentloc=""
  contentlocurl=""
  contentlocrel="noopener external"
  contentreferencetime=""
>}}

Configurable parameters

Link images to Article

To establish a relationship between Type:ImageObject and Type:Article, add the source URL of the image(s) in the article’s frontmatter, use Hugo’s default: images = ["", ""].

For example: images = ["https://rsc.youronly.one/img/y/Yuki_flag-300h.webp", "https://img.youronly.one/works/Yellow_Bell-02-CC_By-SA_4.0-s.webp"].

It is best to keep the old URLs and redirect it to the new host, or run a mass edit against the existing articles. How to do either of the aforementioned options is outside the scope of this project and documentation.

Sample #1: Basic images

Switching existing posts from Hugo built-in figure to Semantic Web for Hugo image shortcode—without adding new parameters—will look like this:

{{< image
  class="semwebdemostyle"
  src="https://rsc.youronly.one/img/y/Yuki_flag-300h.webp"
  link="https://im.youronly.one/yuki/"
  alt="ALT"
  title="TITLE"
  caption="CAPTION"
  attr="ATTRIBUTION"
  attrlink="https://youronly.one"
>}}
ALT

TITLE

CAPTION

The work shown above is Copyrighted to ATTRIBUTION.

Wondering why there is a class="semwebdemostyle" in the above sample image? We are mimicking the built-in figure shortcode, as explained above, and we need to add display: table-cell to render the image properly in this documentation theme.

Sample #2: Rich images

This is a sample of an image shortcode with additional parameters useful for building Semantic Web and Linked Data.

{{< image
  style="display: table-cell;"

  isrepresentativeofpage=false

  src="https://img.youronly.one/works/Yellow_Bell-02-CC_By-SA_4.0-s.webp"
  link="https://im.youronly.one/yuki/photography/the-yellow-bells-of-piddig-2021225/"
  linkrel="noopener external"

  title="Allamanda cathartica or Yellow Bell"

  datecreated="2018-05-19"
  datepublished="2020-08-13"

  licensecode="ccbysa4"
  licenseurl="https://creativecommons.org/licenses/by-sa/4.0/"
  licensename="Creative Commons Attribution-ShareAlike 4.0 International"

  acquirelicensepage="https://im.youronly.one/p/legal-notice/"

  attribto="I'M YourOnly.One"
  attriburl="https://im.youronly.one/"
  attribrel="noopener external"

  contentloc="Piddig, Ilocos Norte, Philippines"
  contentlocurl="https://en.wikipedia.org/wiki/Piddig"
  contentlocrel="noopener external"
  contentreferencetime="2018-05-19"
>}}

Bonus: cover image

{{< image
  style="display: table-cell;"
  type="imagecoverattrib"

  link="https://img.youronly.one/works/Sunflower_in_the_City-03-Nokia3_macro-20180409_150647-s.webp"
  linkrel="noopener external"

  title="Sunflower in the City"

  licensecode="ccbysa4"
  licenseurl="https://creativecommons.org/licenses/by-sa/4.0/"
  licensename="Creative Commons-Attribution-ShareAlike 4.0 International"

  acquirelicensepage="https://im.youronly.one/p/legal-notice/"

  attribto="I'M YourOnly.One"
  attriburl="https://im.youronly.one/"
  attribrel="noopener external"
>}}

The image shortcode includes an option to give attribution for the article’s cover image separately, simply add the image shortcode at the end of an article’s file with the type set to imagecoverattrib.

It will look like this:

VideoObject

This Type takes advantage of Hugo’s shortcode feature. The {{< video >}} shortcode is included in Semantic Web for Hugo with support for YouTube and Vimeo, and Hugo’s Privacy Config.

{{< video >}} shortcode

{{< video
  height=""
  width=""
  class=""
  style=""
  platform=""

  id=""
  linkrel="noopener external"
  isplaylist=false
  isloop=false
  starttime=""
  endtime=""

  title=""
  caption=""
  inlanguage=""

  datecreated=""
  datepublished=""

  director=""
  musicby=""

  objframesize=""
  objquality=""
  objheight=""
  objwidth=""

  infoalign=""

  licensecode=""
  licenseurl=""
  licensename=""

  acquirelicensepage=""
  copyrightnotice=""
  credittext=""

  attribto=""
  attriburl=""
  attribrel="noopener external"

  cc0country=""
  cc0countrycode=""
  cc0countryurl=""

  contentloc=""
  contentlocurl=""
  contentlocrel="noopener external"
  contentreferencetime=""
>}}

Configurable parameters

Link videos to Article

To create a relationship between Type:VideoObject and Type:Article, add the URL of the video(s) in the article’s frontmatter, use Hugo’s videos = ["", ""]. If any, remove all other parameters in the URL, it should only contain the video host’s domain name and the video’s ID.

For example:

Sample #1: YouTube

A sample YouTube embed with Hugo’s Privacy Config enabled.

{{< video
  style="display: table-cell;"

  id="OM6XIICm_qo"
  linkrel="noopener external"

  title="Tim Berners-Lee: The next Web of open, linked data"
  caption="20 years ago, Tim Berners-Lee invented the World Wide Web. For his next project, he's building a web for open, linked data that could do for numbers what the Web did for words, pictures, video: unlock our data and reframe the way we use it together."
  inlanguage="en"

  datepublished="2009-03-13"

  licensecode="allrightsreserved"

  attribto="TED"
  attriburl="https://www.youtube.com/channel/UCAuUUnT6oDeKwE6v1NGQxug"
  attribrel="noopener external"
>}}

Tim Berners-Lee: The next Web of open, linked data

20 years ago, Tim Berners-Lee invented the World Wide Web. For his next project, he’s building a web for open, linked data that could do for numbers what the Web did for words, pictures, video: unlock our data and reframe the way we use it together.

The work shown above is Copyrighted to TED.

Sample #2: Vimeo

A Vimeo embed with Hugo’s Privacy Config enabled.

{{< video
  style="display: table-cell;"
  platform="vimeo"

  id="601088734"
  linkrel="noopener external"

  title="The Wild: Capturing Our Planet in Dolby Vision"
  caption="The Wild is a short film inspired by the idea that we need to co-exist and protect nature. It's Noah Beschen's journey through our beautiful world captured and shared with the crisp clarity and vibrancy of Dolby Vision. Because every moment should look like this."
  inlanguage="en"

  datepublished="2021-09-09"

  licensecode="allrightsreserved"

  attribto="Aaron Lieber"
  attriburl="https://vimeo.com/lieberfilms"
  attribrel="noopener external"
>}}

The Wild: Capturing Our Planet in Dolby Vision

The Wild is a short film inspired by the idea that we need to co-exist and protect nature. It’s Noah Beschen’s journey through our beautiful world captured and shared with the crisp clarity and vibrancy of Dolby Vision. Because every moment should look like this.

The work shown above is Copyrighted to Aaron Lieber.

Contribute

You can contribute to the project via our Codeberg repo: https://codeberg.org/yelosan/hugo-semantic-web.

You can also help with our documentation via our Codeberg repo: https://codeberg.org/yelosan/hugo-semantic-web-docs.

Contact Us

Bugs and Suggestions

Please file a bug report and suggest new features in our project’s Codeberg tracker: https://codeberg.org/yelosan/hugo-semantic-web/issues.

Documentation

For documentation improvements, file it in our documentation Codeberg issues tracker: https://codeberg.org/yelosan/hugo-semantic-web-docs/issues



Powered by Hugo | DocuAPI theme by Bjørn Erik Pedersen