Skip to content

Instantly share code, notes, and snippets.

@trovster
Created February 20, 2023 11:07
Show Gist options
  • Save trovster/2c15ac5de15eb28fb8407ba177d69391 to your computer and use it in GitHub Desktop.
Save trovster/2c15ac5de15eb28fb8407ba177d69391 to your computer and use it in GitHub Desktop.
Content model for markdown
<?php
namespace App\Models;
use App\Models\Base as Model;
use App\Support\Str;
use App\Support\Stringable;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Storage;
use Spatie\YamlFrontMatter\YamlFrontMatter;
use Throwable;
/**
* App\Models\Content
*
* @property string $path
* @property string $key
* @property string $type
* @property-read \App\Support\Stringable $title
* @property-read \App\Support\Stringable $safe
* @property-read \App\Support\Stringable $slug
* @property-read int $order
* @property-read bool $enabled
* @property-read string $content
* @property-read \App\Support\Stringable $summary
*/
class Content extends Model
{
/** @var array<string> $fillable */
protected $fillable = [
'path',
'key',
'type',
];
protected array $matter = [];
protected string $body = '';
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->parseFile();
}
public function getRouteKeyName(): string
{
return 'key';
}
public function getSafeAttribute(): Stringable
{
return Str::of($this->key ?? $this->title)->slug();
}
public function getTitleAttribute(): Stringable
{
$title = Arr::get($this->matter, 'title', '');
return Str::of($title);
}
public function getOrderAttribute(): int
{
return Arr::get($this->matter, 'order', 0);
}
public function getSlugAttribute(): Stringable
{
$baseName = basename($this->path);
$slug = Arr::get($this->matter, 'slug', $baseName);
return Str::of($slug);
}
public function getEnabledAttribute(): bool
{
return Arr::get($this->matter, 'enabled', false);
}
public function getContentAttribute(): Stringable
{
return Str::of($this->body)->markdown();
}
public function getSummaryAttribute(): Stringable
{
return Str::of($this->content)->stripTags()->trim()->squish()->limit(250, '…');
}
public function getUrlAttribute(): ?string
{
$route = Arr::get($this->matter, 'route', false);
if ($route) {
return route($route);
}
return Arr::get($this->matter, 'url');
}
protected function parseFile(): void
{
try {
$contents = Storage::disk('content')->get($this->path);
$object = YamlFrontMatter::parse($contents ?? '');
$this->matter = $object->matter();
$this->body = $object->body();
} catch (Throwable $exception) {
$this->matter = [];
$this->body = '';
}
}
/**
* @param string $key
* @return mixed
*/
public function __get($key)
{
return Arr::get($this->matter, $key, parent::__get($key));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment