Chapter 7

Documentation

Helpful Documentation for K-State CS Textbooks

Subsections of Documentation

Textbook From Scratch

This gives the basic steps for creating a brand new Hugo textbook from scratch.

Basic Site Setup

The first steps come from the Hugo Quick Start Guide

  1. Install Hugo from the Hugo Releases. You should have version 0.101.0 or higher.
  2. Create a new site: hugo new site <sitename>.
  3. Open the site’s directory: cd <sitename>.
  4. Start a git repository: git init.
  5. Add the theme: git submodule add https://github.com/ksu-cs-textbooks/hugo-theme-relearn themes/hugo-theme-relearn
  6. Update the config.toml file:
    1. Best way to start is simply to copy the config.toml file for the starter site. It is well documented.
    2. Update the baseURL at the top to match the URL where the site will eventually be deployed.
    3. Update the title to match the site’s name
    4. Update the theme to be just theme = ["hugo-theme-relearn"] (remove the "plausible-hugo" part)
    5. Under [params], update the following:
      1. editURL to match the location where files can be edited in GitLab or GitHub.
      2. author used for metadata
      3. description used for metadata
      4. commitURL to match the location where individual commits can be found.
      5. Most of the parameters are documented in the Hugo Theme Relearn Documentation
    6. Remove the [params.plausible] section - it is not used by the textbooks site.
  7. Preview the site using hugo serve. It will be available at the URL given in the output. If the site loads with default content, then it is working.

Additional Configuration

Perform a few additional steps to make things work smoothly.

  1. Create a .gitignore file in the site’s base directory with the following content:
/public/
/resources/_gen
.hugo_build.lock
  1. If you are using Visual Studio Code to edit the site, create a .vscode folder in the site’s base directory, and then a settings.json file inside of that directory with the following content to change the sort order of your editor’s file explorer:
{
    "explorer.sortOrder": "mixed"
}

GitLab Repository Setup

Once the site is working locally, set up a repository on the CS GitLab server to store the data.

  1. We recommend storing the textbook in the CS Textbooks group. Contact another textbook author to get access.
  2. Create a repository that matches your textbook name. Use the other repositories as a naming guide. Do not initialize the repository in GitLab by creating a README file.
    1. You can choose to make your repository private (accessible only to the group), internal (accessible to anyone with a CS account), or public (accessible to anyone). Only those with permissions can update the repository (typically group members), but others may be able to view the content.
  3. In the site directory on your local system, add the repository’s URL as a remote: git remote add origin <url>
  4. Commit and push: git commit -m "Initial Commit" && git push -u origin main (substitute master for main if needed) 5. Make sure that you don’t commit the .hugo_build.lock file - it should be excluded via the .gitignore file created above.

Initial Content Creation

Now that the site is working, it is time to create some basic content.

Homepage

To create a home page, create a new _index.md file in the content directory. It should have at least the following content:

+++
archetype = "home"
title = "Homepage"
+++

Lorem Ipsum

You can also create this page using the command hugo new --kind home _index.md from the site’s directory and then modifying the content a bit.

See the Hugo Theme Relearn Documentation or Hugo Documentation for more on how to use the front matter of each page.

Chapter

To create a chapter, first create a folder with the chapter’s name in the content directory. We recommend including a number in front of the name to help with sorting, such as 01-introduction. Then, inside of that folder, create a new _index.md file with the following content:

+++
archetype = "chapter"
ordinal = "1"
title = "Introduction"
pre = "<b>1. </b>"
weight = 1
+++

Lorem Ipsum.

You can also create this page using the command hugo new --kind chapter 01-introduction/_index.md from the site’s directory and then modifying the content a bit.

Content Page

To create a content page, simply create a file inside of the desired directory with the .md file extension. Like chapters, we recommend adding a number in front of the file name to help with sorting, such as 01-welcome.md. Place the following content in the page:

---
title: "Welcome"
pre: "1. "
weight: 1
---

Lorem Ipsum.

You can also create this page using the command hugo new 01-introduction/01-welcome.md from the site’s directory and then modifying the content a bit.

Tip

Notice that the front matter for the homepage and chapters use plus symbols +++ as delimiters, while the content pages themselves use dashes --- instead. This is done by convention in this particular theme, and we follow that in this documentation. The plus symbols +++ indicate that the front matter is written in TOML while the dashes --- indicate that the front matter is written in YAML. The biggest difference is that TOML uses the equals symbol = for assignment, while YAML uses a colon : instead. See Front Matter Formats for more information.

Note

When creating this page using the command, it will add draft: true to the front matter. You’ll want to remove that so it appears on the site, or use hugo serve -D to include drafts files when previewing the site. It will also include the date, which can be safely removed - the theme will use the date of the latest commit to GitLab that includes this file instead.

The site right now uses a default logo based on the site’s title in config.toml. To override that, create a file at layouts/partials/logo.html in the site with the following content:

<a id="logo" href="{{ .Site.Home.RelPermalink | default ("/" | relLangURL) }}">
  Hugo Starter
</a>

Replace the text with the desired logo content. Alternatively, an image can be used. Place the image in the static/images/ folder and adapt the following HTML:

<a id="logo" href="{{ .Site.Home.RelPermalink | default ("/" | relLangURL) }}">
    <img src="/images/logo.png" alt="Logo" style="width: 100%">
</a>

The sidebar footer can also be overridden by creating a file at layouts/partials/menu-footer.html. It is best to simply copy the existing content in themes/hugo-theme-relearn/layouts/partials/menu-footer.html and edit it from that template.

Additional Content

From there, you can continue to create additional chapters and pages as needed. For more advanced content structures, look through the source code to this site. It includes examples for page bundles, leaf bundles, hidden pages, non-printable pages, syllabus pages, video content, historical content, and more.

Textbook From Starter

This gives the basic setup for a new textbook based on a starter repository.

Clone Starter Repository

  1. Install Hugo from the Hugo Releases. You should have version 0.101.0 or higher.
  2. Clone the Starter Repository on GitLab or GitHub to your local system: git clone <url> <directory>.
  3. Open the site’s directory: cd <directory>.
  4. Initialize git submodules: git submodule init.
  5. Recursively pull submodules: git pull --recurse.
  6. Update the config.toml file:
    1. Update the baseURL at the top to match the URL where the site will eventually be deployed.
    2. Update the title to match the site’s name
    3. Under [params], update the following:
      1. editURL to match the location where files can be edited in GitLab or GitHub.
      2. author used for metadata
      3. description used for metadata
      4. commitURL to match the location where individual commits can be found.
      5. Most of the parameters are documented in the Hugo Theme Relearn Documentation
  7. Preview the site using hugo serve. It will be available at the URL given in the output. If the site loads with default content, then it is working.

GitLab Repository Setup

Once the site is working locally, set up a repository on the CS GitLab server to store the data.

  1. We recommend storing the textbook in the CS Textbooks group. Contact another textbook author to get access.
  2. Create a repository that matches your textbook name. Use the other repositories as a naming guide. Do not initialize the repository in GitLab by creating a README file.
    1. You can choose to make your repository private (accessible only to the group), internal (accessible to anyone with a CS account), or public (accessible to anyone). Only those with permissions can update the repository (typically group members), but others may be able to view the content.
  3. In the site directory on your local system, add the repository’s URL as the new remote: git remote set-url origin <url>
  4. Commit and push: git commit -m "Initial Commit" && git push -u origin main (substitute master for main if needed) 5. Make sure that you don’t commit the .hugo_build.lock file - it should be excluded via the .gitignore file in the initial repository.

The site right now uses a default logo based on the site’s title in config.toml. To override that, create a file at layouts/partials/logo.html in the site with the following content:

<a id="logo" href="{{ .Site.Home.RelPermalink | default ("/" | relLangURL) }}">
  Hugo Starter
</a>

Replace the text with the desired logo content. Alternatively, an image can be used. Place the image in the static/images/ folder and adapt the following HTML:

<a id="logo" href="{{ .Site.Home.RelPermalink | default ("/" | relLangURL) }}">
    <img src="/images/logo.png" alt="Logo" style="width: 100%">
</a>

The sidebar footer can also be overridden by creating a file at layouts/partials/menu-footer.html. It is best to simply copy the existing content in themes/hugo-theme-relearn/layouts/partials/menu-footer.html and edit it from that template.

Additional Content

The starter repository contains all of the basic content covered in the Textbook from Scratch page.

From there, you can continue to create additional chapters and pages as needed. For more advanced content structures, look through the source code to this site. It includes examples for page bundles, leaf bundles, hidden pages, non-printable pages, syllabus pages, video content, historical content, and more.

Deploying Textbook

This page gives the basic instructions for deploying a textbook to the server. It is mainly meant as a reference for the server’s administrators, but it is helpful for everyone to understand the process.

Clone Repository on Server

  1. Log in to the server via SSH and switch to the textbooks account: sudo su textbooks.
  2. Change directory to the textbooks user’s home directory: cd ~.
  3. Clone the repository into this folder: git clone <url> <directory>.
  4. Change directory to the textbook’s directory: cd <directory>.
  5. Initialize submodules: git submodule init.
  6. Recursively pull submodules: git pull --recurse.
  7. Log out of the textbooks account: exit.

Set up Webhook on Server

  1. Switch to the config account: sudo su config.
  2. Change directory to the config user’s home directory: cd ~.
  3. Edit the webhook/webhook.conf file to add a new webhook.
    1. In general, just copy an existing webhook definition and edit to match the new site. Be Careful! The configuration file is JSON and is very picky about proper JSON syntax.
    2. Webhook Documentation.
  4. Save the file.
  5. Log out of the config account: exit.
  6. Restart webhook service: sudo systemctl restart webhook.

Example Webhook:

{
  "id": "hugo-starter",
  "execute-command": "/home/config/bin/deploy-101.sh",
  "command-working-directory": "/home/textbooks/hugo-starter/",
  "response-message": "Executing checkout script",
  "pass-arguments-to-command":
  [
    {
        "source": "string",
        "name": "hugo-starter"
    }
  ],
  "trigger-rule":
  {
    "match":
    {
      "type": "value",
      "value": "secret",
      "parameter":
      {
        "source": "header",
        "name": "X-Gitlab-Token"
      }
    }
  }
}

Items to configure:

  • id: this is the identifier for the webhook used in the URL
  • execute-command: see the scripts in the /home/config/bin directory.
  • command-working-directory: this is the directory where the textbook repository is stored.
    • deploy.sh will use the default version of Hugo
    • deploy-101.sh will use Hugo version 0.101.0
  • pass-arguments-to-command: this determines the folder where the content will be deployed. The name should match the URL desired (e.g. hugo-starter will deploy at https://textbooks.cs.ksu.edu/hugo-starter)
  • trigger-rule: is used to determine if the webhook request is valid. Change the value to match the key given when setting up the webhook in GitLab.

Set up Webhook on GitLab

  1. Open the repository on GitLab and navigate to the Settings -> Webhooks menu.
  2. Add a hook using the following settings:
  3. URL: http://pacer.cs.ksu.edu:9000/hooks/<hook_id>
  4. Secret Token: <secret>
  5. Trigger: Push events
    1. You can specify a specific branch; I typically leave this blank.
  6. Uncheck SSL Verification - we currently don’t have an SSL certificate on the webhook server.
  7. Click Add Webhook to save.
  8. Once saved, click the Test option and choose Push Event to test it. It should quickly return HTTP 200 at the top of the page if it is working.

Update Permissions

  1. After the first deployment, on the server, go to the web directory: cd /var/www/textbooks.cs.ksu.edu
  2. Update the permissions on the new directory:
    1. sudo chown -R textbooks:www-data <directory>
    2. sudo chmod -R g+w <directory>

Update Homepage

  1. Log in to the server via SSH and switch to the textbooks account: sudo su textbooks.
  2. Edit the site’s homepage at /var/www/textbooks.cs.ksu.edu/index.html to include a link to the new site.
  3. Save the file, and then log out of the textbooks account: exit.

Save Configuration

  1. Switch to the config account: sudo su config.
  2. Change directory to the config user’s home directory: cd ~.
  3. Copy the updated index.html file to the nginx folder: cp /var/www/textbooks.cs.ksu.edu/index.html ~/nginx/.
  4. Use git to commit and push the changes to the server configuration to GitLab.
    1. The only files changed should be webhook/webhook.conf and nginx/index.html.
  5. Log out of the config account: exit.

Notifications

Deployment notifications are sent to a Discord server. Contact one of the other textbook authors to get access to that Discord server. It is helpful if you want to see that your deployments are starting and completing correctly.

Debugging

Deployment logs are stored in the /home/textbooks/<name>.log file. This can be helpful for debugging.

Updating the Theme

From time to time, the underlying Hugo Theme Relearn clone may be updated. This page gives the directions for updating your textbook to the latest theme.

  1. Save and commit any work done on the textbook and push to GitLab. Wait until the deployment completes before continuing.
  2. In the site’s directory, open the themes/hugo-theme-relearn directory: cd themes/hugo-theme-relearn.
  3. Check out the main branch of the theme if you haven’t already: git checkout main.
  4. Pull the latest version of the theme: git pull.
  5. Change directory back to the site’s directory: cd ../../.
  6. Preview the changes: hugo serve.
  7. If everything looks good, commit and push: git commit -m "Update Theme" && git push
    1. It should show modified: themes/hugo-theme-relearn (new commits) when running git status to confirm that the theme is being updated.
  8. The site should deploy with the new theme.

Setting Up Backups

To provide extra security, you can also set up a live backup of your textbook to be hosted on GitHub. This page gives the instructions for setting this up.

Create GitHub Repository

  1. If you haven’t already, ask another textbook author to join the ksu-cs-textbooks organization on GitHub.
  2. Create a new repository on the ksu-cs-textbooks organization on GitHub.
    1. The name of the repository should match the desired URL for your textbook (e.g. https://ksu-cs-textbooks.github.io/<repo_name>)
    2. Do not initialize the repository with a README file.
    3. The repository itself should be private.

Mirror GitLab Repository to GitHub

  1. On the CS GitLab Server, open the repository and go to the Settings -> Repository menu.
  2. Expand the Mirroring Repositories section.
  3. In the Git repository URL, enter the SSH URL for the GitHub repository in the box.
    1. You must add ssh:// to the front of the repository, and also change the colon between the hostname and the organization name to a slash /.
    2. For example, git@github.com:ksu-cs-textbooks/hugo-starter.git becomes ssh://git@github.com/ksu-cs-textbooks/hugo-starter.git
  4. For Mirror Direction choose Push
  5. Click the Detect Host Keys button. It should show a key fingerprint for GitHub in a few seconds. THIS IS IMPORTANT! There is no way to do this after the fact.
  6. For Authentication Method choose SSH Public Key.
  7. Do not check Keep divergent refs - since we don’t want to commit directly to GitHub, we don’t need this.
  8. Checkmark Mirror only protected branches. Only the main or master branch will be mirrored.
  9. Click Mirror Repository to save the settings.

Once that is done, you’ll need to add an SSH public key to your GitHub Account.

  1. Click the Copy SSH Public Key button in the list of mirrored repositories on GitLab.

SSH Public Key Button SSH Public Key Button

  1. On GitHub, navigate to Settings -> SSH and GPG Keys
  2. Click New SSH Key and paste that key. Give it a name like CS GitLab <Textbook> to help keep track of it.
  3. Click Add SSH Key to save it.
  4. Go back to GitLab, and click the Update Now button (right next to the Copy SSH Public Key button). That will try to mirror the repository. After a few seconds, you should see the content appear in GitHub.

Update the Website

In order to properly build the backup site on GitHub, several changes must be made to the existing website directory.

  1. Create a folder .github to store GitHub specific configuration files.
  2. Create the file .github/workflows/gh-pages.yml with the following content:
# https://github.com/peaceiris/actions-hugo

name: GitHub Pages

on:
  push:
    branches:
      - main  # Set a branch to deploy
  pull_request:

jobs:
  deploy:
    runs-on: ubuntu-20.04
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: '0.101.0'
          # extended: true

      - name: Build
        run: hugo -b "https://ksu-cs-textbooks.github.io/hugo-starter"

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        if: ${{ github.ref == 'refs/heads/main' }}
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public

Update the -b "https://ksu-cs-textbooks.github.io/hugo-starter" to match the URL where the site will be deployed (e.g. https://ksu-cs-textbooks.github.io/<repo_name>)

Update the two instances of main to master if needed to match your repository configuration. You can also update the value of the hugo-version variable to match your desired Hugo version.

Note

For more advanced configuration, copy config.toml to github.toml and then edit that file to update the baseURL and other settings. Update the command to hugo --config github.toml to use that configuration file for deployment on GitHub.

  1. [Optional] Create the file .github/dependabot.yml with the following content:
version: 2
updates:
  # Maintain dependencies for GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"
  # Git Submodules
  - package-ecosystem: "gitsubmodule"
    directory: "/"
    schedule:
      interval: "daily"

This will help keep any underlying GitHub actions updated, and it will also send emails when the theme has been updated.

  1. Once these changes are made, commit and push them to GitLab. You should also see them mirrored to GitHub as well.

Configure GitHub Pages Environment

Now that the site has the required GitHub configuration, we need to set up GitHub Pages to deploy the rendered site.

  1. Once the site is updated, GitHub should automatically run the gh-pages action. You can click the Actions tab on GitHub to see that the action completed successfully.
  2. On the GitHub repository, click the Settings tab and navigate to the Pages option.
  3. Under the Branch heading, choose the gh-pages branch and the / (root) folder, then click Save

GitHub Pages Configuration GitHub Pages Configuration

  1. After a minute or so, the GitHub Pages deployment should finish. On the main repository page, you should see is as an active environment on the right side.
  2. Once that is done, you can click on the github-pages environment, and click View Deployment to see the live version of the site.

Add to Homepage

The textbook backups are listed on the homepage available at https://ksu-cs-textbooks.github.io/. That page can be updated by editing this index.html page in the base repository. Anyone who is an owner of the group should be able to edit it. When you commit an edit to that page, it will automatically deploy and update.

Switching to New Theme

Warning

This page gives instructions for switching an existing textbook using the previous theme to the new version of Hugo Theme Relearn. Only use these instructions once per textbook!

Update Hugo

The new theme requires Hugo version 0.101.0 or higher. Install Hugo from the Hugo Releases.

Installing the Theme

Install the new theme as a git submodule:

git submodule add https://github.com/ksu-cs-textbooks/hugo-theme-relearn.git themes/hugo-theme-relearn

Updating the Configuration

  1. Copy config.toml to config.toml.bak as a backup.
  2. Replace the content in config.toml with the content from the config.toml from the starter site.
  3. Customize config.toml to match the desired site configuration (refer to the config.toml.bak as needed).
    1. Update the baseURL at the top to match the URL where the site will eventually be deployed.
    2. Update the title to match the site’s name
    3. Under [params], update the following:
      1. editURL to match the location where files can be edited in GitLab or GitHub.
      2. author used for metadata
      3. description used for metadata
      4. commitURL to match the location where individual commits can be found.
      5. Most of the parameters are documented in the Hugo Theme Relearn Documentation
      6. Add any custom parameters used in the previous site.
  4. Once all updates have been made, delete the config.toml.bak file.

Updating Other Configurations

Depending on how the site is used, the following other configuration updates must be made.

GitHub Backups

If the site is set up for GitHub backups, there are two options:

  1. If github.toml is present, and you’d like to continue using multiple configuration files, replace it with the current contents of the config.toml file and update the baseURL to match what was previously in the github.toml file (e.g. https://ksu-cs-textbooks.github.io/<repo_name>). Ensure that the hugo command in .github/workflows/gh-pages.yml is hugo --config github.toml so that the correct file will be used.
  2. If github.toml is not present, or you’d like to simplify the configuration, set the hugo command in the .github/workflows/gh-pages.yml file to be hugo -b "https://ksu-cs-textbooks.github.io/<repo_name>" and update <repo_name> to match the correct URL. This will use the config.toml file but override the baseURL when building it.

In addition, you should confirm that the hugo-version setting in .github/workflows/gh-pages.yml is set to 0.101.0.

Docker images

If the site is set up to build Docker images, there are two options:

  1. If docker.toml is present, and you’d like to continue using multiple configuration files, replace it with the current contents of the config.toml file and update the baseURL to match what was previously in the docker.toml file (e.g. https://<name>.textbooks.cs.ksu.edu). Ensure that the hugo command in the Dockerfile is hugo --config docker.toml so that the correct file will be used.
  2. If docker.toml is not present, or you’d like to simplify the configuration, set the hugo command in the Dockerfile to be hugo -b "https://<name>.textbooks.cs.ksu.edu" and update <name> to match the correct URL. This will use the config.toml file but override the baseURL when building it.

In addition, you should confirm that the HUGO_VERSION argument in the Dockerfile is set to 0.101.0.

Finally, since we aren’t currently using Docker images yet, you may wish to configure your textbook to only create a Docker image when a new tag is pushed, or disable this completely for the time being. See the Docker Container page for more information.

Updating layouts

If the site has overridden any layouts in the layouts folder, they should be reviewed and updated as needed.

  • layouts/partials/logo.html - the default logo will use the title from the config.toml file as a clickable link. If this is desired, then delete layouts/partials/logo.html. Otherwise, update it using the following templates as a guide:

Static Text

<a id="logo" href="{{ .Site.Home.RelPermalink | default ("/" | relLangURL) }}">
  Hugo Starter
</a>

Logo Image

<a id="logo" href="{{ .Site.Home.RelPermalink | default ("/" | relLangURL) }}">
    <img src="/images/logo.png" alt="Logo" style="width: 100%">
</a>
  • layouts/partials/menu-footer.html - the default menu footer gives information about the site and the CC-BY-NC-SA license. If this is desired, then delete the layouts/partials/menu-footer.html from the site. Otherwise, update it using the following templates as a guide (change only the second paragraph to your desired license information).
Note

The footer works best with a bit of inline HTML to fix the design. I left it this way since it was easier to override than trying to adjust it in the base theme, since updates to the base theme’s CSS may cause issues.

Default Footer

<style>
#footer {
	font-size: 13px;
	margin-left: auto;
	margin-right: auto;
	padding: 2rem 1rem;
	min-width: 230px;
	max-width: 300px;
}
#footer p {
	margin: 0;
}
</style>

<p>Built using <a href="http://gohugo.io/">Hugo</a> and <a href="https://github.com/ksu-cs-textbooks/hugo-theme-relearn">Hugo Relearn Theme</a>.</p>
<p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0; margin: .5rem auto" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.</a></p>

CC Course Footer with License and Attribution Info

<style>
#footer {
    font-size: 13px;
    margin-left: auto;
    margin-right: auto;
    padding: 2rem 1rem;
    min-width: 230px;
    max-width: 300px;
}
#footer p {
    margin: 0;
}
</style>
    
<p>Built using <a href="http://gohugo.io/">Hugo</a> and <a href="https://github.com/ksu-cs-textbooks/hugo-theme-relearn">Hugo Relearn Theme</a>.</p>
<p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0; margin: .5rem auto" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.</a> See <a href="https://core.cs.ksu.edu/license">License & Attribution</a> for details.</p>

Front Matter Changes

By default, the site will now create a printable version of all pages. To remove a page or group of pages from the printed view (such as announcements or assignments pages), add noprint = true (TOML) or noprint: true (YAML) to the front matter of a page or chapter. Any pages beneath that page in the tree will not be included in the print view. By default, all hidden pages will also not be included (but they also won’t be visible in the sidebar menu).

The template no longer includes code for the section: true front matter option - it should be switched to chapter: true to get the chapter header formatting, otherwise it can be removed entirely.

The date option is no longer used. It can be deleted or ignored.

See the Hugo Theme Relearn Documentation or Hugo Documentation for more on how to use the front matter of each page.

Note

This may be an incomplete list of front matter changes - if you run into additional front matter issues when upgrading, let me know and I’ll update this document.

Content Changes

LaTeX Math

Hugo Theme Relearn changed the way that LaTeX math is handled in markdown. Now it is best to either include it in a shortcode or a code fence instead of just using dollar signs $ directly in the markdown. See the Hugo Theme Relearn Documentation for additional details.

In general, any inline LaTeX using single dollar signs $ should be wrapped with the new math shortcode, as in $e^x$.

For multiline LaTeX using two dollar signs $$, use the math codefence:

$$ e^{i \pi} + 1 = 0 $$ $$ sin^2(x) + cos^2(x) = tan^2(x) $$

Shortcode Changes

Click here for Complete Shortcode Documentation. The following shortcodes should be reviewed for updates:

New Shortcodes

  • syllabus - this is a new shortcode to replace the previous include shortcodes for default syllabus statements. See the Syllabus Shortcode Documentation for how to use it.
  • quizdown - this is an implementation of the Quizdown plugin to add short quizzes to the site.

Updated Shortcodes

  • include - this shortcode should now use the < > delimiters instead of % %. Using < > will prevent the Markdown renderer from rendering the content twice, resulting in extra spacing around URLs and other strange formatting issues. See Shortcodes for more information on the different shortcode delimiters. See Custom Include Shortcode Documentation and Default Include Shortcode Documentation for more details on the shortcode itself. It should now support other shortcodes in included files! I recommend running a quick search for something like {% include and {%include to catch most of these and review them on the rendered site before committing.
Note

If you are including files from the previous theme, such as the default syllabus statements, you should update the path to the new theme or consider using the new syllabus shortcode for this.

Deprecated Shortcodes

  • link - the link shortcode has been removed. Now, the default HTML renderer is configured to have a link either open in the same tab if it is a local link (does not have http in the URL), otherwise it will open in a new tab if the link goes to an external site. See Link Shortcode for more information. All links can now be converted to standard Markdown syntax [Link Name](link_url) or replaced with an HTML <a href="link_url" target="_blank" rel="noopener">Link Name</a> tag. You may also want to review the relref function in Hugo to generate relative links to pages within the site that use the correct base URL.
  • norender - the norender shortcode has been removed. It can be replaced by enclosing the content in a <pre> </pre> HTML element.
  • static - the static shortcode has been removed. Any files in the /static folder within the site are now accessible using direct URLs. For example, a file at /static/images/logo.png can be included using ![Logo](/images/logo.png). As long as the baseURL and canonifyURLs settings in config.toml are correct, Hugo will automatically update these URLs to the correct path.
Note

This may be an incomplete list of shortcode changes - if you run into additional shortcode issues when upgrading, let me know and I’ll update this document.

Preview Content

At this point, you should preview the content in your site using hugo serve and ensure that it looks correct. If everything is working properly, then continue. If not, feel free to contact the theme maintainer for assistance.

Update Deployment

Warning

As of August 2022, the server has not been updated to use a newer version of Hugo by default. Therefore, before deploying an updated site, contact one of the server administrators to have your site’s webhook updated to use the deploy-101.sh deployment script, which uses the new version of Hugo.

Commit and Push to Test Deployment

If everything is working correctly, you should be able to commit and push. Make sure that everything has deployed and updated properly. You may have to clear your browser’s cache using CTRL+F5 or CMD+F5 to get the latest version of the CSS file.

If anything doesn’t look correct, contact the theme maintainer for assistance.

Removing the Old Theme

Once everything is working properly, you should remove the old theme from your repository using these commands:

git rm themes/ksucs-hugo-theme
rm -rf .git/modules/themes/ksucs-hugo-theme
git config --remove-section submodule.themes/ksucs-hugo-theme

After making those changes, commit and push.

Updating Other Copies of the Repository

After updating the textbook on one system, it is recommended to delete and re-clone the repository on any other systems that are using it. That will give the cleanest version of the updated repository without any residual files from the previous theme. Run these commands starting outside of the site’s directory, where <directory> is the directory containing the site.

rm -rvf <directory>
git clone <url> <directory>
cd <directory>
git submodule init
git pull --recurse

Cloning an Existing Textbook

The instructions to clone an existing textbook are simple, but require a few extra steps compared to a normal git repository setup.

The basic version is to run these commands, where <directory> is the directory where the site should be stored:

git clone <url> <directory>
cd <directory>
git submodule init
git pull --recurse

These commands do the following:

  • git clone <url> <directory> will clone the existing git repository at <url> into the local directory <directory>.
  • cd <directory> will change the current working directory to be the directory where the site is stored.
  • git submodule init will initialize the submodules for this repository. We use git submodules to keep track of the theme and make it easy to update the theme as needed.
  • git pull --recurse will pull the latest version of the repository AND the theme. The theme will be locked to a specific version unless you go through the steps to Update the Theme.

Creating a Docker Container

The Hugo textbooks can also be deployed into a Docker container.

Dockerfile

  1. Create a file named Dockerfile in the site’s base directory with the following content:
FROM nginx:alpine as build

RUN apk add --update \
    wget git
    
ARG HUGO_VERSION="0.101.0"
RUN wget --quiet "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz" && \
    tar xzf hugo_${HUGO_VERSION}_Linux-64bit.tar.gz && \
    rm -r hugo_${HUGO_VERSION}_Linux-64bit.tar.gz && \
    mv hugo /usr/bin

COPY ./ /site
WORKDIR /site
RUN hugo -b "https://hugo-starter.textbooks.cs.ksu.edu"

#Copy static files to Nginx
FROM nginx:alpine
COPY --from=build /site/public /usr/share/nginx/html

WORKDIR /usr/share/nginx/html
  1. Update the following items in this file to match your desired configuration:
    1. The HUGO_VERSION argument should be set to the version of Hugo used for the site.
    2. The RUN command should include the URL that the site will be deployed to after the -b flag. Alternatively, copy config.toml to docker.toml and update the baseURL setting (as well as any other settings as desired), and use RUN hugo --config docker.toml instead.

You can find more information on setting up a Dockerfile in the Dockerfile Reference.

Build Docker on GitLab

Docker images can be built using GitLab. The organization or repository on GitLab must be configured with a GitLab Runner. This has already been done in most GitLab organizations on the CS GitLab server that contain textbooks.

  1. Create the file .gitlab-ci.yml in the site’s base directory with the following content:
image: docker:20.10.11

variables:
  # When using dind service, you must instruct docker to talk with the
  # daemon started inside of the service. The daemon is available with
  # a network connection instead of the default /var/run/docker.sock socket.
  #
  # The 'docker' hostname is the alias of the service container as described at
  # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services
  #
  # If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
  # the variable must be set to tcp://localhost:2375 because of how the
  # Kubernetes executor connects services to the job container
  # DOCKER_HOST: tcp://localhost:2375
  #
  DOCKER_HOST: tcp://docker:2375
  #
  # This instructs Docker not to start over TLS.
  DOCKER_TLS_CERTDIR: ""
  # 
  # Checkout submodules recursively
  GIT_SUBMODULE_STRATEGY: recursive

services:
  - docker:20.10.11-dind

before_script:
  - docker info
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

build-latest:
  stage: build
  only:
    - tags
  script:
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    - docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - docker push $CI_REGISTRY_IMAGE:latest

# build-branches:
#   stage: build
#   except:
#     - master
#     - main
#   script:
#     - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_BRANCH || true
#     - docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_BRANCH .
#     - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
#     - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_BRANCH
  1. Update the following items in this file to match your desired configuration:
    1. Under the build-latest job, it uses - tags under the only heading. This will only build a Docker container when a new tag is pushed. This reduces the number of containers built, since it is a time-consuming job. You can change this to the following to have it build anytime changes are made to the main or master branches:
only:
  - main
  - master
  1. You can also enable additional jobs:
    1. The build-branches job is commented out. This will build a Docker container for each branch that is tagged using the branch name. This can be uncommented if you’d like to build Docker containers based on a branch. (Likewise, the except section can be replaced with an only section to target specific branches.)

More information on the GitLab CI file can be found in the GitLab Documentation

Warning

You should also enable package cleanup in GitLab by going to the Settings -> Packages and Registries menu in the repository and turning on Clean Up Image Tags. This will clean up all tags older than 90 days, except for the last 10 tags. The latest tag will be kept indefinitely until replaced by a new version. This will help save space on GitLab as images are built and replaced.

Build Docker on GitHub

Docker images can be built using GitHub.

  1. Create a file .github/worflows/docker-image.yml with the following content:
name: Docker Image CI

on:
  push:
    tags:
      - "v*.*.*"

jobs:

  build:
    runs-on: ubuntu-latest
    steps:

    - uses: actions/checkout@v3
      with:
        submodules: recursive
        fetch-depth: 0
      
    - name: Login to GitHub Container Registry
      uses: docker/login-action@v1 
      with:
        registry: ghcr.io
        username: ${{ github.repository_owner }}
        password: ${{ secrets.GITHUB_TOKEN }}
    - name: Build and push
      uses: docker/build-push-action@v2
      with:
        context: .
        push: true
        tags: |
            ghcr.io/${{ github.repository}}:latest            
  1. Update the following items in this file to match your desired configuration:
    1. Under the push heading, it is configured to run this only when a new tag is pushed that matches Semantic Versioning structure. You can change this to the following to have it build anytime changes are made to the main or master branches:
push:
    branches: [ master, main ]

This can also be configured to send notifications to Discord on a successful deployment, and it can also trigger a webhook after deployment. See this example for how to configure those options. It requires creation of GitHub Action Secrets for the Discord webhook and deployment webhook.

More information can be found on the GitHub Actions Documentation.

Warning

As of this writing, GitHub will store all previous versions of this package, and there is no automatic way to delete older packages outside of using another GitHub action. So, if you choose to go this route, you may have to deal with manually cleaning up old packages at some point in the future if you run out of space on GitHub.

Update 2023

In Summer 2023 this theme was updated to match version 5.18.0 of the base Hugo Relearn Theme

New Features

A full list of changes to the theme can be found on the What’s New page and in the Documentation.

Some notable feature updates:

Warning

Currently the template will sometimes include hidden pages in the menu when using hugo serve locally, but this does not affect any deployed versions of the site. To resolve this problem, disable fast rendering using hugo serve --disableFastRender.

Upgrading

To upgrade to the new theme version, do the following:

  1. Navigate to the themes/hugo-theme-relearn directory
  2. Use git pull to pull the latest version of the theme
  3. Navigate back to the root directory of your site.
  4. Commit and push the site. It should see a new version of the themes/hugo-theme-relearn submodule.

To enable the new search features, update the [outputs] section of the config.toml (and other files like docker.toml and github.toml if present) to the following:

[outputs]
  home = ["HTML", "RSS", "PRINT", "SEARCH", "SEARCHPAGE"]
  section = ["HTML", "RSS", "PRINT", "TELE", "EMBED"]
  page = ["HTML", "RSS", "PRINT", "TELE", "EMBED"]

Enable Auto Theme Variants

To enable automatically detecting theme variants based on the user’s OS preferences, find the themeVariant item under [params] in the config.toml (and other files like docker.toml and github.toml if present) and replace that line with the following:

  themeVariant = ["auto", "light-theme", "dark-theme"]
  # The first element is the variant for light mode, the second for dark mode
  themeVariantAuto = ["light-theme", "dark-theme"]

Deprecated Chapter Features

Many of the previous textbooks use the old method for creating chapters by placing chapter = true in the frontmatter. This has been deprecated in favor of using the new archetype = "chapter" setting. See the documentation for details.

Unfortunately, the way that the new archetype system assigns chapter numbers is using the weight parameter. Many of our books use non-sequential weights to make it simpler to add pages later. This theme adds support for an ordinal value in the frontmatter to allow overriding this value.

To get rid of the deprecation warnings, find all pages that contain chapter = true and make the following updates:

  1. Replace chapter = true with archetype = "chapter" in the page’s frontmatter
  2. Remove the top-level headers. Typically these pages would include an h1 and h3 header. These are now generated by the archetype.
  3. OPTIONAL: Add an ordinal = "X" line to the frontmatter, and replace the X with the chapter number.

For example, a chapter with the following content:

+++
title = "Basic Content"
weight = 5
chapter = true
pre = "<b>0. </b>"
+++

### Chapter 0

# Basic Content

The Basics of this Template

should be updated to match this format:

+++
title = "Basic Content"
weight = 5
ordinal = "0"
archetype = "chapter"
pre = "<b>0. </b>"
+++

The Basics of this Template

Update 2024

In Summer 2024 this theme was updated to match version 6.0.0 of the base Hugo Relearn Theme

New Features

A full list of changes to the theme can be found on the What’s New page and in the Documentation.

Some notable feature updates:

In addition, the theme now supports installation via Hugo Modules as well as Git Submodules. We plan to migrate all textbooks to a Hugo Modules setup since it is more portable and easy to configure. More Information.

Upgrading and Switching to Hugo Modules

To Upgrade the theme and switch from a Git Submodule to a Hugo Module, do the following:

  1. Ensure that a recent version of Go and Git is installed.
  2. Install Hugo v0.126.1 or later.
  3. Initialize the Hugo Module system. The name of the module doesn’t matter since it won’t be used - just use the name of the repository, such as hugo mod init cis598-textbook. This should create a file go.mod listing the name of the module and the version of go used.
    1. The module import is already defined at the bottom of the new hugo.toml file and doesn’t need to be configured.
  4. In the textbook directory, remove the submodule using git rm themes/hugo-theme-relearn. This should remove that directory as well as update the .gitmodules file to remove the submodule. If desired, also delete the themes directory itself using rmdir themes.
  5. Create a new file hugo.toml using this sample file as a template.
    1. Look for items labelled # TODO changeme to see what settings should be updated for each site. Many settings can be carried over from the existing config.toml but some settings are new. Configuration Documentation.
    2. One recommendation is to use the Todo Tree extension in VS Code, which will highlight comments containing TODO and other keywords, making them easy to find.
    3. The theme has changed how URLs are handled for sites served in subdirectories (such as textbooks.cs.ksu.edu/cis598). The canonifyURLs setting is deprecated and should be set to false, along with the relativeURLs setting set to false. This may break some image links - see below.
  6. Once the configuration is updated in hugo.toml, delete the existing config.toml as it is no longer needed.
  7. Install the Hugo module using hugo mod get -u. This should install the module and create a file go.sum that includes the checksums of the module dependencies.
    1. In the future, use hugo mod get to get the current version specified, or hugo mod get -u to update the version to the latest in GitHub.
    2. Running hugo serve or hugo build will also install the module if needed.
  8. Check for files such as Dockerfile, .github/workflows/gh_pages.yml, .gitlab-ci.yml or similar and update the version of Hugo to v0.126.1.
    1. Sample Dockerfile that works with Hugo modules instead of git submodules.

Before testing the site, there are a few content changes that must be made.

Content Changes

Updates to ref and relref shortcode

In newer versions of Hugo, the ref and relref shortcode must be delimited using % % instead of < >. Many of our textbooks use the old delimiter. This will result in errors such as this when building the textbook:

ERROR "/home/russfeld/web/cis598-textbook/content/0-introduction/01-syllabus/_index.md": link 'HAAHUGOSHORTCODE14s0HBHB' is not a page
WARN  "/home/russfeld/web/cis598-textbook/content/b-schedule/01-fall2022.md": WARNING you must call the ref / relref shortcode with '% %' instead of '< >' to work correctly for the anchor target attribute

To fix this, the following regex find/replace can be used in VS Code:

Search:

\{\{<\s*(rel)?ref ([^>]*)\s*>\}\}

Replace:

{{% $1ref $2 %}}

These errors can be switched to warnings in hugo.toml but it is best to deal with them directly so they don’t cause problems in the future.

Updates to youtube shortcode

The youtube shortcode may also need to be updated as described above, but in the other direction.

To fix this, the following regex find/replace can be used in VS Code:

Search:

\{\{%\s*youtube (.*)\s*%\}\}

Replace:

{{< youtube $1 >}}

Updates to Images and Other Resources

Newer versions of Hugo can also verify the path of any images and resources included in the page. This is helpful for finding broken links or missing images. Unfortunately, it cannot verify any items stored in the static directory since it is not processed through the content pipeline. Many of our textbooks store all images and resources in the static folder, which is fine, but it means that the build process cannot verify that there aren’t any missing items or broken links.

To fix this, there are a few options:

  1. In hugo.toml, the errors can be switched to warnings or disabled entirely. By default, all checks are set to error except for images, which are set to warning. Read the documentation in hugo.toml to determine what options are preferred.
  2. Images and resources in the static folder can be moved to the assets folder. Ideally the links won’t need to be changed if the images are linked using an absolute reference path (e.g. images/1/image.png). This is the simplest fix
  3. Images and resources in the static folder can be moved to the content folder near the page where they are used. It is recommended to convert any standalone pages to page bundles that contain the page and all associated resources.

For example, the CIS 598 textbook contains a page 01-fall2022.md that contains links to many images in the static folder:

Old Page Layout Old Page Layout

To switch this to a page bundle, create a folder 01-fall2022 and then move the 01-fall2022.md file inside of that folder and rename it to index.md. Then, create an images folder within, and move all of the images from static to the new folder. The resulting layout should be:

New Page Layout New Page Layout

Using this method, all image links on the page can be updated by a quick find and replace to replace /images/fall2022/ with just images/ - removing the leading slash / and the subfolder name used in the old static/images path.

Disabling the canonifyURLs option will break all image links in any Reveal.js slides that are using the /images path prefix. The previous behavior would simply prepend the subdirectory in front of any URL starting with a /.

There are two workarounds:

  1. A quick fix is to a find/replace for the /images/ path in the slides and prepend the subdirectory to the path, as in /cis598/images/. This works as long as the site baseURL is not changed. This requires the images to remain in the static folder unless they are referenced by other markdown files. Generally I just copy images from static to assets to fix the problem above but leave a copy in the static folder as well. Hugo will merge the two.
  2. Another workaround would be to move the images into a page bundle as described above, and then convert the /images URLs to be ../images (or whatever relative path is correct). The ref and relref shortcodes cannot be used in this context. This works regardless of the site baseURL setting.

If the site includes an image in the layouts/partials/logo.html page, you can suppress the error by loading the image as a resource from the assets directory instead of the static directory.

{{/* Place Logo Graphic or Text Here */}}
{{ $image := resources.Get "images/cc410logo.png" }}
<a id="logo" href="{{ .Site.Home.RelPermalink | default ("/" | relLangURL) }}">
    <img src="{{ $image.RelPermalink }}" alt="Computational Core Logo" style="width: 100%">
</a>