This lesson is in the early stages of development (Alpha version)

Building Websites with GitLab

Introduction

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • What is static web content?

  • Why should I use GitHub or GitLab Pages to create my website?

Objectives
  • Explain what a static site generator does.

  • Choose the appropriate tool for your website/project.

How Websites Work

When we use a web browser to visit a page on the World-Wide Web, the browser asks for information from a server - a computer storing the data relevant to the site and configured to receive and respond to requests for that data. Assuming there were no problems at this stage (e.g. asking for a page which doesn’t exist, or being unable to reach the server), our browser receives and interprets this information to render and display the webpage on our screen.

A web developer would probably be horrified to read such a gross oversimplification, which is just one reason why web developers are not the target audience of this tutorial.

The page displayed by the web browser is the result of combining HTML - a hierarchical format describing the structural elements of the page and their raw content - with CSS - an ordered set of styling instructions telling the browser how the content should be organised and formatted - and any images that should be embedded in the page. Other information received from the server, but not displayed by the browser, includes metadata, cookies, and other non-visible elements in the HTML - information about the site that could be relevant for a computer but probably isn’t interesting to a human (there are exceptions to this) - and scripts that the browser may run to do something in response to various triggers.

Hello World in HTML

When learning a new programming language, you may often find a reference to the popular Hello world example. These examples typically capture the simplest code that can produce and display the text “Hello, World!” on screen.

As HTML requires certain tags to be present and almost always in matching pairs (open <tag> and closing </tag>), HTML documents tend to get verbose rather quickly.

The simplest, valid HTML Hello world is:

<!DOCTYPE html>
<html>
  <head>
    <title>Page title</title>
  </head>
  <body>
    <p>Hello, World!</p>
  </body>
</html>

So as you can imagine, writing long HTML documents by hand is rather painful. Notice that we didn’t specify anything about how and where the text should be displayed.

To achieve this we would additionally need to include stylized tags or Cascading Style Sheets (CSS) instructions. If you do not provide CSS instructions (either inside your HTML document or as a separate file), a web browser will make a best guess regarding the layout of HTML elements on the page based on its defaults.

The Many Tags in HTML

In the Hello world example above 5 different tags are used (html, head, title, body and p) in their open <> and closed </> form. We see also the special doctype tag that indicates the format and version of the document, in this case, [HTML(5)][html5-wikipedia].

Many other tags exist to define:

  • structural elements, such as table, div, span, nav, section;
  • lists, such as ul (for unordered lists) and or (for ordered lists);
  • stylized elements, such as i/em (for italics/emphasis), b/strong (for bold) and u (for underlined text);
  • headings, numbered from h1 to h6 for titles and progressively smaller sub-titles;
  • media elements, such as img, video, audio to embed rich media content; and
  • links, using the important a (anchor) tag to link to sections in the same page or other pages within the same or external websites.

The list of valid HTML tags is rather extensive, covering a rich range of features powering today’s world wide web.

Exercise: Writing Basic HTML

Given the stylized text:

Hello, World!

write the HTML that will produce the same result. Hint the big font is achieved by use of a heading.

Solution

<h1><em>Hello</em>, World!</h1>

Let’s write a more complex HTML example using a table showing the “Hello, World!” text in different languages that renders like: HTML table example

The HTML to produce such a table looks like this (you can copy+paste the snippet into the HTML file you created in the previous example):

<table>
    <tr><th>Language</th><th>Text</th></tr>
    <tr><td>English</td><td>Hello, World!</td></tr>
    <tr><td>French</td><td>Bonjour, le monde!</td></tr>
    <tr><td>Portuguese</td><td>Olá, Mundo!</td></tr>
    <tr><td>Serbian</td><td>Zdravo, svete!</td></tr>
</table>

Each row is enclosed between table row <tr> and </tr> tags. Within a row, <th> and </th> tags are used to contain table headings (special table cells displayed in bold font), while regular table data cells are contained within <td> and </td> tags.

A similar example written using HTML lists would look as follows: HTML list example

<ul>
    <li>English: Hello, World!</li>
    <li>French: Bonjour, le monde!</li>
    <li>Portuguese: Olá, Mundo!</li>
    <li>Serbian: Zdravo, svete!</li>
</ul>

Here, we used unordered list tags <ul> and </ul> to define a list with 4 items, each in turn wrapped in individual list item (<li> and </li>) tags.

Static vs Dynamic Sites

Static pages are those whose contents are stored on a server in a state ready to be sent to any user who makes a request for that web page. When a request is made, the server only needs to send the information comprising that web page (such as HTML and CSS). Sites that do not change often, such as a website containing one’s CV, are often stored as static sites.

Conversely, dynamic sites are those that have their pages generated when a user makes a request for a web page. Depending on when the request is made, the content might change; for example, clicking refresh when viewing a discussion in a web forum might result in new comments showing up. The key difference is that static pages need only be generated once, after which they rest unchanged on the server, compared to dynamic pages which are regenerated by a server every time it receives a request.

Examples in the Life Sciences field

A typical example of static website in the Life Science field would be the documentation of a tool or a file format, such as this page at wwpdb.org.

Entry pages of the PDB database, instead, differently load content on the basis of the visualisation tools and options chosen by the user. A database or a webserver is usually a dynamic website.

This lesson focuses on static sites and tools that can be used to create them, known as Static Site Generators.

One of the advantages of using static site generators is that they remove the need for us to manually produce a lot of HTML, allowing us to focus on the human-readable content we want our pages to contain. However, we still need a way to tell the generator how we want our content to look when it’s displayed in the browser. For that, we will use a tool called Markdown, which we’ll learn about in a following episode.

Pages can be created in several ways: static server-side generation (where HTML is generated once on the server and doesn't
change thereafter), dynamic server-side generation (where the server can update and send new HTML based on requests from
the user's browser), and client-side generation (where parts of HTML pages are generated by the browser using Javascript code)

Figure 1.1: Page Generation Alternatives. This figure is a modified version of the original published in JavaScript for Data Science, and is reproduced here with permission from the author.

Static-generated sites are a great choice when the information you want to display on a website is the same regardless of who visits your site and when, and if the content of your pages is unlikely to need to change very often. This makes Static Site Generators a good choice for sites that provide documentation or lesson content like this page: the aim of the page is to deliver the same information to every visitor. The visitor can arrive, (hopefully) find and read what they need, and leave feeling happy and fulfilled.

Dynamic sites provide a lot more possibilities for providing interactivity and personalised or topical content. But creating them is a degree more complicated and also places considerable additional burden on the server, not least in terms of computational requirements and security considerations. Among other things this means that, unlike with static pages (see the rest of this lesson), you’re unlikely to find cost-free platforms to help you deliver dynamic content.

Exercise: The Perfect Tool for the Job

Given the following types of websites, reason if a static site generator is an appropriate solution to implement them.

  • (1) A personal website with About and Projects sections
  • (2) A forum or discussion platform
  • (3) A community blog or news website
  • (4) A search engine (such as google.com)
  • (5) A wiki (such as wikipedia.com)
  • (6) An online book

Solution

  • (1) personal website: In most cases, Yes. This kind of content is typically written/edited by one person and meant to have a read-only access to visitors.
  • (2) forum or discussion: Most likely No. Such website requires interactivity and ways to identify who wrote what content.

For questions 3 and 5 the answer is both Yes and No depending on the requirements and necessary functionality.

  • (3) blog/news: A simple blog or news website, maintained by a small set of users, is perfectly achievable by using a static generator. For very large groups of content creators or if access to articles needs to be controlled individually, using a static generator will lead to difficult technical challenges.
  • (4) search engine: Most often No. Implementing something as sophisticated as Google’s search would be close to impossible with a static generator. There are ways to have a simple engine that searches across all pages produced by a static generator using indexing and making clever use of browser features but this approach has many limitations.
  • (5) wiki: A simple wiki is perfectly doable with a static generator (e.g. GitHub Wiki Pages), however it becomes limiting as soon as its content needs to be edited or discussed by many users, as is the case of Wikipedia.
  • (6) online book: Definitely Yes. Static generators are perfect for this type of website. They typically provide ways to avoid repeating content (variables and templates), automatic creation of a Table Of Contents, among other goodies.

GitLab Pages

If the site you want to create is a good match to the strengths of a static site generator - it’s relatively small, will be updated infrequently, and the content does not need to be personalised to the visitor - then creating it with GitLab Pages is a good option. GitLab Pages is a system allowing users to create and serve websites directly from their GitLab repositories. The service is free for public repositories and simple pages can be created and served with very little configuration required.

We will go through a list of templates, of increasing complexity. While the first will be based on plain Markdown, the more advanced ones will be based on multiple technologies (an example is shown in the diagram below). It may sound overwhelming at first but we will explain most of these technologies in this lesson - we only don’t cover CSS/Sass (styling language that gets compiled into CSS) and JavaScript/CoffeeScript (scripting language that gets compiled into JavaScript) in detail.

Static websites in GitHub Pages technology overview diagram

First, we are going to set up a project to store our files and learn more about how to author and format the content of our pages using HTML and Markdown, before configuring GitLab to display this content as a website using GitLab Pages.

Setting Up a Project

Before we get into working we must first create a project to work in. This project is similar to a folder on your computer, the main differences being that the folder lives on the web in GitLab/GitHub (though you can also keep a copy on your computer if needed) and that folder is using a version control software called git to track changes to the files. For our purposes we will mostly be ignoring the version control software, though it can be handy if you need to revert to old versions (see Software Carpentry - Version Control with Git for an introduction). In this lesson we will be working with this folder on the web to control the website we will be creating.

Login into your GitLab account

Before you can create a repo, you will need to login in the EMBL GitLab

There are two ways of creating a new project:

Click the “+” button in the navbar on top and choose “new project”

Plus button

or, if you are on the projects page, click the “New project” button

New project button

You will be redirected to a page that provides three options:

  1. Create blank project
  2. Create from template
  3. Import project Take your time to read the descriptions of the different cases. Please select “Create blank project”.

Next you will need to fill in some info about your project.

Blank new repository page

In this lesson, we will be working on a general group website. You can imagine this website may be for your lab group, a specific project group, or another group you work with. Under the “Project name” field, type group-website.

The Project slug will determine the URL to access your project and website, it is automatically generated when you fill the Project name field. Leave it as is.

Have a look at the dropdown menu next in the Project URL field. The default option is your own user, this refers to your own namespace. Other namespaces might be available, depending on which groups you belong to. For example, if this is planned to be your group website, it may be a good choice to select your group namespace to host it. This both to provide easy access to the project to other group members and to have your group name (and not your user name) in the website URL. However, we will initialise this test projects in our own namespace.

We can also add a description (for instance “Project for learning how to make websites with GitLab pages”) so we know what this project is when we find it again after the workshop.

We will also check the Initialize repository with a README option. It is good practice to have a README file that gives more information about your repo.

GitLab vs GitHub

Most of the steps here described are very similar in GitHub. What GitLab calls “Project”, in GitHub is a “Repository”, so if your instructor confuses the two terms here is why. In addition, the “Groups” are in GitLab “organisations”.

More relevant are the differences regarding the visibility level and setup options. In GitHub, only two options are available for a repository: “Public” or “Private”. The EMBL GitLab allows a more specific fine tuning of the permissions through the option “Internal”, i.e. accessible only by logged in user. Finally, while GitLab only allows to initialize the repository with a README, GitHub includes the option to initialise it with a .gitignore and license files too.

Once you’ve finished these steps you can click the Create Project button. GitLab will then setup the repo and it should create the repo called group-website with a README.md file in it. What the graphical interface just helped us doing, is basically the following steps:

mkdir group-website
cd group-website
git init
cat > README.md
git add README.md
git commit -m "Initial commit"

On a remote server. The default branch is main.

Github repository for the group website

Before moving on to the next chapter, have a look at the buttons on top, such as Add LICENSE, Add CHANGELOG etc., suggesting you possible next steps. To name one, the License is definitely something you might want to include in your project. We will not be looking into this in detail, but please consider that licensing is a good practice (if not a necessary one) for any project that includes data or software. Your website, even if a very simple and static one, will include some sort of data, even just people names. The technologies and templates you will use to generate it are software. A word to the wise.

Key Points

  • A static site generator combines page-specific content with layout elements and styling information to construct individual webpages.

  • GitHub/GitLab Pages is a good choice for people who are already familiar with Git and GitHub/GitLab.

  • This approach can be used to create a relatively small website/blog on a limited budget.


Authoring With Markdown

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • How can I write content for my webpages?

  • How do I link to other pages?

Objectives
  • create simple pages of formatted text

Markdown

Markdown is a lightweight markup language, i.e. a convention for adding style information to textual content. As the name Markdown indicates, the syntax elements of this language are shut down to a minimum. Having a rather minimalistic syntax, text formatted in Markdown is comparably readable. This might be one reason for Markdown having become the language of choice for formatted user input on websites like, for example:

Where to Start Writing Markdown?

A lot of tools for rendering Markdown source code exist. Rendering is the process of generating a nice view of the content using the style information included in the source text. Chances are high, your editor can do this. As we are working towards authoring websites using GitLab pages, we will use GitLab straight away for learning the basics of Markdown. The GitLab project you created in the last episode contains a file README.md. Click on the file name to access it.

The image below shows the default view. This view includes a rendered view of the content inside the file README.md, like the one in our project homepage.

README preview

The buttons on the right allow you to interact with the file and visualisation. The first couple of buttons, the ones with the icons, allow you to switch between Display source and Display rendered file. Over with the mouse on them to display these two messages in tooltips. The source is the non rendered view of our file. We can edit it through the blue Edit button. Click it.

Editing interface of the group websites README file

We can change the content and have a look at the rendered view by clicking the Preview tab on top.

Preview of the rendered content of the group websites README file

Let’s add Some **bold** font and see what happens when we preview it using the preview tab. What happened to the world bold?

To save the content to the file README.md, we should click the Commit changes button at the bottom of the page. Please notice: this is not a simple “Save” button, but an actual commit. This version of the project will be stored in git with the Commit message that you will specify in the commit menu here and in the branch you settle as Target branch. We only have the main branch for the moment - so that choice is obvious - and the commit message is precompiled with the name of the file you just edited. You may want to be more specific in your commit message, but for the moment let’s go with the default option provided. Commit this change.

Writing a Commit Message

A commit message is a short, descriptive, and specific comment that will help us remember later on what we did and why. You find more about writing commit message in this section of the Git-novice lesson.

After commiting README changes

The interface redirects you to the main project page. On the top, a message says “Your changes have been successfully committed.” Our changes were included in the README file, that now shows the second line with the bold font.

Writing Markdown

Now that we know about the editing interface and preview tab of our projects README.md we can use it as a text editor and investigate selected Markdown features.

Our README.md already contains text and two formatting features:

Let’s learn some more Markdown by adding some formatting and see what happens when we preview it using the preview tab. Add the following to your README.md file.

# group-website
Repo for learning how to make websites with GitLab pages

## Learning Markdown

Vanilla text may contain *italics* and **bold words**.

This paragraph is separated from the previous one by a blank line.
Line breaks
are caused by two trailing spaces at the end of a line.

[Carpentries Webpage](https://carpentries.org/)

### Carpentries Lesson Programs:
- Software Carpentry
- Data Carpentry
- Library Carpentry

You can then click the preview tab again to see how the formatting renders.

Preview of the formatting added to the README

Markdown Trailing Spaces Are Meaningful

In the example above there are two spaces at the end of Line breaks . These introduce what is called a hard line break, causing that paragraph to continue in the next line by adding a <br/> to the generated HTML.

If you break the line in a markdown file but don’t include the two trailing spaces the generated HTML will continue in the same line without introducing a <br/>. This is called a soft line break.

In some cases you may find that soft line breaks do introduce a <br/>. This can happen when using different markdown flavors.

You can commit these changes to save them. But first, let’s do an exercise to try out writing more markdown.

Exercise: Try Out Markdown

Use this cheatsheet to add the following to your README.md:

Example Solution

For example your markdown might look like the following:

## More info on the lesson
You can find this lesson [here](https://grp-bio-it-workshops.embl-community.io/building-websites-with-gitlab/).

### Four reasons you should learn Markdown:

1. Less formatting than HTML
2. Easy to read even with formatting
3. Commonly used for websites and software development
4. We ~~don't~~ use it in The Carpentries

![Carpentries Logo](https://github.com/carpentries/carpentries.org/raw/main/images/TheCarpentries-opengraph.png)

Up to now, we have used inline-style links which have the URL inline with the description text, for example:

[Carpentries Webpage](https://carpentries.org/)

If you use a link more than once, consider using so called reference-style links instead. Reference-style links reference the URL via a label. The label goes into square brackets [ ] right after the description text of the link and then later, usually at the bottom of the page, you can connect that label to the url it references to complete the link. This looks like:

[Carpentries Webpage][carpentries]

[carpentries]: https://carpentries.org/

We will continue to use Markdown and learn more throughout the rest of the lesson. Whether you decide to structure your website through Markdown-based technologies or HTML, you will still need to know some basics of Markdown to edit your README file. The README file will provide an essential guide - shown in the landing page of your project - for your collaborators and also for you to understand what the project is about and how to contribute.

Markdown Flavours

The initial description of Markdown was informal and contained certain ambiguities so over the years different Markdown implementations and syntax variations (often referred to as “flavours”) appeared to support various syntax features and extensions. As a consequence, the syntax from one variant may not be interpreted as expected in another - you have to be aware which one is being used by a particular platform. Here are a few well-known variants:

Mardown is also the language of the collaborative notes platform available at EMBL. You can acces it here. The platform is based on CodiMD.

Exercise: Add Your Repository Details to CodiMD

Use Markdown syntax to add a link in the collaborative notes document you are using to follow along with this lesson. The link text should be your GitLab username, and the target your repository.

Key Points

  • Markdown is an relatively easy way to write formatted text

  • Markdown and HTML tags can be used together in a single page

  • I recommend writing Markdown links ‘reference-style’

  • The landing page for a website is conventionally named index.md


Hosting Pages on GitLab

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • How do I publish my pages via GitLab?

Objectives
  • publish HTML on the web with GitLab Pages

GitLab pages

Static websites only

As anticipated by the previous chapters, to publish a website with GitLab Pages you can use several different technologies like Jekyll, Gatsby, Hugo, Middleman, Harp, Hexo, and Brunch, just to name a few. You can also publish any static website written directly in plain HTML, CSS, and JavaScript. Pages does not support dynamic server-side processing, for instance, as .php and .asp requires.

The key to having your website up and running as expected is the GitLab CI configuration file, called .gitlab-ci.yml. This file configures how your website will be built. It is written in YAML, which has its own syntax that we will not explain into details, so we recommend you follow this quick start guide before setting it up. To work correctly, it needs to be placed at your root directory, i.e. at the same level of our README file, in the main project folder.

The most important fact is that with GitLab CI, you take control over your builds. They won’t be in an invisible black box where you don’t know what is going on! You will be able to see any build running live by navigating to your project’s Pipelines (we will do this later). You can also add any command to your .gitlab-ci.yml script. This allows you to do in the remote server pretty much anything you do on your local machine. We will how some examples on how to run custom build commands through the .gitlab-ci.yml. file later on in this lesson.

Work locally or in GitLab

This lesson isn’t aiming to teach Git and how to work locally (in your laptop) on a project versioned and managed in Git. If you have a basic understanding of Git, however, you can do the next steps locally to learn how to properly develop a website: testing it locally and only committing and pushing significant versions of it. On the contrary, working on the online platform will force us to commit versions that will not be very meaningful, for the sake of learning.

If you have a basic understanding of Git, configuring a local project for deployment. Clone your repository locally (check the git novice lesson if you need to review what the git clone command does and how to git push changes from local to remote projects). In short, you should now run, from a terminal:

git clone https://git.embl.de/<your username>/group-website.git
cd group-website

And keep working in your cloned directory. You can add and edit your files via vim or from any editor that you like - it doesn’t have to be launched from the terminal, but remember to keep the terminal open for when you will have to push the changes back to the remote.

We will start with the simplest example, a plain HTML site with GitLab pages.

Let’s create the .gitlab-ci.yml file directly in our GitLab project online. We will need to work on multiple files. To do so, we want to open the Web IDE by clicking the button on the top right of our project: Edit > Web IDE.

Edit IDE

If this is the first time that you open it, a customisation panel will appear. Ignore it for now, but know that the look-and-feel of the next screenshots might differ from what you see based on the default template. You should however have the same menus and files available for use. In particular, the EXPLORER (a file explorer) on the right side lists files and folders in your repository (at the moment, there should only be the README file), and the panel on the right shows the content of such files when you open them.

Over the mouse on the name of your project in the EXPLORER to see a small menu including an icon to add files to the folder. Click on that and create a .gitlab-ci.yml file. Then, fill it with the following content:

Create your .gitlab-ci.yml file and write in it:

pages:
  stage: deploy
  script:
    - echo 'Nothing to do...'
  artifacts:
    paths:
      - public
  only:
    - main

What this code is doing is creating a job called “pages” telling GitLab to deploy the website content in public, whenever a commit is pushed and only to the main branch. It doesn’t have much to do but looking at the content in public, hence the “script” configuration is basically none (it just echoes “Nothing to do” to the terminal).

Validating the gitlab-ci.yml file

Before you push any .gitlab-ci.yml to your project, you can validate its syntax with the tool called CI Lint. You need to be logged into your account to have access to this tool. It’s found by navigating to your project’s Pipelines: there is a button at the top-right of your screen. You can read through the full documentation for .gitlab-ci.yml for more information.

Git branches and GitLab CI files

You can have a distinct .gitlab-ci.yml for each project - but you could even have distinct GitLab CI configurations for each branch. This means you could test your script in parallel branches before pushing to your main branch. If the build succeeds, you merge. If it doesn’t, you can make adjustments and try building again without messing up your main branch.

Next, we will create the public folder (use the new folder icon in the EXPLORER menu), containing an index.html file.

Work locally or in GitLab

If you are working locally, you can do so from the terminal through:

mkdir public
cat > public/index.html

Populate the new file index.html with this content:

<html>
    <head>
        <title>Home</title>
    </head>
    <body>
        <h1>Hello World!</h1>
    </body>
</html>

Before we go on with the chapter, try to imagine what will be the final display in the resulting webpage. You can draw it in a piece of paper.

Work locally or in GitLab

If you are working locally, now commit and push your changes. You can do so from the main project folder through:

git add .
git commit -m "simple html in public"
git push -u origin main

If you created the .gitlab-ci.yml file, and the public folder containing the index.html file, you should see all of them in the EXPLORER. Now, let’s save the first version of our project (commit), by selecting the Source control menu on the left side.

IDE version control button

This will change the panel on the left, which will list the files that we changed (two files added) and expect you to input a commit message (a short description of the project version that you are committing) in the textbox above. Our commit message in this case could be: “Deploy simple HTML through GitLab pipeline”. Input this or another message, and then Commit to 'main'.

IDE version control

Go back to your remote project in GitLab. The screenshot below shows how it should look like:

Simple HTML project screenshot

The public folder contains the index.html file. The push command you just launched should have triggered your first pipeline. On the menu on the left, choose Build > Pipelines to visualise it.

First running pipeline

Since we stopped and checked what our remote folder looked like, your pipeline may already be passed. If not, just wait until it becomes so.

Your first website was deployed successfully! Wonder where you can see it? Go to Deploy > Pages. The URL of your website is reported there. It should be: https://<your user name>.embl-community.io/group-website.

The Page URL in Settings>Pages

The screenshot below also contains an interesting alert. Always read this type of messages prompted by the GitLab interface, these are usually relevant to you. It says “Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project’s Settings > General > Visibility and select Everyone in pages section.” It also links to further documentation if you want to know more. Follow the instructions if you would like to make your website public.

Wheter it’s public or not, we should be able to visualise our own website. Click on the link, and here it is:

Simple website view

Exercise: Compare with your sketch

Does the website you just deployed look as you thought it would, given the html code in the index file? Did you think that something else would be shown? Discuss with the colleague next to you.

Exercise: The plain-html template

GitLab provides a series of templates of web pages deployed through Pages. One of them is called “plain-html”, you can access it at this link. The general structure is quite similar to the one we just used. Go to the public folder. There are two files here, one style.css file and one index.html file.

We will now go into the detail of .css file functioning in this lesson, but it might be interesting now to have a look at its syntax and content. This type of file is used to style HTML content. This specific file provides styling instructions for three elements: the body, the navbar and the link text (a) within the navbar, that changes color when the mouse is over it (a:hover). Don’t worry now about understanding how this works exactly, but when you will visualise this page, remember to go with the mouse over the navbar links to see this in action.

Now open the index.html file. Its content is reported below.

<!DOCTYPE html>
<html>
 <head>
   <meta charset="utf-8">
   <meta name="generator" content="GitLab Pages">
   <title>Plain HTML site using GitLab Pages</title>
   <link rel="stylesheet" href="style.css">
 </head>
 <body>
   <div class="navbar">
     <a href="https://pages.gitlab.io/plain-html/">Plain HTML Example</a>
     <a href="https://gitlab.com/pages/plain-html/">Repository</a>
     <a href="https://gitlab.com/pages/">Other Examples</a>
   </div>

   <h1>Hello World!</h1>

   <p>
     This is a simple plain-HTML website on GitLab Pages, without any fancy static site generator.
   </p>
 </body>
</html>

Time to sketch again! Draw the resulting webpage, provided this HTML file content. Hint: the navbar is a bar on the top of the page, that allows us to navigate the website content.

Optional question: how is the .css file used? How does the website know which is the right file to read?

Solution

You can go to the deployed website to check how does it look like. Here below a screenshot of the result:

Plain HTML template

Is there any difference with your sketch?

Optional question: the .css file location is specified in the .html file, through: <link rel="stylesheet" href="style.css">.

You have the minimal tools now to be able to play around with HTML and css. You can copy the two files from the last exercise template into your repository and try to edit the text size, the navbar color, add links or text formatting. If you decide to fork this repository to experiment, please do as the authors ask in their README file (one more reason to consult the README files in each other projects and to compile them carefully): “If you forked this project for your own use, please go to your project’s Settings and remove the forking relationship, which won’t be necessary unless you want to contribute back to the upstream project.”

An extensive tutorial about HTML elements, including examples of forms, media and links embedding, can be found at w3schools. In addition to this one, many other resources provide HTML tutorials, you can definitely choose one that fits your tastes to learn more.

Key Points

  • GitLab serves pages in your project according to a configuration file called .gitlab-ci.yml


GitLab Pages with Jekyll

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • How do I publish web pages through GitLab and Jekyll?

Objectives
  • Publish Markdown files as HTML on the web with GitHub Pages

Jekyll is a powerful static site generator that may be behind GitLab Pages. It creates static HTML website content out of various files in your repository (Markdown files, CSS style sheets, page templates/layouts, etc.). This ‘compiled’ content is then served as your website.

Jekyll makes managing your website easier because it depends on templates. Templates (or layouts in Jekyll notation) are blueprints that can be reused by multiple pages. For example, we (your instructors) did not style each single exercise in this lesson separately: we created a template that specify how exercises should be shown (the orange box, the dropdown solution box etc.) and every time we tag a block of text as “Exercise” it is shown this way.

We will cover Jekyll layouts in a bit; for now let’s start learning Jekyll and its scripting language called Liquid.

Global Parameters

Also in this case, we will trigger and customise our deployment from the .gitlab-ci.yml file. You can decide to edit your previous version of the group-website repository, but we suggest to create a new one. Follow the steps in “Setting up a project” in the introduction if you want to do so. Create/change the .gitlab-ci.yml file content with:

image: ruby:latest

pages:
  script:
    - gem install bundler
    - bundle install
    - bundle exec jekyll build -d public
  artifacts:
    paths:
      - public
  only:
    - main

This code requires the script to run on the environment of the latest Ruby version, installs the Jekyll gem, and builds the site to the public path (creating the folder remotely, you should not worry about it at this point). The result affects only the main branch.

The execution of this pipeline also requires a Gemfile. Create it in the root folder with the following content:

source "https://rubygems.org"

gem "jekyll"

In brief, but we will look into it in more detail, Jekyll looks for text files that begin with a header formatted like this:

---
variable: value
other_variable: other_value
---

...stuff in the page...

and inserts the values of those variables into the page when formatting it. The three dashes that start the header must be the first three characters in the file: even a single space before them will make Jekyll ignore the file.

The header’s content must be formatted as YAML, and may contain Booleans, numbers, character strings, lists, and dictionaries of name/value pairs. Values from the header are referred to in the page as page.variable. For example, this page:

---
name: Science
---
Today we are going to study {{page.name}}.

is translated into:

<html>
  <body>
    <p>Today we are going to study Science.</p>
  </body>
</html>

Exercise: Jekyll’s syntax

Test your understanding of Jekyll’s syntax. What would this template will be translated into?

---
name: Tom
location: Heidelberg
---
{{page.name}} is in {{page.location}}. I believe {{page.location}} is a very nice city.

Solution

<html>
  <body>
    <p>Tom is in Heidelberg. I believe Heidelberg us a very nice city.</p>
  </body>
</html>

Jekyll’s main configuration options are specified however in another file, called _config.yml. Let’s create some configuration parameters for our website.

  1. Create a _config.yml file in your site’s root directory.
  2. Add parameters description and email to it as:
description: This project develops training materials for reseachers wanting to learn to build project
websites in GitLab Pages.
email: team@carpentries.org

Global configuration settings from _config.yml are made available as site.PARAMETER_NAME variable in every page within the website. So, global parameter email we defined above would be accessed as site.email. Please note: this are global paramenters, hence different from the local page-specific parameters in the examples above.

In order to access the parameter’s value within a page, you use Liquid’s notation to output content by surrounding a variable in curly braces as {{ variable }}.

Predefined Global Parameters

In addition to the global parameters you define, Jekyll also makes a number of useful predefined site-wide variables available to you within your website: e.g. {{ site.time }} (the current time) or {{ site.pages }} (a list of all pages).

Create a index.md file in the root folder, with the following content:

---
title: My first Jekyll page
---

# Building Websites with Jekyll and GitLab

## Description
{{ site.description }}
Welcome to {{ page.title }}

Have any questions about what we do? [We'd love to hear from you!](mailto:{{ site.email }})

Your project should include the following files:

Basic Jekyll

Commit and push your changes, then monitor the pipeline execution and check the final result at your https://<your user name>.embl-community.io/group-website URL.

Exercise: Create a Global Twitter Parameter

In about.md we have a Twitter URL under the ‘Contact us’ section. That’s one piece of information that could go into global parameters in _config.yml as you may want to repeat it on a footer of every page. Make changes to your website to extract Twitter URL as a global parameter.

Solution

  1. Add parameter twitter to _config.yml:
    description: "This research project develops training materials for reseachers wanting to learn to build project
    websites in GitHub with GitHub Pages."
    email: "team@carpentries.org"
    twitter: "https://twitter.com/thecarpentries"
    
  2. Make use of the twitter parameter in about.md:

    # About
    
    ## Project
    
    {{ site.description }}
    
    ## Funders
    
    We gratefully acknowledge funding from the XYZ Founding Council, under grant number 'abc'.
    
    ## Cite us
    
    You can cite the project as:
    
    > *The Carpentries 2019 Annual Report. Zenodo. https://doi.org/10.5281/zenodo.3840372*
    
    ## Contact us
    
    - Email: [{{ site.email }}](mailto:{{ site.email }})
    - Twitter: [{{ site.twitter }}]({{ site.twitter }})
    
  3. Note that you should not see any changes to your website really. However, you can now access your Twitter URL from any website page, should you need to.

Local Parameters

In addition to global (site-wide) parameters available via the site global variable, Jekyll makes local (page-specific) information available to you via the page variable. Some of these are pre-defined - like page.title, which gives you the title of the page that is currently active/being visited. Others you can define yourself. Check this list of predefined page parameters.

You can define local parameters using YAML notation within a Markdown page by including it in a page header and delimiting the header with triple-dashed lines ---. These headers are called front matter and are used to set variables and metadata on individual pages in your Jekyll site.

Front matter

From Jekyll’s website:

Any file that contains a YAML front matter block will be processed by Jekyll as a special file. The front matter must be the first thing in the file and must take the form of valid YAML set between triple-dashed lines.

Global and Local Parameters Are Case Sensitive

It is important to note that the parameters used in the sites are case sensitive. By convention, usually they are all lowercase characters.

Here is an example:

---
layout: post
title: "My first blog post"
author: "Danger Mouse"
---

Between these triple-dashed lines, you can overwrite predefined variables (like page.layout or page.title) or create custom ones you need locally on the page (like page.author). These variables will then be available for you to access using Liquid’s tags (e.g. {{ page.title }} ) further down in the file and also in any files that include this one. Note that these variables are only accessible on that page. You will get an error if you try to reference a page.variable that was defined on a different page.

Exercise: Practice With Local Variables

Let’s practice making and using local variables. Think of a local variable you may want to use only in your about.md or index.md page. If you cannot think of any, create a local variable called ‘lesson-example’ with the value of ‘https://carpentries.github.io/lesson-example/’ and reference it in your index.md.

What did you add to your index.md to create this variable? Where did you add the front matter in your index.md? How did you reference that variable?

Solution

Create a YAML header at the very top of index.md and add the lesson-example variable in between the triple-dash delimiters. You can then reference the value within your index.md page as {{ page.lesson-example }}. Your file should now look like:

---
lesson-example: "https://carpentries.github.io/lesson-example/"
---

# Building Websites in GitHub

## Description
{{ site.description }}

More details about the project are available from the [About page](about).

See some [examples of our work]({{ page.lesson-example }}).

Have any questions about what we do? [We'd love to hear from you!](mailto:{{ site.email }})

Note that this variable is not accessible from about.md page and is local to index.md.

Adding new pages

The next step will be to create another page of this website. Ideally, our website will have multiple pages and therefore, to keep things in order, we will create the pages folder to store them. In this folder, create an about.md file with the following content:

---
title: About
permalink: /about/
---

# About

## Project

{{ site.description }}

## Funders

We gratefully acknowledge funding from the XYZ Founding Council, under grant number 'abc'.

## Cite us

You can cite the project as:

>    *The Carpentries 2019 Annual Report. Zenodo. https://doi.org/10.5281/zenodo.3840372*

## Contact us

- Email: [{{ site.email }}](mailto:{{ site.email }})
- Twitter: [@thecarpentries](https://twitter.com/thecarpentries)

Note that the URL location of this page is specified in the header, through the permalink attribute.

This is the current aspect of your folders:

About Jekyll

Now, we should edit the index.md file to include a link to this new about page, in order to be able to reach it from the main page. Add a line the index.md to include:

More details about the project are available from the [About page](about).

The link in this line will redirect to https://<your user name>.embl-community.io/group-website/about, that is the URL of our new about page.

Commit, push and go to your website to see the changes. Note that site parameters will not render nicely when viewing files in GitHub (they will be displayed as text {{ site.PARAMETER_NAME }} rather than the parameter’s rendered value) but will in the website.

Reuse and Reduce

Jekyll’s global parameters are a useful way to keep all your site-wide configuration in a single place (even if you only use them once). In combination with Jekyll layouts/templates (to be covered in the next episode) they are a great way of creating reusable markup snippets that can be repeated on multiple or even on every page of your website. Reuse helps you reduce the amount of code you have to write.

This was just meant to be a very basic tutorial. The possibility of sites customisation with Jekyll go far beyond what shown here, you could for example:

and more. This lesson from The Carpentries, even if designed for GitHub, is a valuable resource to learn more about how to do so.

If you are looking for the official GitLab documentation about GitLab Pages with Jekyll, follow this link.

Finally, this project contains a more elaborated template of a GitLab and Jekyll based website.

Key Points

  • Through Jekyll, GitLab serves pages are generated from .md files


GitLab Pages with Sphinx

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • How do I publish web pages through GitLab and Sphinx?

Objectives
  • Publish reStructuredText files as HTML on the web with GitHub Pages

Sphinx is a tool to generate webpages or PDF, mainly designed to create a project documentation. It was originally created for the Python documentation, but it has excellent facilities for the documentation of software projects in a range of languages. Polyglot documentation systems might be very useful in case your project increases in complexity or number of collaborators, so take a note about this.

In this chapter of the lesson we will use Python programming language. Even if this is not strictly necessary, we suggest you to familiarise with Python - as explaining it falls outside the purpose of this lesson. You can choose to do so by going through The Carpentries lesson Programming with Python.

Exercise: Documentation

In a group, have each member open one of the following packages’ documentation

Discuss what the common components are, what is helpful about these documentation sites, how they address the general concepts on documentation, how they’re similar and how they’re different.

While Jekyll converts Markdown files (.md) into HTML, Sphinx converts reStructureText files (.rts). While these two formats might seem very similar at a first glance, they were created for two different purposes: Markdown to write for the web, reStructuredText to write documentation. This blog post provides more insights about what this means in practice, the most important point that we would like to highlight in this context is that reStructuredText is well-suited for the conversion to PDF too. This makes it a useful tool also for the development of documents you may need both online and in paper copies, for example training materials or a meeting agenda.

Sphinx quickstart

In sake of clarity, the next steps of this chapter will only focus on Sphinx files that are relevant for the HTML files generation. However, by installing Sphinx locally you can run the quickstart command to init a basic Sphinx project. We highly recommend this option if you would like to further your understanding of how to document with Sphinx. To this aim, we report here the necessary steps.

Your system probably has Sphinx already installed. Check if so by typing in your terminal:

sphinx-build --version

If it isn’t, you will be able to installing by typing:

pip install -U sphinx

Or check more detailed installation instructions here. Once Sphinx is installed, we can run the quickstart command to get an overview of the minimal set of files that are necessary to build the documentation. The following command will create an empty repository and run this command there:

mkdir sphinx-quickstart-test
cd sphinx-quickstart-test
sphinx-quickstart
...
Separate source and build directories (y/n) [n]:
...
Project name: My project
Author name(s): <Your name>
Project release []:
...
Project language [en]:

Several documents will be generated. Here an overview:

Sphinx quickstart

The files that are relevant to us in this context are the index.rst file - that is the equivalent of our index.md file in the example with Jekyll - and the conf.py file. This is why the lesson goes through them only.

Create an empty project folder. Let’s initialise our index.rst file in our project’s root folder.

.. this is a comment, it is not rendered

Sphinx Example Project's documentation
======================================

Contents:

.. toctree::
    :maxdepth: 2

It reports our project main heading, and then a table of contents through the “TOC tree”. A numeric maxdepth option may be given (we initalised it at 2) to indicate the depth of the tree; by default, all levels are included. More about Toc tree at this link. In short, when adding *.rst files to our table of content, they should be listed here. Let’s add a file to see how this works.

Create a about.rst file, also in the main root folder, with the content:

About
=====

Hello, this is the about page of my project.

Now let’s add this file to the TOC tree by editing the index.rst file:

.. this is a comment, it is not rendered

Sphinx Example Project's documentation
======================================

Contents:

.. toctree::
    :maxdepth: 2

    about.rst

That’s it: our home page (generate with the index.rst file) will now link to the About page (about.rst). Next, let’s write a minimal conf.py file, also in the root directory.

# -- Project information -----------------------------------------------------

project = 'My project'
copyright = '2021, <Your name>'
author = '<Your name>'
release = '1.0'

# -- Options for HTML output -------------------------------------------------

html_theme = 'alabaster'

For a full list of options that can be specified in this file, check the documentation.

Sphinx quickstart

Once again, having Sphinx locally installed will support you through the next stages. Indeed, you can build your documentation website locally through the command sphinx-build . build/ to be run in your root folder. Once run, it will generate your output website in the build/ folder. You can visualize it simply by opening the index.html file through your favourite browser.

Also in this case, the .gitlab-ci.yml file is necessary to specify instructions for GitLab deployment. Fill it with:

pages:
  stage: deploy
  image: python:3.6
  script:
    - pip install -U sphinx
    - sphinx-build -b html . public
  artifacts:
    paths:
      - public

This script: specifies the container for our pipeline (Python, version 3.6), installs Sphinx through Pip, run the command sphinx-build - that builds HTML files in the root folder (.) to a public folder that it also creates. Finally, it specifies where to find the HTML artifacts (in the public folder indeed).

That’s all set. Now we should once again follow the “Setting up a project” in the introduction to set up a remote project in GitLab, set it as remote for our local folder with git remote add origin <git URL>, git add . && git commit -m <message> and then git push -u. Finally, monitor your pipeline execution and check the final result.

Key Points

  • Through Sphinx, GitLab serves pages are generated from .rst files


GitLab Pages with Jupyter books

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • How do I publish web pages through GitLab and Jupyter books?

Objectives
  • Publish Jupyter notebooks as HTML on the web with GitHub Pages

Let’s do something different, that will sound a little more familiar if you are used to the Jupyter projects. From their website:

Project Jupyter exists to develop open-source software, open-standards, and services for interactive computing across dozens of programming languages.

Jupyter notebooks allow you to create and share documents containing live code as well as narrative text. Jupyter Lab expand their functionalities by creating and interactive development environment (allowing you to navigate your file system and define the coding environment). Jupyter Hub is a multi-user version of Jupyer Lab that institutions can implement locally (as we at EMBL did).

And Jupyer book?

Jupyter Book is an open source project for building beautiful, publication-quality books and documents from computational material.

The extensive tutorial will guide you through the installation steps and detailed customisation available, in the context of this lesson we are going to cover just the basics. First things first, let’s install Jupyter Book. In your terminal:

pip install -U jupyter-book

Please note: you will need to have pip installed too. Now, let’s create our first book project. The jupyter-book --help command would help us in checking the options here, but this lesson will spoiler something: the

jupyter-book create jupyter-book-demo

command will create a basic Jupyter book in a jupyter-book-demo folder. This folder already includes the three things needed for building a book: a _config.yml file, a _toc.yml table of content and the book’s content in a collection of MarkDown, reStructuredText or Jupyter Notebook files.

Since we are getting tired of all of this development and deployment, we don’t really want to edit anything in the content, but we prioritise having it up and running in GitLab instead. Just guess, what do we need to add? A .gitlab-ci.yml file indeed.

pages:
  stage: deploy
  image: python:slim
  script:
    - pip install -U jupyter-book
    - jupyter-book clean .
    - jupyter-book build .
    - mv _build/html public
  artifacts:
    paths:
      - public

This piece of code:

  1. Installs jupyter-book (or checks that it is correctly installed remotely).
  2. Cleans the folder from files resulting from (eventual) previous builds.
  3. runs the command jupyter-book build ., which builds the book in the folder into a _build subfolder. You can check the output by running the same command in your terminal, and you will realise that the actual HTML files are in the subfolder _build/html.
  4. It then moves the HTML content into our usual public folder where the artifacts are stored.

Your time to experiment with a template

This template is deliberately minimal to give you the opportunity to test your documentation reading skills. Check the topic guides at jupyterbook.org and find a way to:

  1. Add another page called “About” and linked from the table of contents.
  2. Play with the file format of this new page, add the same type of content in MarkDown, reStructuredTex and Notebook formats.
  3. Add one figure and a figure caption.
  4. Insert a code cell. If you are familiar with any programming language, add a simple plot and visualise the output of such plot into your page.
  5. For more advanced code features, check how to make the code executable
  6. Check the gallery of Jupyter books for inspiration!

Key Points

  • Through Jupyter books, you’ll be able to integrate interactive components and code in your web pages


GitLab Templates

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • Where can I find pre-built projects/themes for my site?

Objectives
  • Find and fork pre-existing templates to determine the technologies behind a project and the styles of the deriving website

Bio-IT templates

The templates that we developed together are available in our GitLab platform:

They might be slightly enriched compared to what we went through during this lesson, for example the plain HTML template also features a .css file, but they are kept minimal on purpose. If you want to use them as a base for your own project, you should fork them. If you do so to develop your own project, and not to contribute to the template itself, you should next remove the fork relationship. Let’s go through the process together.

fork a repository through the Fork button

Fork a project by clicking the “Fork” button on the right side of the project title. This will open a menu (shown below) very similar to the one that prompts when you open a new project. You can decide to keep your project private, and edit the title and description. You can also place it in the relevant group/namespace.

the fork project menu

Once you are done, please remove the fork relationship. You can edit the project settings on the left side menu on the project page, follow: Settings > General > Advanced and then scroll down to the “Remove fork relationship” card.

remove fork relationship

Once this is done, you can clone your repository locally and start editing the template. If you need a recap about cloning, forking, pushing and pulling in Git please check this lesson by The Carpentries.

More templates

Wonder where you can find more examples of GitLab pages projects? Check this link. It includes more than 40 examples, based on multiple technologies. Also in those cases, it is good a practice to remove the fork relationship if your aim is to use the template for the development of your own website, and not to contribute to the template itself. Some examples of template you will find in this repository are:

Now you have all the expertise required to start playing with GitLab pages. Feel free to contact us if you have any question or open an issue in the template projects to request for features or to raise issues. You are also welcomed to contribute to the development of pages templates, both the ones existing and new ones that may fit your use cases. Finally, check the next (bonus) chapter to know how to deal with errors in pipeline execution to be able to troubleshoot eventual CI/CD errors!

Key Points

  • You can find many pre-existing templates for sites on the Internet

  • You can find the presented themes for sites in our local GitLab

  • You can avoid duplicated effort by basing new layouts on previous ones


When things go wrong

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • How do I troubleshoot errors in the GitLab pipelines?

Objectives
  • Get feedback from GitLab about why a pipeline failed

When Things Go Wrong

So far we have seen how to successfully use various technologies to produce a website. There are however some situations where they may fail to do so either due to a typo or missing information. We will go through one of these cases with a Jekyll example.

Exercise: Troubleshooting Jekyll

This exercise will help you recognise what common mistakes look like when working with these elements of a Jekyll website.

Edit your _config.yml file and substitute a : with a = character in one of the variables.

Solution

For instance, mail=team@carpentries.org instead of mail:team@carpentries.org.

description: "This research project develops training materials for reseachers wanting to learn to build project
websites in GitHub with GitHub Pages."
email: "team@carpentries.org"
twitter: "https://twitter.com/thecarpentries

If you navigate your GitHub repository you would be able to see something break in about.md where we use {{ site.twitter }} however, contrary to what we saw before with invalid Markdown, Jekyll will refuse to build the website and produce an error message.

We will see after this where to find the error message and identify what caused them.

If you were keeping an eye on the GitLab pipeline execution page until now (CI/CD > Pipelines), you may have noticed that the once you push the pipeline results “pending”, then it starts “running”, and eventually it “passes”. Eventually. If it doesn’t, then the status is “failed”, you may receive an email about it (depending on your GitLab account settings) and you shouldn’t panic. How can we instead understand what caused the error, and fix it? The “failed” status happens to be a button, let’s click it.

click on the failed button to access the pipeline log

Once again, you can click on the ❌ pages button to access more details, i.e. the complete log of our pipeline execution. Scroll up the terminal-like window to see how it started, prepared the environments, installed dependencies and correctly executed until the command bundle exec jekyll build - public. Remember that? It is the command that launches Jekyll, we included it in the .gitlab-ci.yml file.

Based on this, we have reasons to suspect that the error here is related to Jekyll being unable to build the page. Reading more carefully in order to get more details, we find:

$ bundle exec jekyll build -d public
                    ------------------------------------------------
      Jekyll 4.2.1   Please append `--trace` to the `build` command
                     for any additional information or backtrace.
                    ------------------------------------------------
/usr/local/bundle/gems/safe_yaml-1.0.5/lib/safe_yaml/load.rb:143:in `parse': (/builds/hpg_ToyM/0/grp-bio-it/template-pages-jekyll/_config.yml): could not find expected ':' while scanning a simple key at line 3 column 1 (Psych::SyntaxError)

This means two things: first, the log suggests a way to eventually get more details, i.e. to modify the .gitlab-ci.yml file by adding --trace to the command bundle exec jekyll build -d public, that thus becomes bundle exec jekyll build -d public --trace. However, we don’t really need that: the next sentence is clear enough. It says, there was an error in parsing the _config.yml file because Jekyll could not find the expected : character. Since this typo prevents Jekyll from building the page, the process cannot continue.

Failure Will Not Remove Your Website

Given the failure you may be wondering what happened to the website? If you visit the address you will find that the website is still be available.

GitLab will keep your previous version online until the error is fixed and a new build is completed successfully.

We should go back to our _config.yml file and fix the = error we made (on purpose, this time). Then push the project again, and problem solved!

Exercise: Practice With Troubleshooting Jekyll

Sometimes typos happen and can make your website change in surprising ways. Let’s experiment with some possible issues that might come up and see what happens.

Try the changes listed below on your index.md file and see what happens when the page renders. You will want to correct the previous mistake each time.

  1. Use a global or local variable that you didn’t define first.
  2. Leave the dash off the end of the YAML header.
  3. Don’t put a space between the YAML header and the rest of the page
  4. Put the YAML header in a different location in the page.

Solution

  1. The place where you used the undefined variable is blank but otherwise no error. Example:

    Hi! {{ site.greeting }}. What have you been up to?
    
  2. The header shows somewhat in the file and the variable that was defined goes to the index page intead of the link we set.

    ---
    lesson-example: "https://carpentries.github.io/lesson-example/"
    
    Examples of our work can be found at: {{ page.lesson-example }}
    
  3. This doesn’t seem to affect our page but can often make more complex pages break.

    ---
    lesson-example: "https://carpentries.github.io/lesson-example/"
    ---
    Examples of our work can be found at: {{ page.lesson-example }}
    
  4. This also makes the header somewhat show in the page and breaks the variable link we created.

    Examples of our work can be found at: {{ page.lesson-example }}
    ---
    lesson-example: "https://carpentries.github.io/lesson-example/"
    ---
    

Note: Be sure to fix any errors you intentionally introduced in your page before moving on.

Key Points

  • If a pipeline fails, GitLab will provide you useful feedback on why