Move rendering into private templates
Add an explicit template renderer with HTML views and partials for the app, bootstrap, package, and catalog pages. Move shared reporting setup into config/reporting.php and relocate stylesheet assets under css/.
This commit is contained in:
+117
-65
@@ -5,12 +5,19 @@
|
||||
* Shared page header renderer for logged-in application pages.
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/Template.php';
|
||||
|
||||
function app_header_h($s)
|
||||
{
|
||||
return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
return RacketSandboxTemplate::escape($s);
|
||||
}
|
||||
|
||||
function render_app_header($options)
|
||||
{
|
||||
echo app_header_html($options);
|
||||
}
|
||||
|
||||
function app_header_html($options)
|
||||
{
|
||||
$title = (string)($options['title'] ?? '');
|
||||
$navItems = $options['nav_items'] ?? array();
|
||||
@@ -26,69 +33,114 @@ function render_app_header($options)
|
||||
$logoutLabel = (string)($options['logout_label'] ?? '');
|
||||
$message = (string)($options['message'] ?? '');
|
||||
$error = (string)($options['error'] ?? '');
|
||||
?>
|
||||
<header class="page-header">
|
||||
<div class="page-titlebar">
|
||||
<h1><?= app_header_h($title) ?></h1>
|
||||
|
||||
<nav class="header-nav" aria-label="<?= app_header_h($title) ?> navigation">
|
||||
<?php foreach ($navItems as $item): ?>
|
||||
<?php if (!empty($item['separator_before'])): ?>
|
||||
<span class="nav-separator" aria-hidden="true">|</span>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($item['active'])): ?>
|
||||
<strong><?= app_header_h($item['label'] ?? '') ?></strong>
|
||||
<?php else: ?>
|
||||
<a href="<?= app_header_h($item['url'] ?? '#') ?>"><?= app_header_h($item['label'] ?? '') ?></a>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php if ($logoutAction !== '' && $logoutLabel !== ''): ?>
|
||||
<span class="nav-separator" aria-hidden="true">|</span>
|
||||
<form class="header-action-form" method="post" action="<?= app_header_h($logoutAction) ?>">
|
||||
<input type="hidden" name="action" value="logout">
|
||||
<button type="submit"><?= app_header_h($logoutLabel) ?></button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($user !== null): ?>
|
||||
<span class="nav-separator" aria-hidden="true">|</span>
|
||||
<span class="nav-user">
|
||||
<?php if ($userPrefix !== ''): ?>
|
||||
<?= app_header_h($userPrefix) ?>
|
||||
<?php endif; ?>
|
||||
<?= app_header_h($user->displayName()) ?>
|
||||
<?php if ($user->isAdmin()): ?>
|
||||
<span class="small">(<?= app_header_h($adminLabel) ?>)</span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
|
||||
<form class="header-language-form" method="get" action="<?= app_header_h($languageAction) ?>">
|
||||
<?php foreach ($languageHidden as $name => $value): ?>
|
||||
<input type="hidden" name="<?= app_header_h($name) ?>" value="<?= app_header_h($value) ?>">
|
||||
<?php endforeach; ?>
|
||||
<label>
|
||||
<?= app_header_h($languageLabel) ?>
|
||||
<select name="lang" onchange="this.form.submit()">
|
||||
<?php foreach ($languages as $lang => $label): ?>
|
||||
<option value="<?= app_header_h($lang) ?>" <?= $lang === $language ? 'selected' : '' ?>>
|
||||
<?= app_header_h($label) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
</form>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<?php if ($message !== ''): ?>
|
||||
<div class="message"><?= app_header_h($message) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($error !== ''): ?>
|
||||
<div class="error"><?= app_header_h($error) ?></div>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
<?php
|
||||
return RacketSandboxTemplate::renderFile('app-header.html', array(
|
||||
'title' => $title,
|
||||
'nav_html' => app_header_nav_html($navItems),
|
||||
'logout_html' => app_header_logout_html($logoutAction, $logoutLabel),
|
||||
'user_html' => app_header_user_html($user, $userPrefix, $adminLabel),
|
||||
'language_html' => app_header_language_html($languageLabel, $language, $languages, $languageAction, $languageHidden),
|
||||
'message_html' => app_header_status_html('message', $message),
|
||||
'error_html' => app_header_status_html('error', $error),
|
||||
));
|
||||
}
|
||||
|
||||
function app_header_status_html($class, $message)
|
||||
{
|
||||
if ($message === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return RacketSandboxTemplate::renderFile('partials/message.html', array(
|
||||
'class' => $class,
|
||||
'message' => $message,
|
||||
));
|
||||
}
|
||||
|
||||
function app_header_nav_html($navItems)
|
||||
{
|
||||
$html = '';
|
||||
|
||||
foreach ($navItems as $item) {
|
||||
if (!empty($item['separator_before'])) {
|
||||
$html .= RacketSandboxTemplate::renderFile('partials/header-separator.html', array()) . "\n";
|
||||
}
|
||||
|
||||
if (!empty($item['active'])) {
|
||||
$html .= RacketSandboxTemplate::renderFile('partials/header-nav-active.html', array(
|
||||
'label' => $item['label'] ?? '',
|
||||
)) . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$html .= RacketSandboxTemplate::renderFile('partials/header-nav-link.html', array(
|
||||
'url' => $item['url'] ?? '#',
|
||||
'label' => $item['label'] ?? '',
|
||||
)) . "\n";
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
function app_header_logout_html($logoutAction, $logoutLabel)
|
||||
{
|
||||
if ($logoutAction === '' || $logoutLabel === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return RacketSandboxTemplate::renderFile('partials/header-logout.html', array(
|
||||
'logout_action' => $logoutAction,
|
||||
'logout_label' => $logoutLabel,
|
||||
)) . "\n";
|
||||
}
|
||||
|
||||
function app_header_user_html($user, $userPrefix, $adminLabel)
|
||||
{
|
||||
if ($user === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$adminHtml = '';
|
||||
|
||||
if ($user->isAdmin()) {
|
||||
$adminHtml = RacketSandboxTemplate::renderFile('partials/header-admin-badge.html', array(
|
||||
'admin_label' => $adminLabel,
|
||||
));
|
||||
}
|
||||
|
||||
return RacketSandboxTemplate::renderFile('partials/header-user.html', array(
|
||||
'user_prefix' => $userPrefix,
|
||||
'display_name' => $user->displayName(),
|
||||
'admin_html' => $adminHtml,
|
||||
)) . "\n";
|
||||
}
|
||||
|
||||
function app_header_language_html($languageLabel, $language, $languages, $languageAction, $languageHidden)
|
||||
{
|
||||
$hiddenInputsHtml = '';
|
||||
|
||||
foreach ($languageHidden as $name => $value) {
|
||||
$hiddenInputsHtml .= RacketSandboxTemplate::renderFile('partials/header-hidden-input.html', array(
|
||||
'name' => $name,
|
||||
'value' => $value,
|
||||
)) . "\n";
|
||||
}
|
||||
|
||||
$languageOptionsHtml = '';
|
||||
|
||||
foreach ($languages as $lang => $label) {
|
||||
$selected = $lang === $language ? ' selected' : '';
|
||||
$languageOptionsHtml .= RacketSandboxTemplate::renderFile('partials/select-option.html', array(
|
||||
'value' => $lang,
|
||||
'selected' => $selected,
|
||||
'label' => $label,
|
||||
)) . "\n";
|
||||
}
|
||||
|
||||
return RacketSandboxTemplate::renderFile('partials/header-language.html', array(
|
||||
'language_action' => $languageAction,
|
||||
'hidden_inputs_html' => $hiddenInputsHtml,
|
||||
'language_label' => $languageLabel,
|
||||
'language_options_html' => $languageOptionsHtml,
|
||||
)) . "\n";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user