Add favicon configuration with auto-generation from PNG upload

- New "Favicon" tab in template config with media picker for PNG upload
- helper/favicon.php generates all standard sizes from source PNG using GD:
  - favicon.ico (16x16 + 32x32 embedded)
  - apple-touch-icon.png (180x180)
  - favicon-32x32.png, favicon-16x16.png
  - android-chrome-192x192.png, android-chrome-512x512.png
  - site.webmanifest for PWA icon discovery
- Generated files cached in images/favicons/ with timestamp checking
- Link tags auto-injected in <head> when favicon source is configured
- Language strings added for en-GB and en-US

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-02 13:45:34 -05:00
parent de5b4395cd
commit 96161f34ae
6 changed files with 210 additions and 0 deletions

View File

@@ -57,6 +57,7 @@ $params_googlesitekey = $this->params->get('googlesitekey', null);
$params_custom_head_start = $this->params->get('custom_head_start', null);
$params_custom_head_end = $this->params->get('custom_head_end', null);
$params_developmentmode = $this->params->get('developmentmode', false);
$params_favicon_source = (string) $this->params->get('favicon_source', '');
// Theme params
$params_theme_enabled = $this->params->get('theme_enabled', 1);
@@ -78,6 +79,19 @@ $pageclass = $menu !== null ? $menu->getParams()->get('pageclass_sfx', '') : '';
// Template/Media path
$templatePath = 'media/templates/site/mokocassiopeia';
// Favicon generation
$faviconHeadTags = '';
if ($params_favicon_source) {
require_once __DIR__ . '/helper/favicon.php';
$faviconSourceAbs = JPATH_ROOT . '/' . ltrim($params_favicon_source, '/');
$faviconOutputDir = JPATH_ROOT . '/images/favicons';
$faviconUrlBase = Uri::root(true) . '/images/favicons';
if (MokoFaviconHelper::generate($faviconSourceAbs, $faviconOutputDir)) {
$faviconHeadTags = MokoFaviconHelper::getHeadTags($faviconUrlBase);
}
}
// Core template CSS
$wa->useStyle('template.base'); // css/template.css
@@ -246,6 +260,9 @@ $wa->useScript('user.js'); // js/user.js
<head>
<?php if (trim($params_custom_head_start)) : ?><?php echo $params_custom_head_start; ?><?php endif; ?>
<jdoc:include type="head" />
<?php if ($faviconHeadTags) : ?>
<?php echo $faviconHeadTags; ?>
<?php endif; ?>
<?php if ($params_theme_enabled) : ?>
<script>