Skip to content

File-based Collections

Introduction to Hyde Data Collections

Hyde provides DataCollection, a subset of Laravel Collections giving you a similar developer experience to working with Eloquent Collections. However, instead of accessing a database, it's all entirely file-based using static data files such as Markdown, Yaml, and JSON files which get parsed into objects that you can easily work with.

As you have access to all standard Laravel Collection methods, you are encouraged to read the Laravel Collections documentation for more information.

This article covers advanced usage intended for those who are writing their own Blade views, and is not required as Hyde comes pre-packaged with many templates for you to use.

High-Level Concept Overview

In short, HydePHP finds files in the specified directory, turns each file into an object, and returns a Laravel Collection of these objects.

To make collections easy to use and understand, Hyde makes a few assumptions about the structure of your collections. Follow these conventions and creating dynamic static sites will be a breeze.

  1. Collections are accessed through static methods in the DataCollection class.
  2. Collections are stored as files in subdirectories of the resources/collections directory.
  3. To get a collection, specify name of the subdirectory the files are stored in.
  4. Data will be parsed into differing objects depending on which facade method you use. See the table below.
  5. The class is aliased so that you can use it in Blade files without having to include the namespace.
  6. While not enforced, each subdirectory should probably only have the same filetype to prevent developer confusion.
  7. Unlike source files for pages, files starting with underscores are not ignored.
  8. You can customize the source directory for collections through a service provider.

Available Collection Types

Quick Reference Overview

The following facade methods for creating data collections are available:

\Hyde\Support\DataCollection::markdown(string $name);
\Hyde\Support\DataCollection::yaml(string $name);
\Hyde\Support\DataCollection::json(string $name, bool $asArray = false);

Quick Reference Table

Collection Type Facade Method Returned Object Type File Extension
Markdown ::markdown() MarkdownDocument .md
Yaml ::yaml() FrontMatter .yaml.yml
Json ::json() stdClass OR  array .json

Markdown Collections

Usage

$collection = \Hyde\Support\DataCollection::markdown('name');

Example returns

Here is an approximation of the data types contained by the variable created above:

\Hyde\Support\DataCollection {
    "testimonials/1.md" => Hyde\Markdown\Models\MarkdownDocument
    "testimonials/2.md" => Hyde\Markdown\Models\MarkdownDocument
    "testimonials/3.md" => Hyde\Markdown\Models\MarkdownDocument
  ]
}

The returned MarkdownObjects look approximately like this:

\Hyde\Markdown\Models\MarkdownDocument {
  +matter: Hyde\Markdown\Models\FrontMatter {
     +data: array:1 [
       "author" => "John Doe"
     ]
  }
  +markdown: Hyde\Markdown\Models\Markdown {
    +body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit..."
  }
}

Assuming the Markdown document looks like this:

---
author: "John Doe"
---

Lorem ipsum dolor sit amet, consectetur adipiscing elit...

YAML Collections

Usage

$collection = \Hyde\Support\DataCollection::yaml('name');

Example returns

Here is an approximation of the data types contained by the variable created above:

\Hyde\Support\DataCollection {
  "authors/1.yaml" => Hyde\Markdown\Models\FrontMatter {
    +data: array:1 [
      "name" => "John Doe",
      "email" => "[email protected]"
    ]
  }
}

Assuming the Yaml document looks like this:

name: "John Doe"
email: "[email protected]"

Json Collections

Usage

$collection = \Hyde\Support\DataCollection::json('name');

By default, the entries will be returned as stdClass objects. If you want to return an associative array instead, pass true as the second parameter:

$collection = \Hyde\Support\DataCollection::json('name', true);

Since both return values use native PHP types, there are no example returns added here, as I'm sure you can imagine what they look like.

Markdown Collections - Hands-on Guide

I think the best way to explain DataCollections is through examples, so let's create a Blade page with customer testimonials!

This example will use Markdown Collections, but the same concepts apply to all other collection types.

Setting up the file structure

We start by setting up our directory structure. We will create a testimonials subdirectory, which will be the collection name.

In it, we will place Markdown files. Each file will be a testimonial. The Markdown will be parsed into a MarkdownDocument object which parses any optional YAML front matter.

Here is the sample Markdown we will use:

Filepath: resources/collections/testimonials/1.md---
author: John Doe
---

Lorem ipsum dolor sit amet, consectetur adipiscing elit...

Let's take a look at our directory structure. I just copied the same file a few times. You can name the files anything you want, I kept it simple and just numbered them.

resources/collections
└── testimonials
    ├── 1.md
    ├── 2.md
    └── 3.md

Using the Facade to Access the Collections

Now for the fun part! We will use the DataCollection::markdown() to access all our files into a convenient object. The class is registered with an alias, so you don't need to include any namespaces when in a Blade file.

The general syntax to use the facade is as follows:

DataCollection::markdown('subdirectory_name')

This will return a Hyde DataCollection object, containing our Markdown files as MarkdownDocument objects. Here is a quick look at the object the facade returns:

^ Hyde\Support\DataCollection {#651 
  #items: array:3 [
    "testimonials/1.md" => Hyde\Markdown\Models\MarkdownDocument {#653 
      +matter: Hyde\Markdown\Models\FrontMatter {#652 }
      +markdown: Hyde\Markdown\Models\Markdown {#654 }
    }
    "testimonials/2.md" => Hyde\Markdown\Models\MarkdownDocument {#656 }
    "testimonials/3.md" => Hyde\Markdown\Models\MarkdownDocument {#659 }
  ]
}

Implementing it in a Blade view

Let's create a Blade page to display all our testimonials.

php hyde make:page "Testimonials" --type="blade"

And we can use the collection almost like any other Laravel one. As you can see, since each entry is a MarkdownDocument class, we are able to get the author from the front matter, and the content from the body.

Filepath: _pages/testimonials.blade.php@foreach(DataCollection::markdown('testimonials') as $testimonial)
    <blockquote>
        <p>{{ $testimonial->body }}</p>
        <small>{{ $testimonial->matter['author'] }}</small>
    </blockquote>
@endforeach