helper_append_version($src, $version),
'defer' => $defer,
'async' => $async,
'type' => $type,
'module' => $module,
];
if ($pos === 'header') {
$GLOBALS['page_header_scripts'][] = $data;
} else {
$GLOBALS['page_footer_scripts'][] = $data;
}
}
function tpl_add_style(
string $href,
string $pos = 'header',
string $priority = 'normal',
?string $version = null,
string $media = 'all'
): void {
$GLOBALS['page_styles'][] = [
'href' => helper_append_version($href, $version),
'pos' => $pos,
'priority' => $priority,
'media' => $media,
];
}
function tpl(string $file, string $type = 'structure', string $site = 'admin'): void
{
$base = __DIR__ . '/../partials/';
$safe = static function ($value) {
return preg_match('/^[a-zA-Z0-9_\-]+$/', $value) === 1;
};
if (!$safe($file) || !$safe($type) || !$safe($site)) {
echo "";
return;
}
$path = $type === 'landing'
? $base . "landingpage/{$site}/{$file}.php"
: $base . "structure/{$file}.php";
extract($GLOBALS, EXTR_SKIP);
if (is_file($path)) {
include $path;
} else {
echo "";
}
}
function tpl_render_scripts(?array $scripts = null, string $pos = 'footer'): void
{
if ($scripts === null) {
$scripts = $pos === 'header'
? ($GLOBALS['page_header_scripts'] ?? [])
: ($GLOBALS['page_footer_scripts'] ?? []);
}
foreach ($scripts as $script) {
if (empty($script['src'])) {
continue;
}
$attrs = [];
if (!empty($script['module'])) {
$attrs[] = 'type="module"';
} elseif (!empty($script['type'])) {
$attrs[] = 'type="' . htmlspecialchars((string)$script['type'], ENT_QUOTES) . '"';
}
if (!empty($script['defer'])) {
$attrs[] = 'defer';
}
if (!empty($script['async'])) {
$attrs[] = 'async';
}
$attrString = '';
if (!empty($attrs)) {
$attrString = ' ' . implode(' ', $attrs);
}
echo '' . PHP_EOL;
}
}
function tpl_render_styles(?array $styles = null, string $pos = 'header'): void
{
if ($styles === null) {
$styles = array_filter(
$GLOBALS['page_styles'] ?? [],
static fn ($style) => ($style['pos'] ?? 'header') === $pos
);
}
if (!$styles) {
return;
}
$priorityOrder = ['critical' => 0, 'high' => 1, 'normal' => 2, 'low' => 3];
usort($styles, static function ($a, $b) use ($priorityOrder) {
$aPriority = strtolower($a['priority'] ?? 'normal');
$bPriority = strtolower($b['priority'] ?? 'normal');
$aScore = $priorityOrder[$aPriority] ?? $priorityOrder['normal'];
$bScore = $priorityOrder[$bPriority] ?? $priorityOrder['normal'];
return $aScore <=> $bScore;
});
foreach ($styles as $style) {
if (empty($style['href'])) {
continue;
}
$media = trim((string)($style['media'] ?? ''));
$mediaAttr = $media && strtolower($media) !== 'all' ? ' media="' . htmlspecialchars($media, ENT_QUOTES) . '"' : '';
echo '' . PHP_EOL;
}
}