Skip to content

Commit

Permalink
- build a sitemap once all content is generated
Browse files Browse the repository at this point in the history
  • Loading branch information
horuskol committed Aug 10, 2023
1 parent 786866d commit 1884dd7
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 12 deletions.
1 change: 1 addition & 0 deletions caxton
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ if (file_exists(Config::instance()->get('paths.output'))) {
$middlewares = [
Middleware\CopyPublicFiles::class,
Middleware\BuildContentFiles::class,
Middleware\GenerateSiteMap::class,
];

$action = fn (FileList $files): FileList => $files;
Expand Down
11 changes: 11 additions & 0 deletions resources/views/sitemap.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach ($files as $file)
@if ($file->type() === 'text/html')
<url>
<loc>{{ $file->fullUrl() }}</loc>
<lastmod>{{ $file->lastModified()?->toW3cString() }}</lastmod>
</url>
@endif
@endforeach
</urlset>
4 changes: 2 additions & 2 deletions src/ContentFileFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ public function accept(): bool
$filename = $this->current()->getFilename();

if (
in_array($pathname, Config::instance()->get('files.block', []))
|| (! in_array($pathname, Config::instance()->get('files.allow', []))
in_array($pathname, Config::instance()->get('files.exclude', []))
|| (! in_array($pathname, Config::instance()->get('files.include', []))
&& ($filename[0] === '.' || $filename[0] === '_')
)
) {
Expand Down
46 changes: 43 additions & 3 deletions src/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,49 @@

namespace SavvyWombat\Caxton;

use Illuminate\Support\Carbon;

class File
{
protected \SplFileInfo $sourceFileInfo;

public function __construct(
public string $filename
) { }
}
protected string $filename,
protected ?string $url = '',
protected ?string $source = '',
) {
if (empty($url)) {
$this->url = $filename;
}
$this->sourceFileInfo = new \SplFileInfo($source);
}

public function filename(): string
{
return $this->filename;
}

public function url(): string
{
return $this->url;
}

public function fullUrl(): string
{
return Config::instance()->get('base_url') . $this->url;
}

public function lastModified(): ?Carbon
{
if (empty($this->source)) {
return null;
}

return Carbon::createFromTimestamp($this->sourceFileInfo->getMTime());
}

public function type(): string
{
return mime_content_type(Config::instance()->get('paths.output') . $this->filename);
}
}
36 changes: 34 additions & 2 deletions src/FileList.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,44 @@

namespace SavvyWombat\Caxton;

class FileList
class FileList implements \Iterator
{
protected array $files = [];
protected int $index = 0;
protected array $filenames = [];


public function add(File $file): void
{
$this->files[$file->filename] = $file;
$this->files[$file->filename()] = $file;

if (! in_array($file->filename(), $this->filenames)) {
$this->filenames[] = $file->filename();
}
}

public function current(): File
{
return $this->files[$this->filenames[$this->index]];
}

public function key(): int
{
return $this->index;
}

public function next(): void
{
++$this->index;
}

public function valid(): bool
{
return isset($this->filenames[$this->index]);
}

public function rewind(): void
{
$this->index = 0;
}
}
13 changes: 10 additions & 3 deletions src/Middleware/BuildContentFiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,22 @@ public function run(FileList $files, callable $next): FileList
str_replace('/', '.', $subpath),
[
'page' => null,
'url' => Config::instance()->get('base_url') . (str_ends_with($subpath, 'index') ? substr($subpath, 0, -5) : $subpath),
'url' => Config::instance()->get('base_url') . (str_ends_with($subpath, '/index') ? substr($subpath, 0, -6) : $subpath),
]
)->render();

file_put_contents(Config::instance()->get('paths.output') . $subpath . '.html', $output);
$files->add(new File($subpath . '.html'));
$files->add(new File(
filename: $subpath . '.html',
url: (str_ends_with($subpath, '/index')) ? substr($subpath, 0, -6) : $subpath,
source: $contentFile->getRealPath(),
));
} else if (!is_dir($contentFile->getRealPath())) {
copy($contentFile->getRealPath(), Config::instance()->get('paths.output') . $subpath);
$files->add(new File($subpath));
$files->add(new File(
filename: $subpath,
source: $contentFile->getRealPath(),
));
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/Middleware/CopyPublicFiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ public function run(FileList $files, callable $next): FileList
if (!is_dir($publicFile->getRealPath())) {
copy($publicFile->getRealPath(), Config::instance()->get('paths.output') . $subpath);

$files->add(new File($subpath));
$files->add(new File(
filename: $subpath,
source: $publicFile->getRealPath(),
));
}
}

Expand Down
32 changes: 32 additions & 0 deletions src/Middleware/GenerateSiteMap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace SavvyWombat\Caxton\Middleware;

use SavvyWombat\Caxton\Config;
use SavvyWombat\Caxton\File;
use SavvyWombat\Caxton\FileList;
use SavvyWombat\Caxton\ViewFactory;

/**
* Builds a sitemap file to assist search engine discovery.
*
* https://ahrefs.com/blog/how-to-create-a-sitemap/
*/
class GenerateSiteMap implements Middleware
{
public function run (FileList $files, $next): FileList
{
$sitemap = ViewFactory::instance()->make(
'sitemap',
[
'files' => $files,
]
)->render();

file_put_contents(Config::instance()->get('paths.output') . '/sitemap.xml', $sitemap);

$files->add(new File('/sitemap.xml'));

return $next($files);
}
}
8 changes: 7 additions & 1 deletion src/ViewFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ protected function __construct()
return new CompilerEngine($bladeCompiler);
});

$viewFinder = new FileViewFinder($filesystem, [Config::instance()->get('paths.content')]);
$viewFinder = new FileViewFinder(
$filesystem,
[
Config::instance()->get('paths.content'),
realpath(__DIR__ . '/../resources/views'),
]
);

$this->viewFactory = new Factory($viewResolver, $viewFinder, $eventDispatcher);
$this->viewFactory->setContainer($container);
Expand Down

0 comments on commit 1884dd7

Please sign in to comment.