Collection detection you already know

This commit is contained in:
Javier Feliz 2025-08-20 00:56:22 -04:00
parent 06d22835c7
commit 8d3ec7a983
7 changed files with 114 additions and 12 deletions

View File

@ -2,6 +2,9 @@
namespace App\Commands;
use App\Build\SiteParser;
use App\Models\ContentCollection;
use App\SiteConfiguration;
use Illuminate\Console\Scheduling\Schedule;
use LaravelZero\Framework\Commands\Command;
use Symfony\Component\Yaml\Yaml;
@ -25,5 +28,15 @@ class ParseConfigCommand extends Command
/**
* Execute the console command.
*/
public function handle() {}
public function handle()
{
// $col = new ContentCollection("projects");
// dd(SiteConfiguration::collections());
foreach ((new SiteParser)->getPages() as $p) {
$this->info($p->key);
$this->warn("- " . $p->entityName);
$this->warn("- " . $p->collection);
$this->warn("- " . $p->layout);
}
}
}

View File

@ -2,10 +2,35 @@
namespace App\Models;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
class ContentCollection
{
public function __construct(
protected string $name,
protected string $layout
) {}
public Collection $pages;
public function __construct(public string $name)
{
$directories = Storage::disk('source')->directories($name);
$files = Storage::disk('source')->files($name);
$pages = collect();
foreach ($files as $f) {
$p = new Page($f);
$p->collection = $name;
$pages->push($p);
}
// Go through directories and check for index.md
foreach ($directories as $dir) {
if (Storage::disk('source')->exists("$dir/index.md")) {
$p = new Page("$dir/index.md");
$p->collection = $name;
$pages->push($p);
}
}
$this->pages = $pages;
}
}

View File

@ -5,6 +5,7 @@ namespace App\Models;
use App\Render\BladeRenderer;
use App\Render\MarkdownRenderer;
use App\Render\Renderer;
use App\SiteConfiguration;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Support\Facades\Storage;
use League\CommonMark\Environment\Environment;
@ -30,6 +31,8 @@ class Page
public string $key;
protected Filesystem $sourceDisk;
public ?string $layout;
public ?string $collection = null;
public string $entityName; // The name of this page. Ex: projects/myproject = myproject
protected string $content;
public function __construct(public string $path)
@ -44,10 +47,45 @@ class Page
$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->entityName = $this->isIndex ? basename($this->directory) : $this->slug;
$this->detectCollection();
$this->fillAdditionalData();
}
// TODO: Do something with the [params]
// from the collection name if present.
// Maybe store it in a $collectionParams
// array on the page or something.
public function detectCollection()
{
$key_parts = explode('.', $this->key);
$collections = SiteConfiguration::collections();
foreach ($collections as $c) {
$parts = explode('.', $c);
// If we have key: projects.something
// and collection projects.[project_name].docs
// then it's not it
if (count($parts) > $key_parts) {
continue;
}
// Get a subset of max length key parts
$key_compare = array_slice($key_parts, 0, count($parts));
$match = true;
foreach ($key_compare as $i => $v) {
// TODO: Use regex here to search for [] instead of just [
if ($v !== $parts[$i] && !str($parts[$i])->contains("[")) {
$match = false;
break;
}
}
if ($match) $this->collection = $c;
}
}
/**
* Grab data from the file's front matter
* as well as the config and overwrite
@ -57,6 +95,22 @@ class Page
*/
public function fillAdditionalData()
{
// If we have a collection, get the settings from it
if (!empty($this->collection)) {
$config = SiteConfiguration::getConfig()['collections'][$this->collection];
// if ($this->collection == "projects") {
// dd($config);
// }
$fillIfEmpty = ['layout'];
foreach ($fillIfEmpty as $field) {
if (empty($this->$field) && !empty($config[$field])) {
$this->$field = $config[$field];
}
}
}
// Grab front matter data if any
if ($this->fileExtension == 'md') {
// Build the markdown parser
@ -73,6 +127,9 @@ class Page
}
}
}
// If layout is still empty just set it to main
if (empty($this->layout)) $this->layout = 'main';
}
public function renderer(): Renderer

View File

@ -6,6 +6,7 @@ use App\Models\Page;
use Illuminate\Support\Facades\Blade;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
use League\CommonMark\MarkdownConverter;
@ -18,13 +19,15 @@ class MarkdownRenderer implements Renderer
$mdEnvironment = new Environment();
$mdEnvironment->addExtension(new CommonMarkCoreExtension);
$mdEnvironment->addExtension(new GithubFlavoredMarkdownExtension);
$mdEnvironment->addExtension(new FrontMatterExtension);
$parser = new MarkdownConverter($mdEnvironment);
$parsed = $parser->convert($p->content());
$layout = $p->layout;
$tmpBlade = <<<HTML
<x-layouts.main>
<x-layouts.{$layout}>
$parsed
</x-layouts.main>
</x-layouts.{$layout}>
HTML;
$rendered = Blade::render($tmpBlade, []);

View File

@ -9,8 +9,9 @@ class SiteConfiguration
public static function getConfig(): array
{
$configPath = base_path('zap.yml');
$config = Yaml::parseFile($configPath);
return Yaml::parseFile($configPath);
}
public static function collections(): array
{
$config = self::getConfig();

View File

@ -45,7 +45,8 @@ export default function hotReloadPlugin(options = {}) {
"./site/**/*.md",
"./site/**/*.html",
"./config/**/*.php",
"./app/**/*.php"
"./app/**/*.php",
"./zap.yml"
],
// Files to ignore

View File

@ -5,6 +5,8 @@ collections:
schema:
- name: string
- banner: string
collections:
docs:
projects.[project_name].docs:
layout: docs
schema:
- title: string
- section: string