94aea8501f
Changed: [app/View.php](/Users/tyemeclifford/Documents/GH/blog/app/View.php): generated URLs now honor a base path like /blog. [app/Config.php](/Users/tyemeclifford/Documents/GH/blog/app/Config.php): added base_path support and derives it from base_url or SCRIPT_NAME. [app/App.php](/Users/tyemeclifford/Documents/GH/blog/app/App.php): route parsing strips the base path, and PHP can safely serve theme/upload assets for virtual subdirectory previews. [.htaccess](/Users/tyemeclifford/Documents/GH/blog/.htaccess): removed hardcoded RewriteBase /. [themes/neon/layout.php](/Users/tyemeclifford/Documents/GH/blog/themes/neon/layout.php): root-relative social links like /feed.xml now become /blog/feed.xml. [README.md](/Users/tyemeclifford/Documents/GH/blog/README.md): documented subdirectory setup.
68 lines
1.8 KiB
PHP
68 lines
1.8 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace NeonBlog;
|
|
|
|
final class View
|
|
{
|
|
private static string $basePath = '';
|
|
|
|
public static function setBasePath(string $basePath): void
|
|
{
|
|
$basePath = '/' . trim($basePath, '/');
|
|
self::$basePath = $basePath === '/' ? '' : $basePath;
|
|
}
|
|
|
|
public static function e(mixed $value): string
|
|
{
|
|
return htmlspecialchars((string) $value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
|
}
|
|
|
|
/** @param array<string, mixed> $query */
|
|
public static function url(string $path = '', array $query = []): string
|
|
{
|
|
$path = '/' . ltrim($path, '/');
|
|
if ($path !== '/' && str_ends_with($path, '/')) {
|
|
$path = rtrim($path, '/');
|
|
}
|
|
|
|
$url = self::$basePath . $path;
|
|
if ($url === '') {
|
|
$url = '/';
|
|
}
|
|
|
|
return $query === [] ? $url : $url . '?' . http_build_query($query);
|
|
}
|
|
|
|
/** @param array<string, mixed> $item */
|
|
public static function itemUrl(array $item): string
|
|
{
|
|
$slug = (string) ($item['slug'] ?? '');
|
|
return ($item['type'] ?? 'post') === 'page'
|
|
? self::url($slug)
|
|
: self::url('post/' . $slug);
|
|
}
|
|
|
|
public static function asset(string $path): string
|
|
{
|
|
return self::url('themes/neon/assets/' . ltrim($path, '/'));
|
|
}
|
|
|
|
public static function date(string $iso, string $format = 'M j, Y'): string
|
|
{
|
|
$time = strtotime($iso);
|
|
return $time ? date($format, $time) : $iso;
|
|
}
|
|
|
|
public static function month(string $yearMonth): string
|
|
{
|
|
$time = strtotime($yearMonth . '-01');
|
|
return $time ? date('F Y', $time) : $yearMonth;
|
|
}
|
|
|
|
public static function classIf(bool $condition, string $class): string
|
|
{
|
|
return $condition ? ' ' . $class : '';
|
|
}
|
|
}
|