Lecture 9: Displaying Projects in a Quarto Website

BAA1028 - Workflow & Data Management

Damien Dupré

Before we proceed…

Start again from scratch!

You have made incredible progress with your eportfolio but you should not mess it up. Let’s practice on a fresh website!

In the terminal of VS Code type:

Terminal
quarto create project website baa1028-lecture9
quarto preview

Today, we will learn how to add and modify a “Projects” list of multiple projects pages

Let’s Add a Page!

  • Create a new page: /projects.qmd
  • Add some content
  • Preview: < site url >/projects.html
projects.qmd
---
title: Projects
---

{{< lipsum 1 >}}
{{< placeholder 400 400 >}}

Adding Pages

Two decisions:

  1. Structure Where will it live in your website project?
  2. Navigation How will people discover it on your website?

Structure

File path becomes URL path

File location

projects.qmd

projects/projects.qmd

URL

{ site url }/projects.html

{ site url }/projects/projects.html

index.html is special

File location

index.qmd

projects/index.qmd

URL

{ site url }

{ site url }/projects

index.qmd (or .md, or .ipynb) -> index.html

index.html acts like a default page for the site or directory.

But you aren’t limited to .html!

File location

data/monthly.csv

cv.pdf

URL

{ site url }/data/monthly.csv

{ site url }/cv.pdf

Structure helps …

  • You: Navigate and organize your content

  • Your readers: Understand context of content from its URL

Exercise 1

Add a new subfolder projects to your site and, inside this subfolder, a new page index.qmd:

index.qmd
---
title: Projects
---

{{< lipsum 1 >}}
{{< placeholder 400 400 >}}

Exercise 2

Provide links to your new page:

  • From somewhere in the content of index.qmd
  • After “Home” in the navigation bar

When things get more complicated…

Primary Navigation

Top navigation

Side navigation

Primary Navigation

Top navigation

_quarto.yml
website:
  navbar:
    left:
      - index.qmd
      - talks.qmd
      - projects/index.qmd
    tools:
      - text: GitHub
        href: http://github.com
        icon: github        

Add items to left, right and tools

Side navigation

_quarto.yml
website:
  sidebar:
    contents:
      - index.qmd
      - talks.qmd
      - projects/index.qmd
    tools:
      - text: GitHub
        href: http://github.com
        icon: github    

Add items to contents and tools

Nested Navigation

Top navigation

Side navigation

Nested Navigation

Top navigation

_quarto.yml
website:
  navbar:
    left:
      - index.qmd
      - text: Work
        menu: 
          - talks.qmd
          - projects/index.qmd

Add a text item along with menu

Side navigation

_quarto.yml
website:
  sidebar:
    contents:
      - index.qmd
      - section: Work
        contents: 
          - talks.qmd
          - projects/index.qmd

Add a section with its own contents

Hybrid Navigation

Top navigation navigates between the different “sections” of the website.

Each “section” has its own side navigation.

Hybrid Navigation

_quarto.yml
website:
  navbar:
    left:
      - index.qmd
      - text: Work
        href: talks.qmd

  sidebar:
    - title: Work
      contents:
        - talks.qmd
        - projects/index.qmd
  1. Match navbar item text to a sidebar item title
  2. List navbar item href as first value in sidebar item contents

Automatic Sidebar

If your structure is good, an automatic sidebar can go a long way:

_quarto.yml
website:
  sidebar:
    contents: auto

Pro and Cons

Side nav

  • auto: easy to generate and maintain
  • Linearly present linear content (e.g. a progression through a tutorial)
  • Can be deeply nested
  • Can handle longer entries
  • However, may show too much detail for sections that aren’t of immediate interest |

Pro and Cons

Top nav

  • First place most people look
  • However, not good for long entries, e.g. keep to short single words
  • Can’t be nested beyond one level
  • Nested content is hidden unless clicked on

Pro and Cons

Hybrid

  • Organize lots of content without overwhelming viewer
  • Harder to build and maintain |

Other navigation elements

For reference

Table of Contents

https://quarto.org/docs/output-formats/html-basics.html#table-of-contents

Controlled by format not website:

_quarto.yml
format:
  html: 
    toc: true

Project Listings

Before we proceed…

We have created a subfolder projects at the root of the website with quarto file index.qmd inside this folder.

We have referenced this projects/index.qmd in the navbar inside the _quarto.yml file.

Today, we will populate the content of projects/index.qmd with a list of different projects!

Let’s Add more Pages!

  • Create a new subfolder called list inside /projects
  • In this list sub-subfolder, create 3 quarto files: project_1.qmd, project_2.qmd, and project_3.qmd

Displaying a listing on projects/index.qmd is as simple as:

---
title: My Projects
listing: default
---

Explicit default options:

---
title: My Projects
listing:
  contents: /
  sort: "date"
  type: default
  categories: false
---

A listing is…

  • an automatically generated list of content
  • styled via a template, (built-in type, or custom template)
  • can be included on any page

Generated from documents in contents

blog/third-post/index.qmd
---
title: "First Post"
description: "Post description for first post"
author: "Alicia"
date: "5/22/2021"
image: "cover.jpg"
categories:
  - Science
  - Technology
---

Why use a listing?

  • Great for large collections
  • Great for collections that grow

Your Turn

  1. (Repeat) Make a new page blog/index.qmd which is a listing
  2. Experiment with type and categories:
    • type: grid or table
    • categories: true, unnumbered, cloud
    Other listing options
  3. Discuss with your neighbor:
    • What makes this a blog?
    • What would you change if this was a gallery of your projects?

Default

Grid

Table

Categories

true/numbered

unnumbered

cloud

Use listings for _ projects _

https://ivelasq.rbind.io/project

Use listings for _ talks _

https://meghan.rbind.io/talks/

Use listings for _ publications _

https://mickael.canouil.fr/publications

Use listings for …

https://charlotte.quarto.pub/listings/

contents can be a YAML file

projects/index.qmd
---
title: Projects
listing:
  contents: projects.yml
  type: grid
  max-description-length: 250
---
project/projects.yml
- title: Predicting House Prices with Machine Learning
  path: https://example.com/house-prices
  # Photo by Breno Assis on Unsplash https://unsplash.com/photos/aerial-photography-of-rural-r3WAWU5Fi5Q 
  image: images/breno-assis-r3WAWU5Fi5Q-unsplash.jpg
  description: >
    This project involves using machine learning algorithms to predict house prices based on
    various features such as location, size, and amenities. It includes data cleaning,
    feature engineering, and model selection.
  categories: [Python, Machine Learning, Data Cleaning]
  date: 2024-01-01
  ...

path can be a relative path to a file in your site, or a URL

You can use Listing Fields, or create custom ones.

contents can be a YAML file

Simple Customization: Select Fields

Use fields to specify which Listing Fields are displayed.

E.g. Exclude date:

listing:
  contents: projects.yml
  type: grid
  fields: ["image", "title", "categories", "description"]

Simple Customization: Rename Fields

Use field-display-names to provide a different label for a field

Mostly useful for type: table.

E.g. Rename title to Project

listing:
  contents: projects.yml
  type: table
  field-display-names: 
    title: Project

Your Turn

  1. Switch to type: table

  2. Omit the image field from the listing

  3. Change the name of the “Categories” column to “Skills”

  4. Brainstorm: What could you use a listing for on your own site?

Advanced Customization

Example: https://www.andrewheiss.com/teaching/

Source: https://github.com/andrewheiss/ath-quarto/blob/main/teaching/index.qmd

  • Listing in a custom location on a page
  • More than one listing on a page
  • Custom Template

Custom Location

teaching/index.qmd
---
title: "Teaching"
listing:
  id: ay_23-24
  contents: ay_23-24.yml
---

Give the listing an id

teaching/index.qmd
## 2023–24

:::{#ay_23-24}
:::

## 2022–23

Use the id in a fenced div where you want it to appear

Multiple Listings

teaching/index.qmd
---
title: "Teaching"
listing:
  - id: ay_23-24
    contents: ay_23-24.yml
  - id: ay_22-23
    contents: ay_22-23.yml
---

Make listing an array, use ids

teaching/index.qmd
## 2023–24

:::{#ay_23-24}
:::

## 2022–23

:::{#ay_22-23}
:::

Place listings in the page by id

Custom template

teaching/index.qmd
---
title: "Teaching"
listing:
  - id: ay_23-24
    contents: ay_23-24.yml
    template: ../html/teaching/listing.ejs
---

Provide an ejs file to template

../html/teaching/listing.ejs
```{=html}
<div class="teaching">
    <% for (const course of items) { %>
    <div class="course-entry">
        <div class="logo">
            <% if (course.url) { %>
            <a href="<%= course.url %>" target="_blank"><img src="<%= course.logo %>" alt="<%= course.title %>" title="<%= course.title %>" /></a>
            <% } else { %>
            <img src="<%= course.logo %>" alt="<%= course.title %>" title="<%= course.title %>" />
            <% } %>
        </div>
        <div class="body">
            <p class="course-title">
                <% if (course.url) { %>
                <a href="<%= course.url %>" target="_blank"><%= course.title %></a> 
                <% } else { %>
                <%= course.title %> 
                <% } %>
            </p>
            <p class="course-details">
                <span class="course-number"><%= course.number %></span> | 
                <span class="course-university"><%= course.university %></span>
                <% if (course.role) { %>
                | <span class="course-role"><%= course.role %></span>
                <% } %>
            </p>
            <p class="course-description"><%= course.description %></p>

            <ul class="course-semesters">
                <% for (const semester of course.semester) { %>
                <% if (semester.url) { %>
                <li><a href="<%= semester.url %>"><i class="fa-solid fa-building-columns"></i> <%= semester.name %></a></li>
                <% } else { %> 
                <li class="no-link"><i class="fa-solid fa-building-columns"></i> <%= semester.name %></li>
                <% } %>
                <% } %>
            </ul>
        </div>
    </div>
    <% } %>
</div>
```

Define how item in items should be generated

Your Turn

Add a listing page to your site:

  1. Create a page to house the listing

  2. Either:

    • populate a .yml file with a couple of items (use projects/project.yml as a template), or
    • create some placeholder .qmd files.
  3. Add the page to your site navigation

  4. Clean up any template listing pages/files/folders you don’t want

References

Huge thanks the following people who have generated and shared most of the content of this lecture:


Thanks for your attention and don’t hesitate to ask if you have any questions!
@damien_dupre
@damien-dupre
https://damien-dupre.github.io
damien.dupre@dcu.ie