Rebuild article system

This commit is contained in:
2025-06-09 20:59:09 -06:00
parent 2ffa1b2267
commit 6d996abe27
8 changed files with 422 additions and 40 deletions
+43 -38
View File
@@ -1,57 +1,62 @@
<?php
$debug = 5;
require '_debug.php';
#$debug = 5;
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/lib/debug.php';
require __DIR__ . '/lib/render_markdown.php';
require __DIR__ . '/lib/render_php.php';
# Pattern begins '/' foloowed by 1 or more characters that are not '/' or '.'
# Pattern begins '/' followed by 1 or more characters that are not '/' or '.'
# In particular this blocks attempts to hack into system
#
# Example path '/article/market' will result in 'market' which we can try to
# match with 'market.php' or 'market.md'
if (preg_match('#/([^/.]+)#',$_SERVER['PATH_INFO'], $m) === false) {
# Nullish ?? is used to set default page for article summaries
if (!preg_match('#/([^/.]+)#',$_SERVER['PATH_INFO']??'/index', $m)) {
http_response_code('400');
echo "Request {$_SERVER['PATH_INFO']} malformed";
echo "Request Path info malformed";
exit;
}
$page = $m[1];
# Identify type of file as PHP or Markdown
if (file_exists($page . '.php')) {
$file = $page . '.php';
$type = 'php';
} else if (file_exists($page . '.md')) {
$file = $page . '.md';
$type = 'markdown';
$page = $m[1];
if ($page !== 'index') {
# Identify type of file as PHP or Markdown
if (file_exists($page . '.php')) {
$file = $page . '.php';
$type = 'php';
$article = render_php($file);
} else if (file_exists($page . '.md')) {
$file = $page . '.md';
$type = 'markdown';
$article = render_markdown($file);
} else {
# Unknown or invalid path
http_response_code('404');
echo "File '$page' not found";
exit;
}
} else {
# Unknown or invalid path
http_response_code('404');
echo "File '$page' not found";
exit;
$article = [
'meta' => [ 'title' => 'articles' ],
'html' => <<<HTML
<h1>Placeholder for article listings</h1>
HTML,
];
}
$template = file_get_contents('template.inc');
$result = preg_replace_callback('/\[(\w+)\]/', function ($matches) use ($article) {
$key = $matches[1];
return isset($article['meta'][$key]) ? $article['meta'][$key] : $matches[0]; // fallback to original if key not found
}, $template);
$rendered= preg_replace('/\[contents?\]/', $article['html'], $result);
debug("PAGE: $page\n"
."TYPE: $type\n"
."FILE: $file\n"
."PATH: {$_SERVER['PATH_INFO']}\n");
# Load file, we do include rather than file_get_contents so PHP can be
# executed if needed
ob_start();
include __DIR__ . '/' . $file;
$contents = ob_get_clean();
# Split off head matter
#
# this pattern uses the 'ms' modifier to treat multiline strings as a
# single string, and let '\s', '.' etc treat newlines as whitespace
# I match an _optional_ HTML ( '<!-- nnnn -->') comment if we want to wrap
# the headmatter in a comment.
#
# The headmatter is delimited by either '----' or '++++' as per
# Markdown/yaml standards.
# Technical note that '+' is a regex character so \+{3,} instead of ++++
if (preg_match('/^(<!--\s*)?(-{3,}|\+{3,})(.*)(-{3,}|\+{3,})(-->)?(.*)/ms',$contents, $parts) === true) {
$var_dump($parts);
}
echo $rendered;