Skip to content

Commit

Permalink
Merge pull request #14 from plank/12-improve-readme
Browse files Browse the repository at this point in the history
Improve ReadMe content
  • Loading branch information
m-triassi authored Jun 19, 2024
2 parents 4b0158a + b68dcf5 commit 700f235
Showing 1 changed file with 133 additions and 7 deletions.
140 changes: 133 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -11,6 +11,13 @@

⚠️ This package is currently in development and is not ready for production use. ⚠️

This package allows for models to be built up dynamically by attaching `Content` to it. It's intended use is to allow for
creating a module system that plays nicely with Laravel Nova (via Repeaters, or other block editing systems) to create user
defined pages.

Considerations have been made to keep this package compatible with other packages in the Plank ecosystem such as [Snapshots](https://github.com/plank/snapshots).
It also has been architected to allow for explicit linking between modules and other entities within an application.

## Table of Contents

- [Installation](#installation)
@@ -32,34 +39,153 @@ You can install the package via composer:
composer require plank/contentable
```

You can use the package's install command to complete the installation:

```bash
php artisan contentable:install
```

## Quick Start

Once the installation has completed, to begin using the package:

1. Add the `HasContent` trait and `Contentable` interface to any model you'd like to attach content too.
2. Add the `CanRender` trait and `Renderable` interface to any models that will act as "Modules".
3. Implement the missing `Renderable` interface methods, specifically the `renderHtml()` method. Optionally add a `$renderableFields` class property, listing all fields that should be accessed by the module.

## Configuration

The package's configuration file is located at `config/contentable.php`. If you did not publish the config file during installation, you can publish the configuration file using the following command:

```bash
php artisan vendor:publish --tag=contentable-config
# Be sure to run any associated migrations
php artisan migrate
```

 

## Usage

### Building a Module system

Contentable's main purpose is to ease the building of a page builder style experience while maintaining explicit relationships
between `Renderable` models and any other arbitrary models within the application. This enables easily building things like
"Callout" modules, that can link to a concrete record in the database.

#### Define Modules

To take advantage of the above approach, any modules that are distinct from each other must be defined as their own models.
Eg, you might define a simple "Text" module (that is, a section on a page that displays a title and body text) like so:

```php
<?php

namespace App\Models;

use App\Models\Contracts\Renderable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Plank\Contentable\Concerns\CanRender;

class TextModule extends Model implements Renderable
{
use CanRender;
use HasFactory;

protected $guarded = ['id'];

protected array $renderableFields = ['title', 'body'];

public function renderHtml(): string
{
return "<h2>{$this->title}</h2>" +
"<p>{$this->body}</p>";
}
}
```

Of course, associated migrations, factories, etc... would need to be generated as well.

#### Define Contentables

Once modules have been created, though, they can then be attached to some `Contentable`, such as a `Page` model
eg:
```php
<?php

namespace App\Models;

use App\Models\Concerns\HasContent;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Plank\Contentable\Contracts\Contentable;


class Page extends Model implements Contentable
{
use HasContent;
use HasFactory;

/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = ['id'];

/**
* Get the route key for the model.
*/
public function getRouteKeyName(): string
{
return 'slug';
}
}
```

Such a page can now have any number of modules attached to it, and rendered. This allows most Laravel oriented content management
systems to simply relate a module to a `Page` via a (polymorphic) relationship field.

You can even get creative and use repeater style fields to build up a page's content in a more editorial fashion!

### Layouts
Layouts enable the user to control the "window dressing" around the modules that are laid out on a page. Effectively, a
layout represents the template used by a `Contentable` model (or any other model for that matter).

Layouts natively support Blade templates and Inertia pages.

Layouts are created automatically when Blade / JS files are created in the appropriate locations.
By default, these locations are `resources/views/layouts` for Blade templates or `resources/js/Pages/Layouts` for Inertia based systems.

Calling the function `php artisan contentable:sync` will scan these directories

### Layoutables

### LayoutData
Typically, any model with that fulfils the `Conentable` contract will also want to be `Layoutable`. This allows
users to have full control over the display modes on a page. The above `Page` model can be extended as so to add Layout functionality:

```php
use Illuminate\Database\Eloquent\Model;
use App\Models\Concerns\HasLayouts;
use Plank\Contentable\Contracts\Contentable;
use Plank\Contentable\Contracts\Layoutable;

class Page extends Model implements Contentable, Layoutable
{
// ...
use HasLayouts;

/**
* (Optional: Allows for layouts to be model specific)
* Restrict the Page layouts to ones strictly in the Pages folder
*/
protected static $globalLayouts = false;
}
```
Contentable exposes a function that make it easy to have a particular instance of a model use its set layout. Simply call `->layout()` on it, and pass that to the chosen render function.

eg:
```php
public function show(Page $page): \Illuminate\View\View
{
return view($page->layout())->with(compact('page'));
}
```

&nbsp;

0 comments on commit 700f235

Please sign in to comment.