Trio Icon
Trio v6.1.0

The Trio Blog

  1. Latest
  2. Releases
  3. News
  4. Tutorials

Advanced Page Composition And Collections: Part 2) Main Catalog Page

a web page composition abstract

Prerequisites

Before proceeding with this tutorial, please familiarize yourself with Trio's Core Concepts, Tag-Based Callbacks, Metadata, and Collections.

Also, if you haven't already installed this tutorial's starter project then please follow the instructions given in the Advanced Page Composition And Collections: Part 1) Tutorial Introduction And Starter Project Setup tutorial.

Intention Of This Tutorial

In this tutorial we will use what we have already learned about Trio's advanced page composition to create the landing page for our Flags Of The World website, which will list each flag of the world along with the geographical location that it pertains to.

Create The Template Project Asset

In the project's root/source/templates folder, first delete the .gitkeep file, and then create a new template file named catalog.html and copy and paste the following markup into that file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="../../css/main.4b032a8bb77734ada3ae34e1a6cf849f.css">
</head>
<body>
    <main class="catalog">
        <h1 class="catalog__page-title">Flags Of The World</h1>
        <ul class="catalog__list" data-trio-callback="catalog"></ul>
    </main>
</body>
</html>

Please notice that the above template project asset doesn't contains a tag that is decorated with the data-trio-fragment attribute. That is because the fragment that will be associated with this template (see below) will not be contributing any content of its own into the composite. Instead, the tag-based callback that is declared in this template's unordered list <ul> tag will be solely responsible for this composite's content, which it will dynamically generate using the data found in the root/source/data/world.json file and which it will append to the template's unordered list tag.

Create The Fragment Project Asset

In the project's root/source/fragments folder, first delete the .gitkeep file, and then create a new fragment file named index.html and copy and paste the following into that:

<!--
template: catalog
title: Home | Flags Of The World
-->

Please notice how the above fragment project asset declares front matter at the very top of the file, in which it defines:

  1. The required front matter property template with the name of the template file it is associated with and
  2. The required front matter property title with the title to be assigned to the generated document's title tag and

Also, please note that fragment project asset's front matter does not define the optional front matter property appendToTarget because the fragment is not contributing any content of its own to the composite.

And finally, please notice that though this fragment has no content of its own to contribute to the composite it is still required because, as we learned in the tutorial about basic page composition, every page that Trio generates must be defined by a project fragment asset and a project template asset.

The JSON File

In the starter project's root/source/data folder you will find the world.json file, which is an array of 249 items which contain the data for each flag of the world. The following is only a very small sample of the actual file:

[
{"id":4,"name":"Afghanistan","alpha2":"af","alpha3":"afg","img":"af.png"},
{"id":248,"name":"Åland Islands","alpha2":"ax","alpha3":"ala","img":"ax.png"},
{"id":8,"name":"Albania","alpha2":"al","alpha3":"alb","img":"al.png"},
{"id":12,"name":"Algeria","alpha2":"dz","alpha3":"dza","img":"dz.png"},
.
.
.
]

The following describes the key: value pairs of the items in the file:

  • "id" - a number, the unique id of the item
  • "name" - a string, the geographical location that this items flags pertains to, also used to sort the file in ascending "name" order
  • "alpha2" - a string, the 2 character code for the flag and its geographical location
  • "alpha3" - a string, the 3 character code for the flag and its geographical location
  • "img" - a string, the path to the flag's .png image residing in the site's media/flags/128x128/ folder

Create The Tag-Based Callback

In the project's root/source/callbacks folder, first delete the .gitkeep file, and then create a new javascript file named catalog.js and copy and paste the following into that:

/*
dataDependency: world
*/

module.exports = ({ $tag, site }) => {
    const size = "128x128";
    site.dataCatalog.world.forEach(item => {
        $tag.append(`
            <li class="catalog__list-item">
                <img src="media/flags/${size}/${item.img}" alt="${item.name} flag">
                <a class="catalog__list-item-link" href="/country/${item.name.toLowerCase()}/">
                    <p class="catalog__list-item-name">${item.name}</p>
                </a>
            </li>
        `);
    });
};

This tag-based callback does the following:

  1. It iterates over the items in the root/source/data/world.json file using:
site.dataCatalog.world.forEach(item => {
  1. Then appends each item's data to the tag in the template project asset that was decorated with the data-trio-callback tag:
$tag.append(`
    <li class="catalog__list-item">
        <img src="media/flags/${size}/${item.img}" alt="${item.name} flag">
        <a class="catalog__list-item-link" href="/country/${item.name.toLowerCase()}/">
            <p class="catalog__list-item-name">${item.name}</p>
        </a>
    </li>
`);

Build And Run The Project

Now that we have composed our intended page using a template, a fragment, data from a JSON file, and a tag-based callback we are ready to build our site and render the page in the browser. In your terminal application, please run the following commands from the root folder of your project:

trio build; trio serve

If you prefer, you can use the abbreviated forms of these commands instead:

trio b; trio s

The build command instructs Trio to do a one-off build of your site for development and to place the site's generated output into the project's public/ folder. The serve command instructs Trio to serve the project's public/ folder's content in the browser.

When public/index.html, the landing page for the Flags Of The World website, is rendered in the browser it should look like the following:

image of Flags Of The World landing page

While the page is rendered in your browser please scroll through the contents of the landing page. Please note that the links to the detail flag pages are broken because the detail flag pages aren't implemented yet but they will be implemented in the next tutorial.

You can also view the content of the generated HTML document, which resides in public/index.html, by simply opening it in your editor of choice or by running cat public/index.html from the root of your project in the terminal. Let's take a look at it now:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Home | Flags Of The World</title>
    <link rel="stylesheet" href="../../css/main.4b032a8bb77734ada3ae34e1a6cf849f.css">
</head>

<body>
    <main class="catalog">
        <h1 class="catalog__page-title">Flags Of The World</h1>
        <ul class="catalog__list" data-trio-callback="catalog">
            <li class="catalog__list-item">
                <img src="media/flags/128x128/af.png" alt="Afghanistan flag">
                <a class="catalog__list-item-link" href="/country/afghanistan/">
                    <p class="catalog__list-item-name">Afghanistan</p>
                </a>
            </li>

            <li class="catalog__list-item">
                <img src="media/flags/128x128/ax.png" alt="&#xC5;land Islands flag">
                <a class="catalog__list-item-link" href="/country/&#xE5;land islands/">
                    <p class="catalog__list-item-name">&#xC5;land Islands</p>
                </a>
            </li>

            <li class="catalog__list-item">
                <img src="media/flags/128x128/al.png" alt="Albania flag">
                <a class="catalog__list-item-link" href="/country/albania/">
                    <p class="catalog__list-item-name">Albania</p>
                </a>
            </li>

            <li class="catalog__list-item">
                <img src="media/flags/128x128/dz.png" alt="Algeria flag">
                <a class="catalog__list-item-link" href="/country/algeria/">
                    <p class="catalog__list-item-name">Algeria</p>
                </a>
            </li>
            .
            .
            .
        </ul>
    </main>
</body>

</html>

From the above we can see that the tag-based callback root/source/callbacks/catalog.js declared by the <ul> tag that is decorated with the data-trio-callback attribute in the template

<ul class="catalog__list" data-trio-callback="catalog"></ul>

was called and that it did dynamically generate the list items from the root/source/data/world.json file and appended them as content to the <ul> tag.

Conclusion

This tutorial examined how using Trio's advanced page composition we can add dynamic content contributed by a JSON file located in the root/source/data folder to your site's HTML documents.

In the next tutorial in this series we will explore Trio's collections feature and use it to generate each of the 249 detail flag pages for us.

Your Financial Support Of This Project Is Greatly Appreciated

Trio is an open source project and is therefore free of charge to use both for noncommercial and commercial use, but when you use Trio to create a new website, please consider donating a few bucks. It doesn't take very long, the process is secure, and it will allow us to continue to support the community and to maintain and enhance Trio going forward.

Show your ❤️, add your ★ to the Github repo.