You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
297 lines
8.4 KiB
PHP
297 lines
8.4 KiB
PHP
<?php
|
|
|
|
|
|
namespace Eater;
|
|
|
|
|
|
use DateTime;
|
|
use League\CommonMark\CommonMarkConverter;
|
|
use Slim\Factory\AppFactory;
|
|
use Slim\Psr7\Request;
|
|
use Slim\Psr7\Response;
|
|
use Twig\Environment;
|
|
use Twig\Loader\FilesystemLoader;
|
|
use Yosymfony\Toml\Toml;
|
|
|
|
class Blog
|
|
{
|
|
private $app;
|
|
private $twig;
|
|
private $debug = false;
|
|
private $posts = [];
|
|
private $tags = [];
|
|
private $pages = [];
|
|
private $config = [];
|
|
private $games = [];
|
|
|
|
public function __construct()
|
|
{
|
|
$this->app = AppFactory::create();
|
|
$this->twig = new Environment(
|
|
new FilesystemLoader([__DIR__."/../views"]), [
|
|
'cache' => __DIR__."/../var/cache/twig",
|
|
'debug' => $this->debug,
|
|
]
|
|
);
|
|
|
|
$this->routes();
|
|
$this->makeListing();
|
|
}
|
|
|
|
public function run()
|
|
{
|
|
$this->app->run();
|
|
}
|
|
|
|
public function routes()
|
|
{
|
|
$app = $this->app;
|
|
$app->get(
|
|
'/',
|
|
function (Request $request, Response $response, $args) {
|
|
$response->getBody()->write(
|
|
$this->twig->render(
|
|
"main.html.twig",
|
|
$this->context()
|
|
)
|
|
);
|
|
|
|
return $response;
|
|
}
|
|
);
|
|
|
|
$app->get(
|
|
'/tag/{tag}',
|
|
function (Request $request, Response $response, $args) {
|
|
$tag = $args['tag'];
|
|
$posts = array_filter(
|
|
$this->posts,
|
|
function ($post) use ($tag) {
|
|
return in_array($tag, $post['meta']['tags'] ?: []);
|
|
}
|
|
);
|
|
|
|
$response->getBody()->write(
|
|
$this->twig->render(
|
|
"tag.html.twig",
|
|
$this->context(
|
|
[
|
|
'tag' => $tag,
|
|
'posts' => $posts,
|
|
]
|
|
)
|
|
)
|
|
);
|
|
|
|
return $response;
|
|
}
|
|
);
|
|
|
|
$app->get(
|
|
'/game/{game}',
|
|
function (Request $request, Response $response, $args) {
|
|
$game = $this->games[$args['game']] ?? false;
|
|
if ( ! $game) {
|
|
return $response->withStatus(404);
|
|
}
|
|
|
|
$posts = array_filter(
|
|
$this->posts,
|
|
function ($post) use ($game) {
|
|
return in_array($game['slug'], $post['meta']['games'] ?: []);
|
|
}
|
|
);
|
|
|
|
$response->getBody()->write(
|
|
$this->twig->render(
|
|
"game.html.twig",
|
|
$this->context(
|
|
[
|
|
'posts' => $posts,
|
|
'game' => $game,
|
|
'game_body' => $this->parseMarkdown($game['markdown']),
|
|
]
|
|
)
|
|
)
|
|
);
|
|
|
|
return $response;
|
|
}
|
|
);
|
|
|
|
$app->get(
|
|
'/post/{post}',
|
|
function (Request $request, Response $response, $args) {
|
|
$post = $this->posts[$args['post']] ?? false;
|
|
if ( ! $post) {
|
|
return $response->withStatus(404);
|
|
}
|
|
|
|
$response->getBody()->write(
|
|
$this->twig->render(
|
|
"post.html.twig",
|
|
$this->context(
|
|
[
|
|
'post' => $post,
|
|
'post_body' => $this->parseMarkdown($post['markdown']),
|
|
]
|
|
)
|
|
)
|
|
);
|
|
|
|
return $response;
|
|
}
|
|
);
|
|
|
|
$app->get(
|
|
'/rss.xml',
|
|
function (Request $request, Response $response) {
|
|
$response->getBody()->write(
|
|
$this->twig->render(
|
|
"rss.xml.twig",
|
|
$this->context()
|
|
)
|
|
);
|
|
|
|
return $response->withHeader("Content-Type", "application/rss+xml");
|
|
}
|
|
);
|
|
|
|
$app->get(
|
|
'/games',
|
|
function (Request $request, Response $response) {
|
|
$response->getBody()->write(
|
|
$this->twig->render(
|
|
"games.html.twig",
|
|
$this->context()
|
|
)
|
|
);
|
|
|
|
return $response;
|
|
}
|
|
);
|
|
|
|
$app->get(
|
|
'/{page}',
|
|
function (Request $request, Response $response, $args) {
|
|
$page = $this->pages[$args['page']] ?? false;
|
|
if ( ! $page) {
|
|
return $response->withStatus(404);
|
|
}
|
|
|
|
$response->getBody()->write(
|
|
$this->twig->render(
|
|
"page.html.twig",
|
|
$this->context(
|
|
[
|
|
'page' => $page,
|
|
'page_body' => $this->parseMarkdown($page['markdown']),
|
|
]
|
|
)
|
|
)
|
|
);
|
|
|
|
return $response;
|
|
}
|
|
);
|
|
}
|
|
|
|
private function context($context = [])
|
|
{
|
|
return array_merge(
|
|
[
|
|
'pages' => $this->pages,
|
|
'posts' => $this->posts,
|
|
'config' => $this->config,
|
|
'games' => $this->games,
|
|
'tags' => $this->tags,
|
|
],
|
|
$context
|
|
);
|
|
}
|
|
|
|
private function parseObjects($path, $registerTags = false)
|
|
{
|
|
$objectBase = realpath($path);
|
|
$objects = glob($objectBase."/*.md");
|
|
|
|
$objectsColl = [];
|
|
foreach ($objects as $object) {
|
|
$objectSource = file_get_contents($object);
|
|
$parts = explode('---', $objectSource, 2);
|
|
if (count($parts) !== 2) {
|
|
continue;
|
|
}
|
|
|
|
$meta = Toml::parse($parts[0]);
|
|
$md = $parts[1];
|
|
|
|
$slug = ltrim(substr($object, strlen($objectBase)), '/');
|
|
$objectsColl[$slug] = [
|
|
"markdown" => $md,
|
|
"meta" => $meta,
|
|
"slug" => $slug,
|
|
];
|
|
|
|
if ($registerTags) {
|
|
$this->tags = array_merge($meta['tags'] ?: [], $this->tags);
|
|
}
|
|
}
|
|
|
|
return $objectsColl;
|
|
}
|
|
|
|
private function makeListing()
|
|
{
|
|
$cacheFile = __DIR__."/../var/cache/listing.json";
|
|
if (file_exists($cacheFile) && ! $this->debug) {
|
|
$data = json_decode(file_get_contents($cacheFile), true);
|
|
|
|
$this->posts = $data['posts'];
|
|
$this->pages = $data['pages'];
|
|
$this->tags = $data['tags'];
|
|
$this->config = $data['config'];
|
|
$this->games = $data['games'];
|
|
|
|
foreach ($this->posts as &$post) {
|
|
if (isset($post['meta']['date'])) {
|
|
$post['meta']['date'] = new DateTime($post['meta']['date']['date']);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
$this->posts = $this->parseObjects(__DIR__."/../data/posts", true);
|
|
$this->pages = $this->parseObjects(__DIR__."/../data/pages");
|
|
$this->games = $this->parseObjects(__DIR__."/../data/games");
|
|
|
|
$this->config = Toml::parse(file_get_contents(__DIR__."/../data/config.toml"));
|
|
$this->tags = array_unique($this->tags);
|
|
|
|
$cacheDir = __DIR__."/../var/cache/";
|
|
if ( ! is_dir($cacheDir)) {
|
|
mkdir($cacheDir, 0777, true);
|
|
}
|
|
|
|
file_put_contents(
|
|
__DIR__."/../var/cache/listing.json",
|
|
json_encode(
|
|
[
|
|
"pages" => $this->pages,
|
|
"posts" => $this->posts,
|
|
"tags" => $this->tags,
|
|
"games" => $this->games,
|
|
"config" => $this->config,
|
|
]
|
|
)
|
|
);
|
|
}
|
|
|
|
private function parseMarkdown($markdown)
|
|
{
|
|
$converter = new CommonMarkConverter();
|
|
|
|
return $converter->convertToHtml($markdown);
|
|
}
|
|
} |