110 lines
3.5 KiB
PHP
110 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Render\BladeRenderer;
|
|
use App\Render\MarkdownRenderer;
|
|
use App\Render\Renderer;
|
|
use Illuminate\Contracts\Filesystem\Filesystem;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use League\CommonMark\Environment\Environment;
|
|
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
|
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
|
|
use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
|
|
use League\CommonMark\MarkdownConverter;
|
|
|
|
use function Illuminate\Filesystem\join_paths;
|
|
|
|
// TODO: Load page's frontmatter and replace things like
|
|
// title and layout from it. Also set any default,
|
|
// values for things like layout from the config
|
|
// if they're not present on the page.
|
|
class Page
|
|
{
|
|
public string $filename;
|
|
public string $fileExtension;
|
|
public string $directory;
|
|
public string $title;
|
|
public string $slug;
|
|
public bool $isIndex;
|
|
public string $key;
|
|
protected Filesystem $sourceDisk;
|
|
public ?string $layout;
|
|
protected string $content;
|
|
|
|
public function __construct(public string $path)
|
|
{
|
|
$this->sourceDisk = Storage::disk('source');
|
|
|
|
$this->filename = basename($this->path);
|
|
$this->fileExtension = (str_ends_with($this->filename, '.blade.php')) ? 'blade.php' : pathinfo($this->filename, PATHINFO_EXTENSION);
|
|
$this->fileExtension = str($this->fileExtension)->trim('.')->toString();
|
|
$this->title = str($this->filename)->remove("." . $this->fileExtension)->title()->toString();
|
|
$this->slug = str($this->title)->slug();
|
|
$this->isIndex = str($this->filename)->remove("." . $this->fileExtension)->toString() == "index";
|
|
$this->directory = dirname($this->path);
|
|
$this->key = str($this->path)->remove("." . $this->fileExtension)->replace("/", ".")->lower()->toString();
|
|
|
|
$this->fillAdditionalData();
|
|
}
|
|
|
|
/**
|
|
* Grab data from the file's front matter
|
|
* as well as the config and overwrite
|
|
* or fill in any missing attributes.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function fillAdditionalData()
|
|
{
|
|
// Grab front matter data if any
|
|
if ($this->fileExtension == 'md') {
|
|
// Build the markdown parser
|
|
$mdEnvironment = new Environment();
|
|
$mdEnvironment->addExtension(new CommonMarkCoreExtension);
|
|
$mdEnvironment->addExtension(new FrontMatterExtension);
|
|
|
|
$parser = new MarkdownConverter($mdEnvironment);
|
|
$parsed = $parser->convert($this->content());
|
|
if ($parsed instanceof RenderedContentWithFrontMatter) {
|
|
$frontMatter = $parsed->getFrontMatter();
|
|
foreach ($frontMatter as $field => $value) {
|
|
$this->$field = $value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public function renderer(): Renderer
|
|
{
|
|
return ($this->fileExtension == 'blade.php') ? new BladeRenderer : new MarkdownRenderer;
|
|
}
|
|
|
|
public function render(): string
|
|
{
|
|
return $this->renderer()->render($this);
|
|
}
|
|
|
|
public function outputPath(): string
|
|
{
|
|
|
|
$baseDirectory = $this->directory;
|
|
if ($this->isIndex) {
|
|
return join_paths($baseDirectory, "index.html");
|
|
}
|
|
|
|
return join_paths($baseDirectory, "{$this->slug}", "index.html");
|
|
}
|
|
|
|
public function content(): string
|
|
{
|
|
if (!empty($this->content)) {
|
|
return $this->content;
|
|
}
|
|
|
|
$content = Storage::disk('source')->get($this->path);
|
|
$this->content = $content;
|
|
return $content;
|
|
}
|
|
}
|