<commit_before>---
layout: tutorials
permalink: /tutorials/navigation/
title: Navigation
---

If your Jekyll site has a lot of pages, you might want to create navigation for the pages. Instead of hard-coding navigation links, you can programmatically retrieve a list of pages to build the navigation for your site.

Although there's already information about [interacting with data files]({% link _docs/datafiles.md %}) in other Jekyll docs, this tutorial dives into building more robust navigation for your site.

There are two primary ways of retrieving pages on a Jekyll site:

* **Retrieve pages listed in a YAML data source**. Store the page data in a YAML (or JSON or CSV) file in the `_data` folder, loop through the YAML properties, and insert the values into your theme.
* **Retrieve pages by looping through the page front matter**. Look through the front matter of your pages to identify certain properties, return those pages, and insert the pages' front matter values into your theme.

The examples that follow start with a basic navigation scenario and add more sophisticated elements to demonstrate different ways of returning the pages. In every scenario, you'll see 3 elements:

* YAML
* Liquid
* Result

The YAML file in the `_data` directory is called `samplelist.yml`.

The scenarios are as follows:

* TOC
{:toc}

## Scenario 1: Basic List

You want to return a basic list of pages.

**YAML**

```yaml
docs_list_title: ACME Documentation
docs:

- title: Introduction
  url: introduction.html

- title: Configuration
  url: configuration.html

- title: Deployment
  url: deployment.html
```

**Liquid**

{% raw %}
```liquid
<h2>{{ site.data.samplelist.docs_list_title }}</h2>
<ul>
   {% for item in site.data.samplelist.docs %}
      <li><a href="{{ item.url }}" alt="{{ item.title }}">{{ item.title }}</a></li>
   {% endfor %}
</ul>
```
{% endraw %}

**Result**
<div class="highlight result" data-proofer-ignore>
   <h2>ACME Documentation</h2>
   <ul>
      <li><a href="#" alt="Introduction">Introduction</a></li>
      <li><a href="#" alt="Configuration">Configuration</a></li>
      <li><a href="#" alt="Deployment">Deployment</a></li>
   </ul>
</div>

{: .note .info }
For the results in these fictitious samples, `#` is manually substituted for the actual link value to avoid 404 errors.)

When you use a `for` loop, you choose how you want to refer to the items you're looping through. The variable you choose (in this case, `item`) becomes how you access the properties of each item in the list. Dot notation is used to get a property of the item (for example, `item.url`).

The YAML content has two main types of formats that are relevant here:

* mapping
* list

`docs_list_title: ACME Documentation` is a mapping. You access the value with `site.data.samplelist.docs_list_title`.

`docs:` is a list. The list begins each item with a hyphen. Unlike with mappings, you usually don't access list properties directly as you do with mappings. If you want to access a specific item in the list, you must identify the position in the list you want, following typical array notation. For example, `site.data.samplelist.docs[0]` would access the first item in the list. However, this is rarely done.

With lists, you usually use `for` loops to cycle through the list of items and do something with each item. With navigation menus, you usually insert each list item into `li` tags based on the navigation structure you're using in your HTML theme.

Each hyphen (`-`) indicates another item in the list. This example just has two properties with each list item: `title` and `url`. You can include as many properties as you want for each item. The order of properties at each position in the list doesn't matter.

## Scenario 2: Sorted list

Suppose you wanted to sort the list by the `title`. To do this, convert the reference to the `docs` collection to a variable, and then apply Liquid's `sort` filter to the variable:

**Liquid**

{% raw %}
```liquid
{% assign doclist = site.data.samplelist.docs | sort: 'title'  %}
<ol>
{% for item in doclist %}
    <li><a href="{{ item.url }}" alt="{{ item.title }}">{{ item.title }}</a></li>
{% endfor %}
</ol>
```
{% endraw %}

**Result**

<div class="highlight result" data-proofer-ignore>
   <ol>
      <li><a href="#" alt="Configuration">Configuration</a></li>
      <li><a href="#" alt="Deployment">Deployment</a></li>
      <li><a href="#" alt="Introduction">Introduction</a></li>
   </ol>
</div>

The items now appear in alphabetical order. The `sort` property in the Liquid filter applies to the `title`, which is an actual property in the list. If `title` weren't a property, we would need to sort by another property.

See the [Liquid array filter](https://help.shopify.com/themes/liquid/filters/array-filters) for more filter options. Note that you can't simply use this syntax:

{% raw %}
```liquid<commit_msg>Remove alt attribute from a tags (#7407)<commit_after>---
layout: tutorials
permalink: /tutorials/navigation/
title: Navigation
---

If your Jekyll site has a lot of pages, you might want to create navigation for the pages. Instead of hard-coding navigation links, you can programmatically retrieve a list of pages to build the navigation for your site.

Although there's already information about [interacting with data files]({% link _docs/datafiles.md %}) in other Jekyll docs, this tutorial dives into building more robust navigation for your site.

There are two primary ways of retrieving pages on a Jekyll site:

* **Retrieve pages listed in a YAML data source**. Store the page data in a YAML (or JSON or CSV) file in the `_data` folder, loop through the YAML properties, and insert the values into your theme.
* **Retrieve pages by looping through the page front matter**. Look through the front matter of your pages to identify certain properties, return those pages, and insert the pages' front matter values into your theme.

The examples that follow start with a basic navigation scenario and add more sophisticated elements to demonstrate different ways of returning the pages. In every scenario, you'll see 3 elements:

* YAML
* Liquid
* Result

The YAML file in the `_data` directory is called `samplelist.yml`.

The scenarios are as follows:

* TOC
{:toc}

## Scenario 1: Basic List

You want to return a basic list of pages.

**YAML**

```yaml
docs_list_title: ACME Documentation
docs:

- title: Introduction
  url: introduction.html

- title: Configuration
  url: configuration.html

- title: Deployment
  url: deployment.html
```

**Liquid**

{% raw %}
```liquid
<h2>{{ site.data.samplelist.docs_list_title }}</h2>
<ul>
   {% for item in site.data.samplelist.docs %}
      <li><a href="{{ item.url }}">{{ item.title }}</a></li>
   {% endfor %}
</ul>
```
{% endraw %}

**Result**
<div class="highlight result" data-proofer-ignore>
   <h2>ACME Documentation</h2>
   <ul>
      <li><a href="#">Introduction</a></li>
      <li><a href="#">Configuration</a></li>
      <li><a href="#">Deployment</a></li>
   </ul>
</div>

{: .note .info }
For the results in these fictitious samples, `#` is manually substituted for the actual link value to avoid 404 errors.)

When you use a `for` loop, you choose how you want to refer to the items you're looping through. The variable you choose (in this case, `item`) becomes how you access the properties of each item in the list. Dot notation is used to get a property of the item (for example, `item.url`).

The YAML content has two main types of formats that are relevant here:

* mapping
* list

`docs_list_title: ACME Documentation` is a mapping. You access the value with `site.data.samplelist.docs_list_title`.

`docs:` is a list. The list begins each item with a hyphen. Unlike with mappings, you usually don't access list properties directly as you do with mappings. If you want to access a specific item in the list, you must identify the position in the list you want, following typical array notation. For example, `site.data.samplelist.docs[0]` would access the first item in the list. However, this is rarely done.

With lists, you usually use `for` loops to cycle through the list of items and do something with each item. With navigation menus, you usually insert each list item into `li` tags based on the navigation structure you're using in your HTML theme.

Each hyphen (`-`) indicates another item in the list. This example just has two properties with each list item: `title` and `url`. You can include as many properties as you want for each item. The order of properties at each position in the list doesn't matter.

## Scenario 2: Sorted list

Suppose you wanted to sort the list by the `title`. To do this, convert the reference to the `docs` collection to a variable, and then apply Liquid's `sort` filter to the variable:

**Liquid**

{% raw %}
```liquid
{% assign doclist = site.data.samplelist.docs | sort: 'title'  %}
<ol>
{% for item in doclist %}
    <li><a href="{{ item.url }}">{{ item.title }}</a></li>
{% endfor %}
</ol>
```
{% endraw %}

**Result**

<div class="highlight result" data-proofer-ignore>
   <ol>
      <li><a href="#">Configuration</a></li>
      <li><a href="#">Deployment</a></li>
      <li><a href="#">Introduction</a></li>
   </ol>
</div>

The items now appear in alphabetical order. The `sort` property in the Liquid filter applies to the `title`, which is an actual property in the list. If `title` weren't a property, we would need to sort by another property.

See the [Liquid array filter](https://help.shopify.com/themes/liquid/filters/array-filters) for more filter options. Note that you can't simply use this syntax:

{% raw %}
```liquid
{'fraction_non_alphanumeric': 0.10820624546114742, 'fraction_numerical': 0.0026973752463948543, 'mean_word_length': 4.168900804289544, 'pattern_counts': {'":': 0, '<': 99, '<?xml version=': 0, '>': 99, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3370375', 'n_tokens_mistral': 2859, 'n_tokens_neox': 2666, 'n_words': 1325}