From 8d3ec7a9836478889cb492009778ef77050b8141 Mon Sep 17 00:00:00 2001 From: Javier Feliz Date: Wed, 20 Aug 2025 00:56:22 -0400 Subject: [PATCH] Collection detection you already know --- app/Commands/ParseConfigCommand.php | 15 +++++++- app/Models/ContentCollection.php | 33 +++++++++++++++-- app/Models/Page.php | 57 +++++++++++++++++++++++++++++ app/Render/MarkdownRenderer.php | 7 +++- app/SiteConfiguration.php | 3 +- dev-server.js | 3 +- zap.yml | 8 ++-- 7 files changed, 114 insertions(+), 12 deletions(-) diff --git a/app/Commands/ParseConfigCommand.php b/app/Commands/ParseConfigCommand.php index 98aeaca..9d07b60 100644 --- a/app/Commands/ParseConfigCommand.php +++ b/app/Commands/ParseConfigCommand.php @@ -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); + } + } } diff --git a/app/Models/ContentCollection.php b/app/Models/ContentCollection.php index b1e7558..74b2397 100644 --- a/app/Models/ContentCollection.php +++ b/app/Models/ContentCollection.php @@ -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; + } } diff --git a/app/Models/Page.php b/app/Models/Page.php index 354f367..811ce1d 100644 --- a/app/Models/Page.php +++ b/app/Models/Page.php @@ -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 diff --git a/app/Render/MarkdownRenderer.php b/app/Render/MarkdownRenderer.php index 6579ebf..7abe5ae 100644 --- a/app/Render/MarkdownRenderer.php +++ b/app/Render/MarkdownRenderer.php @@ -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 = << + $parsed - + HTML; $rendered = Blade::render($tmpBlade, []); diff --git a/app/SiteConfiguration.php b/app/SiteConfiguration.php index e2d727b..6c3c09b 100644 --- a/app/SiteConfiguration.php +++ b/app/SiteConfiguration.php @@ -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(); diff --git a/dev-server.js b/dev-server.js index 79a985a..381b33b 100644 --- a/dev-server.js +++ b/dev-server.js @@ -45,7 +45,8 @@ export default function hotReloadPlugin(options = {}) { "./site/**/*.md", "./site/**/*.html", "./config/**/*.php", - "./app/**/*.php" + "./app/**/*.php", + "./zap.yml" ], // Files to ignore diff --git a/zap.yml b/zap.yml index 7ecb8f4..87165e1 100644 --- a/zap.yml +++ b/zap.yml @@ -5,6 +5,8 @@ collections: schema: - name: string - banner: string - collections: - docs: - layout: docs \ No newline at end of file + projects.[project_name].docs: + layout: docs + schema: + - title: string + - section: string \ No newline at end of file