hi-folks/fusion

Laravel package that enhances Eloquent models to facilitate the management of structured, database-free content through Markdown files with Frontmatter.

v0.0.10 2024-05-01 21:30 UTC

This package is auto-updated.

Last update: 2024-12-03 17:44:39 UTC


README

Fusion

Latest Version on Packagist Total Downloads
Packagist License Packagist PHP Version Support GitHub last commit
Tests

Fusion is a Laravel package designed to manage Markdown content via Eloquent Models, eliminating the necessity for a conventional database setup. It achieves this by leveraging Markdown files enhanced with Frontmatter.

Laravel package that enhances Eloquent models to facilitate the management of structured, database-free content through Markdown files with Frontmatter.

Fusion aids in website development by integrating the power of Markdown and Frontmatter, enabling developers to create content-driven Web sites without having to manage databases.

With Fusion, developers can leverage the simplicity of Markdown syntax combined with the flexibility of Frontmatter to seamlessly organize and structure content.

By parsing Frontmatter into Eloquent models, Fusion enables developers to create complex, structured websites with ease. Say goodbye to the complexities of database management and welcome simplified website development with Fusion.

Warning

The package is under development (version 0.0.x), so the functions, classes and methods provided can be changed, especially for the FusionBaseModel model class. So, if you want to start using the package in order to provide feedback, you are welcome, but please don't use it in production until the version 1.0.0 will be released. Thank you

Installation

You can install the package via the composer tool:

composer require hi-folks/fusion

Usage

Once you installed Fusion you can start the process of creating content in Markdown files and querying the files through the Models. For example, now we are going to create articles in Markdown format and we will parse and query them like you can do it with a database.

Creating the content

In the resources/content directory, you can create the article directory. In the resources/content/article, you can create your Markdown files with a frontmatter header like for example:

---
date: 2024-04-05
title: Example title for article 1
excerpt: This will be a short excerpt from article number 1.
published: true
---

# Article 1

Markdown goes here

you can name this file as resources/content/article/article-1.md You can create similarly the other Markdown files. These files represent your articles.

Creating the Model

Similarly, you are doing with a database, you can create your model for loading the markdown files. Because you are creating articles you can create your model as app/Models/Article.php.

You can fill the file in this way:

<?php

namespace App\Models;


use HiFolks\Fusion\Models\FusionBaseModel;
use HiFolks\Fusion\Traits\FusionModelTrait;

class Article extends FusionBaseModel
{
    use FusionModelTrait;


    public function frontmatterFields(): array
    {
        return [
            "excerpt"
        ];
    }

}

Consider that:

  • the class has to extend the FusionBaseModel with extends FusionBaseModel;
  • you have to use the trait FusionModelTrait: use FusionModelTrait;
  • you have to implement the frontmatterFields() function for returning the list of the field names used in the frontmatter header.

Creating automatically the Model

If you want to create automatically the Model file, based on the structure and the content of the Markdown files you can use the fusion:sync-model command:

php artisan fusion:sync-model --path=resources/content/project --create-model

The path parameter sets the directory of the markdown files for a specific model (like article, page, post, project etc.). The --create-model option will generate automatically the Model file based on the content and the frontmatter section of the Markdown files. Without the --create-model option the fusion:sync-model command will list some information detected from Markdown like the name of the Model and the list of the fields.

Querying the content

Now in your Controllers or your Blade components, you can use the Article model with the usual method like where(), orderBy() etc:

$articles = \App\Models\Article
    ::where('published', true)
    ->orderBy('date')
    ->get();

Advanced Usage

Once you understand the basics of using Fusion with your Markdown files, you can use some of the advanced features. Consider that Fusion is a LAravel Package and during the design and the implementation of the Package we try to use and adhere to as much as possible the Laravel functionalities. With this approach, we think that we can inherit all the benefits of some Laravel features. Some of these feature that we explore and explain in the next sections are:

  • Reloading the page of the website you are visualizing in the Browser when you change the Markdown content;
  • Casting date in the Model so you can use the date in the Frontmatter headers;
  • Casting collection in the Model so you can use complex and nested Frontmatter headers;
  • Using the Check Markdown command for detecting the Frontmatter fields in the Markdown files.

Adding real-time page reload

If you want the browser to automatically reload the pages when you change some content in the Markdown files you can set the refresh option in the laravel Vite plugin. In the vite.config.js file add the refresh option with the list of the folder you want that Vite will "watch" for changes and reload the page.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: ["resources/css/app.css", "resources/js/app.js"],
            refresh: [
                {
                    paths: ["resources/content/**"],
                },
            ],
        }),
    ]
});

In the example, the resources/content directory is added.

If you need to setup the Vite asset bundling you can take a look at the LAravel documentation: https://laravel.com/docs/11.x/vite

Using dates in the Markdown files

If you want to use date (or date-time) in your front matter you can use the format YYYY-MM-DD in the Frontmatter for example:

---
date: 2023-01-26
title: Example title for article 1
---
This is the **Markdown**.

Then in the Model you can set the casting in this way:

    protected function casts(): array
    {
        return [
            'date' => 'datetime:Y-m-d',
        ];
    }

Where date is the field name, the same name you are using in the Markdown.

If you are adding a new field, remember to add the field name in the list of the frontmatter field in the frontmatterFields() function in the Model:

    public function frontmatterFields(): array
    {
        return [
            "title", "date", "excerpt", "published", "highlight", "head"
        ];
    }

If you are interested into exploring more the attribute casting in the Laravel Model you can take a look at The Laravel Eloquent attribute casting documentation.

Using collections in the Markdown files

If you need to manage complex data in the Markdown, like for example a list of tags you can use the arrays in the Frontmatter:

---
date: 2023-01-26
title: Example title for article 1
excerpt: This will be a short excerpt from article number 1.
published: true
highlight: true
head:
  - tag: title
    content: Custom about title
  - tag: title2
    content: Custom about title2
---

# Article 1

Markdown goes here

In the example, we are adding a field named head which is an array of values for tag and content.

In the Model file, you have to cast properly the head field as collection.

    protected function casts(): array
    {
        return [
            'head' => 'collection',
            'date' => 'datetime:Y-m-d',
        ];
    }

So that in your blade files, you can loop through the head field and access to tag or content sub-fields:

@if (! is_null($article->head))
    @foreach ($article->head as $headItems)
    <div class="mx-3 px-8 badge badge-neutral">{{ $headItems["tag"] }}</div>
    @endforeach
@else
    <div class="mx-3 px-8 badge badge-ghost">No Tag</div>
@endif

Customizing the slug

By default, the slug of a content is the filename without the extension. Now you can customize the slug using the frontmatter attribute slug. For example:

---
date: 2023-04-13
slug: fusion
name: Fusion
claim:  build Website with Markdown files
excerpt: Fusion integrates Markdown into Laravel Models, simplifying Website development.
published: true
highlight: true
image: /img/fusion-cover-website.webp
tags:
  - tag: Laravel
  - tag: Website Development
---

# Fusion

Fusion aids in website development by integrating the power of Markdown and Frontmatter, enabling developers to create content-driven Web sites without having to manage databases.

Using the Check Markdown command

To inspect the Markdown files and show and list the Frontmatter fields you can use the Artisan command fusion:check.

php artisan fusion:check

Using the Check Model command

To inspect the Model file and check if it extends the right class and uses the proper Traits to be a Model compatible with Markdown files, you can use the fusion:check-model command:

php artisan fusion:check-model --model="App\Models\Article"

The output will tell you if your model is correct or not:

Parsing the Model File
Class App\Models\Article exists
App\Models\Article extends correctly the class HiFolks\Fusion\Models\FusionBaseModel
App\Models\Article uses HiFolks\Fusion\Traits\FusionModelTrait

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security-related issues, please open an issue in the tracker using the "New issue" functionality.

Credits

License

The MIT License (MIT). Please see License File for more information.

References

We built this Open Source project using some nice and powerful Open Source libraries like:

  • Sushi: Eloquent's missing "array" driver;
  • league/commonmark: Highly-extensible PHP Markdown parser which fully supports the CommonMark and GFM specs;
  • yaml-front-matter: A to the point yaml front matter parser;
  • PestPHP: Pest is an elegant PHP testing Framework with a focus on simplicity, meticulously designed to bring back the joy of testing in PHP. Under the hood PestPHP uses PHPUnit, the PHP testing framework;
  • RectorPHP: Instant Upgrades and Automated Refactoring of any PHP 5.3+ code;
  • Laravel Pint: an opinionated PHP code style fixer for minimalists. Under the hood, Laravel Pint uses PHP-CS-Fixer the open source tool to automatically fix PHP Coding Standards issues.

Laravel Package Boilerplate

This package was generated using the Laravel Package Boilerplate.