Collections

Jigsaw provides powerful features for working with groups of related pages, or collections. Collections give you the ability to access your content at an aggregate level, enabling you to easily add near-dynamic features like menus, pagination, categories, and tags to your static site.

Collections can be used to generate pages of related content—for example, blog posts or articles that are sorted by date, with an index page displaying summaries of the five most recent posts—or for embedding related blocks of content within a page, for content like staff bios, product descriptions, or a portfolio of projects.

Defining a Collection

To define a collection, add an array named collections to config.php. Each collection should be indicated by the name of the collection (typically, plural), followed by an array of settings. For example:

config.php

<?php

return [
    'company' => 'Tighten Co',
    'contact_email' => 'support@tighten.co',
    'collections' => [
        'people' => [
            'path' => 'people',
            'sort' => 'last_name',
        ],
        'posts' => [
            'path' => 'blog/{date|Y-m-d}/{filename}',
            'author' => 'Tighten Co.',
        ],
    ],
];

Jigsaw will look for collection items in a directory with the same name as your collection, preceded by an underscore: in this example, _people and _posts. Collection items can be Markdown or Blade files, or even Blade/Markdown hybrid files.

Collections directory structure

In config.php, the array where you define your collection can contain path and sort settings for the collection, as well as variables and helper functions. None of these elements are required, however; if omitted, default path and sort settings will be used. In fact, for the simplest configuration using default settings and no variables or functions, you can define a collection with simply its name:

config.php

<?php

return [
    'collections' => [ 'posts' ],
];

Generating Collection Pages

If you'd like to generate an individual page for each of your collection items—for example, a page for each blog post—specify a parent template file in the extends key of the YAML front matter, or with the @extends directive in a Blade file, just as you would with a regular Jigsaw page. For example:

my-first-post.md

---
extends: _layouts.post
title: My First Blog Post
author: Keith Damiani
date: 2017-03-23
section: content
---

This post is *profoundly* interesting.

_layouts/post.blade.php

@extends('_layouts.master')

<h1>{{ $page->title }}</h1>
<p>By {{ $page->author }} • {{ $page->date }}</p>

@yield('content')

Accessing Collection Items

In any Blade template, you have access to each of your collections using a variable with the collection's name. This variable references an object that contains all the elements in your collection, and can be iterated over to access individual collection items. The collection variable also behaves as if it were an Illuminate Collection in Laravel, meaning you have access to all of Laravel's standard collection methods like count(), filter(), and where().

For example, to create a list of the titles for all your blog posts, you can iterate over the $posts object in a Blade @foreach loop, and display the title property that you defined in the YAML front matter of each post:

posts.blade.php

<p>Total of {{ $posts->count() }} posts</p>

<ul>
@foreach ($posts as $post)
    <li>{{ $post->title }}</li>
@endforeach
</ul>

Collection Metadata

In addition to the metadata available for every page, such as getPath(), getUrl(), and getFilename(), collection items have access to a few additional functions:

  • getContent() returns the main content of the collection item, i.e. the body of the Markdown file (currently, getContent() is available for Markdown files only)
  • getCollection() returns the name of the collection
  • getPrevious() and getNext() give you the adjacent items in the collection, based on the collection's default sort order
  • getFirst() returns the first item of a collection (as does the Laravel collection method first())
  • getLast() returns the last item of a collection (as does the Laravel collection method last())

_layouts/post.blade.php

@extends('_layouts.master')

<h1>{{ $page->title }}</h1>

@yield('content')

@if ($page->getNext())
    <p>Read my next post:
        <a href="{{ $page->getNext()->path }}">{{ $page->getNext()->title }}</a>
    </p>
@endif