chore: trigger update-server workflow for version suffix [skip bump]
Universal: Auto Version Bump / Version Bump (push) Has been cancelled
Generic: Repo Health / Site Health (push) Has been cancelled
Generic: Repo Health / Access control (push) Has been cancelled
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled

This commit is contained in:
Moko Consulting
2026-05-28 14:02:40 -05:00
committed by Jonathan Miller
parent 153cd407e3
commit eec06b1875
21 changed files with 478 additions and 1008 deletions
+2
View File
@@ -20,6 +20,8 @@
<build>
<language>PHP</language>
<package-type>joomla</package-type>
<joomla-type>module</joomla-type>
<joomla-element>mod_mokojoomhero</joomla-element>
<entry-point>src/</entry-point>
</build>
</moko-platform>
+1 -1
View File
@@ -13,7 +13,7 @@
# Extension Configuration
EXTENSION_NAME := mokojoomhero
EXTENSION_TYPE := template
EXTENSION_TYPE := module
# Options: module, plugin, component, package, template
EXTENSION_VERSION := 1.0.0
-39
View File
@@ -1,39 +0,0 @@
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoJoomHero.Template
* INGROUP: MokoJoomHero
* REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
* PATH: /src/component.php
* VERSION: 01.00.01
* BRIEF: Component-only output — used when ?tmpl=component strips all template chrome
*/
defined('_JEXEC') or die;
use Joomla\CMS\Document\HtmlDocument;
/** @var HtmlDocument $this */
$wa = $this->getWebAssetManager();
$wa->usePreset('template.tpl_mokojoomhero');
?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<jdoc:include type="metas" />
<jdoc:include type="styles" />
<jdoc:include type="scripts" />
</head>
<body class="contentpane component">
<jdoc:include type="message" />
<jdoc:include type="component" />
</body>
</html>
+67 -300
View File
@@ -3,328 +3,95 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoJoomHero.Template.Assets
* INGROUP: MokoJoomHero.Template
* REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
* DEFGROUP: MokoJoomHero.Module.Assets
* INGROUP: MokoJoomHero.Module
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero
* PATH: /src/css/template.css
* VERSION: 01.00.01
* BRIEF: Main template stylesheet — base layout, typography, and module chrome
* BRIEF: Hero module stylesheet — slideshow, video background, overlay
*/
/* ============================================================
CSS Custom Properties
Hero container
============================================================ */
:root {
--brand-color: #1a73e8;
--brand-color-dark: #1557b0;
--text-color: #333;
--text-muted: #666;
--bg-color: #fff;
--bg-light: #f8f9fa;
--border-color: #dee2e6;
--header-height: 64px;
--sidebar-width: 260px;
--container-max: 1200px;
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
--spacing-xl: 3rem;
--radius: 6px;
--shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
--transition: 0.2s ease;
}
/* ============================================================
Reset & Base
============================================================ */
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 1rem;
line-height: 1.6;
color: var(--text-color);
background-color: var(--bg-color);
}
img {
max-width: 100%;
height: auto;
}
a {
color: var(--brand-color);
text-decoration: none;
}
a:hover {
color: var(--brand-color-dark);
text-decoration: underline;
}
/* ============================================================
Container
============================================================ */
.container {
width: 100%;
max-width: var(--container-max);
margin-inline: auto;
padding-inline: var(--spacing-md);
}
.container-fluid {
width: 100%;
padding-inline: var(--spacing-md);
}
/* ============================================================
Header
============================================================ */
.site-header {
background: var(--bg-color);
border-bottom: 1px solid var(--border-color);
z-index: 100;
}
.site-header.sticky-header {
position: sticky;
top: 0;
}
.header-inner {
display: flex;
align-items: center;
justify-content: space-between;
min-height: var(--header-height);
gap: var(--spacing-md);
}
.site-brand a {
display: flex;
align-items: center;
gap: var(--spacing-sm);
text-decoration: none;
}
.site-logo {
height: 40px;
width: auto;
}
.site-title {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-color);
}
.site-description {
font-size: 0.875rem;
color: var(--text-muted);
margin: 0;
}
/* ============================================================
Navigation
============================================================ */
.site-navigation ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: var(--spacing-sm);
}
.site-navigation a {
display: block;
padding: var(--spacing-sm) var(--spacing-md);
color: var(--text-color);
border-radius: var(--radius);
transition: background var(--transition);
}
.site-navigation a:hover,
.site-navigation a.active {
background: var(--bg-light);
text-decoration: none;
color: var(--brand-color);
}
/* ============================================================
Topbar
============================================================ */
.topbar {
background: var(--bg-light);
border-bottom: 1px solid var(--border-color);
font-size: 0.875rem;
padding: var(--spacing-xs) 0;
}
/* ============================================================
Hero Section
============================================================ */
.hero-section {
padding: var(--spacing-xl) 0;
background: linear-gradient(135deg, var(--brand-color) 0%, var(--brand-color-dark) 100%);
color: #fff;
}
.hero-section h1,
.hero-section h2 {
color: #fff;
}
/* ============================================================
Breadcrumbs
============================================================ */
.breadcrumbs-area {
padding: var(--spacing-sm) 0;
background: var(--bg-light);
border-bottom: 1px solid var(--border-color);
font-size: 0.875rem;
}
/* ============================================================
Main Content Layout
============================================================ */
.site-main {
padding: var(--spacing-lg) 0;
min-height: 50vh;
}
.content-area {
display: flex;
gap: var(--spacing-lg);
}
.content-body {
flex: 1;
min-width: 0;
}
.sidebar {
flex: 0 0 var(--sidebar-width);
}
/* ============================================================
Module Chrome — card style
============================================================ */
.card {
background: var(--bg-color);
border: 1px solid var(--border-color);
border-radius: var(--radius);
box-shadow: var(--shadow);
margin-bottom: var(--spacing-md);
.mokojoomhero {
position: relative;
overflow: hidden;
}
.card .card-header {
padding: var(--spacing-md);
border-bottom: 1px solid var(--border-color);
font-weight: 600;
}
.card .card-body {
padding: var(--spacing-md);
}
/* ============================================================
Footer
============================================================ */
.site-footer {
background: var(--bg-light);
border-top: 1px solid var(--border-color);
padding: var(--spacing-lg) 0;
margin-top: var(--spacing-xl);
}
.footer-copyright {
text-align: center;
font-size: 0.875rem;
color: var(--text-muted);
}
.footer-copyright p {
margin: 0;
}
/* ============================================================
Back to Top
============================================================ */
.back-to-top {
position: fixed;
bottom: 2rem;
right: 2rem;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: var(--brand-color);
color: #fff;
border-radius: 50%;
text-decoration: none;
box-shadow: var(--shadow);
opacity: 0;
visibility: hidden;
transition: opacity var(--transition), visibility var(--transition);
z-index: 99;
}
.back-to-top.visible {
opacity: 1;
visibility: visible;
}
.back-to-top:hover {
background: var(--brand-color-dark);
color: #fff;
text-decoration: none;
}
/* ============================================================
System Messages
Image slides
============================================================ */
.alert {
padding: var(--spacing-md);
margin-bottom: var(--spacing-md);
border: 1px solid transparent;
border-radius: var(--radius);
.mokojoomhero__slide {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
opacity: 0;
transition: opacity 1s ease;
}
.alert-message { background: #d1ecf1; border-color: #bee5eb; color: #0c5460; }
.alert-warning { background: #fff3cd; border-color: #ffeeba; color: #856404; }
.alert-error { background: #f8d7da; border-color: #f5c6cb; color: #721c24; }
.mokojoomhero__slide--active {
opacity: 1;
}
/* ============================================================
Video background
============================================================ */
.mokojoomhero__video {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
/* ============================================================
Overlay
============================================================ */
.mokojoomhero__overlay {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
padding: 2rem;
}
/* ============================================================
Content
============================================================ */
.mokojoomhero__content {
max-width: 900px;
width: 100%;
}
.mokojoomhero__content h1,
.mokojoomhero__content h2,
.mokojoomhero__content h3 {
margin-top: 0;
color: inherit;
}
.mokojoomhero__content p:last-child {
margin-bottom: 0;
}
/* ============================================================
Responsive
============================================================ */
@media (max-width: 768px) {
.header-inner {
flex-direction: column;
align-items: flex-start;
padding: var(--spacing-sm) 0;
.mokojoomhero__overlay {
padding: 1rem;
}
.site-navigation ul {
flex-direction: column;
width: 100%;
}
.content-area {
flex-direction: column;
}
.sidebar {
flex: 1 1 auto;
.mokojoomhero__content {
font-size: 0.9rem;
}
}
-88
View File
@@ -1,88 +0,0 @@
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoJoomHero.Template
* INGROUP: MokoJoomHero
* REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
* PATH: /src/error.php
* VERSION: 01.00.01
* BRIEF: Error page template — displayed for 403, 404, 500, etc.
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
/** @var Joomla\CMS\Document\ErrorDocument $this */
$app = Factory::getApplication();
// Error details
$error_code = $this->error->getCode();
$error_message = $this->error->getMessage();
if (!in_array($error_code, [400, 401, 403, 404, 500])) {
$error_code = 500;
}
?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo $error_code; ?> - <?php echo htmlspecialchars($error_message, ENT_QUOTES, 'UTF-8'); ?></title>
<link rel="stylesheet" href="<?php echo Uri::root(true); ?>/templates/tpl_mokojoomhero/css/template.css">
<style>
.error-page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
text-align: center;
padding: 2rem;
}
.error-code {
font-size: 6rem;
font-weight: 700;
color: var(--brand-color, #1a73e8);
line-height: 1;
margin: 0 0 1rem;
}
.error-message {
font-size: 1.25rem;
color: #555;
margin: 0 0 2rem;
}
.error-home {
display: inline-block;
padding: 0.75rem 1.5rem;
background: var(--brand-color, #1a73e8);
color: #fff;
border-radius: 4px;
text-decoration: none;
transition: opacity 0.2s;
}
.error-home:hover {
opacity: 0.85;
}
</style>
</head>
<body class="site error-<?php echo $error_code; ?>">
<div class="error-page">
<p class="error-code"><?php echo $error_code; ?></p>
<p class="error-message"><?php echo htmlspecialchars($error_message, ENT_QUOTES, 'UTF-8'); ?></p>
<a href="<?php echo Uri::base(); ?>" class="error-home">
<?php echo Text::_('JERROR_LAYOUT_HOME_PAGE'); ?>
</a>
</div>
</body>
</html>
-1
View File
@@ -1 +0,0 @@
<!DOCTYPE html><title></title>
-182
View File
@@ -1,182 +0,0 @@
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoJoomHero.Template
* INGROUP: MokoJoomHero
* REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
* PATH: /src/index.php
* VERSION: 01.00.01
* BRIEF: Main template entry point — renders the full HTML page
*/
defined('_JEXEC') or die;
use Joomla\CMS\Document\HtmlDocument;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
/** @var HtmlDocument $this */
$app = Factory::getApplication();
$wa = $this->getWebAssetManager();
$params = $app->getTemplate(true)->params;
// Register and use template assets via Web Asset Manager
$wa->usePreset('template.tpl_mokojoomhero');
// Template parameters
$logo = $params->get('logoFile', '');
$site_description = $params->get('siteDescription', '');
$brand_color = $params->get('brandColor', '#1a73e8');
$fluid = (bool) $params->get('fluidContainer', 0);
$sticky_header = (bool) $params->get('stickyHeader', 1);
$back_to_top = (bool) $params->get('backToTop', 1);
$container_class = $fluid ? 'container-fluid' : 'container';
// Inject brand color as CSS custom property
$this->addHeadStyle(':root { --brand-color: ' . htmlspecialchars($brand_color, ENT_QUOTES, 'UTF-8') . '; }');
?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<jdoc:include type="metas" />
<jdoc:include type="styles" />
<jdoc:include type="scripts" />
</head>
<body class="site <?php echo $this->direction === 'rtl' ? 'rtl' : 'ltr'; ?>">
<?php // Topbar position ?>
<?php if ($this->countModules('topbar')) : ?>
<div class="topbar">
<div class="<?php echo $container_class; ?>">
<jdoc:include type="modules" name="topbar" style="none" />
</div>
</div>
<?php endif; ?>
<?php // Header ?>
<header class="site-header<?php echo $sticky_header ? ' sticky-header' : ''; ?>">
<div class="<?php echo $container_class; ?>">
<div class="header-inner">
<?php // Site branding ?>
<div class="site-brand">
<a href="<?php echo Uri::base(); ?>">
<?php if ($logo) : ?>
<img src="<?php echo htmlspecialchars($logo, ENT_QUOTES, 'UTF-8'); ?>"
alt="<?php echo htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8'); ?>"
class="site-logo" />
<?php else : ?>
<span class="site-title"><?php echo htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8'); ?></span>
<?php endif; ?>
</a>
<?php if ($site_description) : ?>
<p class="site-description"><?php echo htmlspecialchars($site_description, ENT_QUOTES, 'UTF-8'); ?></p>
<?php endif; ?>
</div>
<?php // Navigation ?>
<?php if ($this->countModules('menu')) : ?>
<nav class="site-navigation" aria-label="<?php echo Text::_('TPL_MOKOJOOMHERO_MAIN_NAV'); ?>">
<jdoc:include type="modules" name="menu" style="none" />
</nav>
<?php endif; ?>
</div>
</div>
</header>
<?php // Banner ?>
<?php if ($this->countModules('banner')) : ?>
<div class="banner-area">
<jdoc:include type="modules" name="banner" style="none" />
</div>
<?php endif; ?>
<?php // Hero section ?>
<?php if ($this->countModules('hero')) : ?>
<section class="hero-section">
<div class="<?php echo $container_class; ?>">
<jdoc:include type="modules" name="hero" style="hero" />
</div>
</section>
<?php endif; ?>
<?php // Breadcrumbs ?>
<?php if ($this->countModules('breadcrumbs')) : ?>
<div class="breadcrumbs-area">
<div class="<?php echo $container_class; ?>">
<jdoc:include type="modules" name="breadcrumbs" style="none" />
</div>
</div>
<?php endif; ?>
<?php // Main content area ?>
<main class="site-main">
<div class="<?php echo $container_class; ?>">
<?php if ($this->countModules('main-top')) : ?>
<div class="main-top">
<jdoc:include type="modules" name="main-top" style="card" />
</div>
<?php endif; ?>
<div class="content-area">
<?php // Sidebar left ?>
<?php if ($this->countModules('sidebar-left')) : ?>
<aside class="sidebar sidebar-left" role="complementary">
<jdoc:include type="modules" name="sidebar-left" style="card" />
</aside>
<?php endif; ?>
<?php // Component output ?>
<div class="content-body">
<jdoc:include type="message" />
<jdoc:include type="component" />
</div>
<?php // Sidebar right ?>
<?php if ($this->countModules('sidebar-right')) : ?>
<aside class="sidebar sidebar-right" role="complementary">
<jdoc:include type="modules" name="sidebar-right" style="card" />
</aside>
<?php endif; ?>
</div>
<?php if ($this->countModules('main-bottom')) : ?>
<div class="main-bottom">
<jdoc:include type="modules" name="main-bottom" style="card" />
</div>
<?php endif; ?>
</div>
</main>
<?php // Footer ?>
<footer class="site-footer">
<div class="<?php echo $container_class; ?>">
<?php if ($this->countModules('footer')) : ?>
<jdoc:include type="modules" name="footer" style="none" />
<?php endif; ?>
<div class="footer-copyright">
<p>&copy; <?php echo date('Y'); ?> <?php echo htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8'); ?></p>
</div>
</div>
</footer>
<?php // Back to top button ?>
<?php if ($back_to_top) : ?>
<a href="#" class="back-to-top" aria-label="<?php echo Text::_('TPL_MOKOJOOMHERO_BACK_TO_TOP'); ?>">
<span aria-hidden="true">&uarr;</span>
</a>
<?php endif; ?>
<?php // Debug position ?>
<jdoc:include type="modules" name="debug" style="none" />
</body>
</html>
+7 -7
View File
@@ -1,26 +1,26 @@
{
"$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
"name": "tpl_mokojoomhero",
"name": "mod_mokojoomhero",
"version": "1.0.0",
"description": "MokoJoomHero template web assets",
"description": "MokoJoomHero module web assets",
"license": "GPL-3.0-or-later",
"assets": [
{
"name": "template.tpl_mokojoomhero",
"name": "mod_mokojoomhero",
"type": "preset",
"dependencies": [
"template.tpl_mokojoomhero.css",
"template.tpl_mokojoomhero.js"
"mod_mokojoomhero.css",
"mod_mokojoomhero.js"
]
},
{
"name": "template.tpl_mokojoomhero.css",
"name": "mod_mokojoomhero.css",
"type": "style",
"uri": "css/template.css",
"version": "1.0.0"
},
{
"name": "template.tpl_mokojoomhero.js",
"name": "mod_mokojoomhero.js",
"type": "script",
"uri": "js/template.js",
"version": "1.0.0",
+21 -19
View File
@@ -4,32 +4,34 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoJoomHero.Template.Assets
* INGROUP: MokoJoomHero.Template
* REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
* DEFGROUP: MokoJoomHero.Module.Assets
* INGROUP: MokoJoomHero.Module
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero
* PATH: /src/js/template.js
* VERSION: 01.00.01
* BRIEF: Main template JavaScript — back-to-top toggle and lightweight UI helpers
* BRIEF: Hero module JavaScript — image slideshow crossfade
*/
'use strict';
document.addEventListener('DOMContentLoaded', function () {
// Back-to-top button visibility toggle
var backToTop = document.querySelector('.back-to-top');
document.querySelectorAll('.mokojoomhero[data-slides]').forEach(function (hero) {
var slides = hero.querySelectorAll('.mokojoomhero__slide');
var interval = parseInt(hero.dataset.interval, 10) || 5000;
var current = 0;
if (backToTop) {
window.addEventListener('scroll', function () {
if (window.scrollY > 300) {
backToTop.classList.add('visible');
} else {
backToTop.classList.remove('visible');
}
}, { passive: true });
if (slides.length < 2) {
return;
}
backToTop.addEventListener('click', function (e) {
e.preventDefault();
window.scrollTo({ top: 0, behavior: 'smooth' });
});
}
setInterval(function () {
slides[current].classList.remove('mokojoomhero__slide--active');
slides[current].setAttribute('aria-hidden', 'true');
current = (current + 1) % slides.length;
slides[current].classList.add('mokojoomhero__slide--active');
slides[current].setAttribute('aria-hidden', 'false');
}, interval);
});
});
+12
View File
@@ -0,0 +1,12 @@
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
; SPDX-License-Identifier: GPL-3.0-or-later
;
; FILE INFORMATION
; DEFGROUP: MokoJoomHero.Module.Language
; INGROUP: MokoJoomHero.Module
; REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero
; PATH: /src/language/en-GB/mod_mokojoomhero.ini
; VERSION: 01.00.01
; BRIEF: Front-end language strings for MokoJoomHero module
MOD_MOKOJOOMHERO_NO_CONTENT="Add content to this module to display it over the hero image."
@@ -0,0 +1,51 @@
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
; SPDX-License-Identifier: GPL-3.0-or-later
;
; FILE INFORMATION
; DEFGROUP: MokoJoomHero.Module.Language
; INGROUP: MokoJoomHero.Module
; REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero
; PATH: /src/language/en-GB/mod_mokojoomhero.sys.ini
; VERSION: 01.00.01
; BRIEF: System language strings — used in admin Extension Manager and Module Manager
MOD_MOKOJOOMHERO="Module - MokoJoomHero"
MOD_MOKOJOOMHERO_DESCRIPTION="Displays a random hero image slideshow or background video with content overlaid. Designed for MokoOnyx template. By Moko Consulting."
; Hero mode
MOD_MOKOJOOMHERO_MODE_LABEL="Hero Mode"
MOD_MOKOJOOMHERO_MODE_DESC="Choose between a slideshow of images or a background video."
MOD_MOKOJOOMHERO_MODE_IMAGES="Images"
MOD_MOKOJOOMHERO_MODE_VIDEO="Video"
; Image settings
MOD_MOKOJOOMHERO_IMAGE_FOLDER_LABEL="Image Folder"
MOD_MOKOJOOMHERO_IMAGE_FOLDER_DESC="Path to folder containing hero images, relative to Joomla root (e.g. images/heroes)."
MOD_MOKOJOOMHERO_IMAGE_COUNT_LABEL="Number of Images"
MOD_MOKOJOOMHERO_IMAGE_COUNT_DESC="How many random images to include in the slideshow (15)."
MOD_MOKOJOOMHERO_SLIDE_INTERVAL_LABEL="Slide Interval (ms)"
MOD_MOKOJOOMHERO_SLIDE_INTERVAL_DESC="Time between slides in milliseconds (e.g. 5000 = 5 seconds)."
; Video settings
MOD_MOKOJOOMHERO_VIDEO_FILE_LABEL="Video File"
MOD_MOKOJOOMHERO_VIDEO_FILE_DESC="Path or URL to the background video file (MP4 recommended)."
; Hero height
MOD_MOKOJOOMHERO_HERO_HEIGHT_LABEL="Hero Height"
MOD_MOKOJOOMHERO_HERO_HEIGHT_DESC="CSS height of the hero section (e.g. 400px, 60vh)."
; Overlay fieldset
MOD_MOKOJOOMHERO_FIELDSET_OVERLAY="Overlay &amp; Text"
MOD_MOKOJOOMHERO_OVERLAY_COLOR_LABEL="Overlay Colour"
MOD_MOKOJOOMHERO_OVERLAY_COLOR_DESC="Background colour of the overlay on top of the hero image."
MOD_MOKOJOOMHERO_OVERLAY_OPACITY_LABEL="Overlay Opacity"
MOD_MOKOJOOMHERO_OVERLAY_OPACITY_DESC="Transparency of the overlay (0 = fully transparent, 1 = fully opaque)."
MOD_MOKOJOOMHERO_TEXT_ALIGN_LABEL="Text Alignment"
MOD_MOKOJOOMHERO_TEXT_ALIGN_DESC="Horizontal alignment of the overlay text."
MOD_MOKOJOOMHERO_TEXT_COLOR_LABEL="Text Colour"
MOD_MOKOJOOMHERO_TEXT_COLOR_DESC="Colour of the text displayed over the hero image."
; Alignment options
MOD_MOKOJOOMHERO_ALIGN_LEFT="Left"
MOD_MOKOJOOMHERO_ALIGN_CENTER="Centre"
MOD_MOKOJOOMHERO_ALIGN_RIGHT="Right"
-13
View File
@@ -1,13 +0,0 @@
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
; SPDX-License-Identifier: GPL-3.0-or-later
;
; FILE INFORMATION
; DEFGROUP: MokoJoomHero.Template.Language
; INGROUP: MokoJoomHero.Template
; REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
; PATH: /src/language/en-GB/tpl_mokojoomhero.ini
; VERSION: 01.00.01
; BRIEF: Front-end language strings for MokoJoomHero template
TPL_MOKOJOOMHERO_MAIN_NAV="Main Navigation"
TPL_MOKOJOOMHERO_BACK_TO_TOP="Back to top"
@@ -1,25 +0,0 @@
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
; SPDX-License-Identifier: GPL-3.0-or-later
;
; FILE INFORMATION
; DEFGROUP: MokoJoomHero.Template.Language
; INGROUP: MokoJoomHero.Template
; REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
; PATH: /src/language/en-GB/tpl_mokojoomhero.sys.ini
; VERSION: 01.00.01
; BRIEF: System language strings — used in admin Extension Manager and Template Manager
TPL_MOKOJOOMHERO="MokoJoomHero"
TPL_MOKOJOOMHERO_DESCRIPTION="A modern, accessible Joomla template by Moko Consulting. Features a hero section, flexible module positions, sticky header, and customisable brand colour."
TPL_MOKOJOOMHERO_LOGO_FILE_LABEL="Logo"
TPL_MOKOJOOMHERO_LOGO_FILE_DESC="Select an image to use as the site logo."
TPL_MOKOJOOMHERO_SITE_DESCRIPTION_LABEL="Site Description"
TPL_MOKOJOOMHERO_SITE_DESCRIPTION_DESC="A short tagline displayed next to the logo."
TPL_MOKOJOOMHERO_BRAND_COLOR_LABEL="Brand Colour"
TPL_MOKOJOOMHERO_BRAND_COLOR_DESC="Primary accent colour used throughout the template."
TPL_MOKOJOOMHERO_FLUID_LABEL="Fluid Container"
TPL_MOKOJOOMHERO_FLUID_DESC="Use a full-width container instead of a fixed-width one."
TPL_MOKOJOOMHERO_STICKY_HEADER_LABEL="Sticky Header"
TPL_MOKOJOOMHERO_STICKY_HEADER_DESC="Keep the header visible when scrolling."
TPL_MOKOJOOMHERO_BACK_TO_TOP_LABEL="Back to Top Button"
TPL_MOKOJOOMHERO_BACK_TO_TOP_DESC="Show a floating button that scrolls the page to the top."
+75
View File
@@ -0,0 +1,75 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_mokojoomhero
*
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
* @license GPL-3.0-or-later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\ModuleHelper;
use Joomla\CMS\Uri\Uri;
/** @var \Joomla\Registry\Registry $params */
// Register and load module assets via Web Asset Manager
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->getRegistry()->addExtensionRegistryFile('mod_mokojoomhero');
$wa->usePreset('mod_mokojoomhero');
// Module parameters
$heroMode = $params->get('heroMode', 'images');
$imageFolder = $params->get('imageFolder', 'images/heroes');
$imageCount = (int) $params->get('imageCount', 5);
$slideInterval = (int) $params->get('slideInterval', 5000);
$videoFile = $params->get('videoFile', '');
$heroHeight = $params->get('heroHeight', '400px');
$overlayColor = $params->get('overlayColor', '#000000');
$overlayOpacity = (float) $params->get('overlayOpacity', 0.5);
$textAlign = $params->get('textAlign', 'center');
$textColor = $params->get('textColor', '#ffffff');
// Collect hero images
$heroImages = [];
if ($heroMode === 'images') {
$folderPath = JPATH_ROOT . '/' . ltrim($imageFolder, '/');
if (is_dir($folderPath)) {
$allowed = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'avif', 'svg'];
$all = [];
foreach (new DirectoryIterator($folderPath) as $file) {
if ($file->isFile() && in_array(strtolower($file->getExtension()), $allowed, true)) {
$all[] = $file->getFilename();
}
}
if ($all) {
shuffle($all);
$picked = array_slice($all, 0, min($imageCount, 5));
foreach ($picked as $filename) {
$heroImages[] = Uri::root() . $imageFolder . '/' . $filename;
}
}
}
}
// Build video URL (relative path → absolute)
$videoUrl = '';
if ($heroMode === 'video' && $videoFile) {
$videoUrl = (strpos($videoFile, '://') !== false)
? $videoFile
: Uri::root() . ltrim($videoFile, '/');
}
// Module content from the editor (overlay text)
$content = $module->content ?? '';
require ModuleHelper::getLayoutPath('mod_mokojoomhero', $params->get('layout', 'default'));
+150
View File
@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
This file is part of a Moko Consulting project.
SPDX-License-Identifier: GPL-3.0-or-later
FILE INFORMATION
DEFGROUP: MokoJoomHero.Module
INGROUP: MokoJoomHero
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero
PATH: /src/mod_mokojoomhero.xml
VERSION: 01.00.01
BRIEF: Joomla module manifest — random hero image with content overlay
-->
<extension type="module" client="site" method="upgrade">
<name>mod_mokojoomhero</name>
<creationDate>2026-05</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<copyright>Copyright (C) 2026 Moko Consulting. All rights reserved.</copyright>
<license>GPL-3.0-or-later</license>
<version>1.0.0</version>
<description>MOD_MOKOJOOMHERO_DESCRIPTION</description>
<files>
<filename module="mod_mokojoomhero">mod_mokojoomhero.php</filename>
<filename>mod_mokojoomhero.xml</filename>
<filename>joomla.asset.json</filename>
<folder>tmpl</folder>
<folder>css</folder>
<folder>js</folder>
<folder>language</folder>
</files>
<languages folder="language">
<language tag="en-GB">en-GB/mod_mokojoomhero.ini</language>
<language tag="en-GB">en-GB/mod_mokojoomhero.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="heroMode"
type="list"
label="MOD_MOKOJOOMHERO_MODE_LABEL"
description="MOD_MOKOJOOMHERO_MODE_DESC"
default="images"
>
<option value="images">MOD_MOKOJOOMHERO_MODE_IMAGES</option>
<option value="video">MOD_MOKOJOOMHERO_MODE_VIDEO</option>
</field>
<field
name="imageFolder"
type="text"
label="MOD_MOKOJOOMHERO_IMAGE_FOLDER_LABEL"
description="MOD_MOKOJOOMHERO_IMAGE_FOLDER_DESC"
default="images/heroes"
filter="path"
showon="heroMode:images"
/>
<field
name="imageCount"
type="number"
label="MOD_MOKOJOOMHERO_IMAGE_COUNT_LABEL"
description="MOD_MOKOJOOMHERO_IMAGE_COUNT_DESC"
default="5"
min="1"
max="5"
showon="heroMode:images"
/>
<field
name="slideInterval"
type="number"
label="MOD_MOKOJOOMHERO_SLIDE_INTERVAL_LABEL"
description="MOD_MOKOJOOMHERO_SLIDE_INTERVAL_DESC"
default="5000"
min="1000"
step="500"
showon="heroMode:images"
/>
<field
name="videoFile"
type="text"
label="MOD_MOKOJOOMHERO_VIDEO_FILE_LABEL"
description="MOD_MOKOJOOMHERO_VIDEO_FILE_DESC"
filter="url"
showon="heroMode:video"
/>
<field
name="heroHeight"
type="text"
label="MOD_MOKOJOOMHERO_HERO_HEIGHT_LABEL"
description="MOD_MOKOJOOMHERO_HERO_HEIGHT_DESC"
default="400px"
filter="string"
/>
</fieldset>
<fieldset name="advanced"
label="MOD_MOKOJOOMHERO_FIELDSET_OVERLAY"
>
<field
name="overlayColor"
type="color"
label="MOD_MOKOJOOMHERO_OVERLAY_COLOR_LABEL"
description="MOD_MOKOJOOMHERO_OVERLAY_COLOR_DESC"
default="#000000"
/>
<field
name="overlayOpacity"
type="range"
label="MOD_MOKOJOOMHERO_OVERLAY_OPACITY_LABEL"
description="MOD_MOKOJOOMHERO_OVERLAY_OPACITY_DESC"
default="0.5"
min="0"
max="1"
step="0.1"
/>
<field
name="textAlign"
type="list"
label="MOD_MOKOJOOMHERO_TEXT_ALIGN_LABEL"
description="MOD_MOKOJOOMHERO_TEXT_ALIGN_DESC"
default="center"
>
<option value="left">MOD_MOKOJOOMHERO_ALIGN_LEFT</option>
<option value="center">MOD_MOKOJOOMHERO_ALIGN_CENTER</option>
<option value="right">MOD_MOKOJOOMHERO_ALIGN_RIGHT</option>
</field>
<field
name="textColor"
type="color"
label="MOD_MOKOJOOMHERO_TEXT_COLOR_LABEL"
description="MOD_MOKOJOOMHERO_TEXT_COLOR_DESC"
default="#ffffff"
/>
</fieldset>
</fields>
</config>
<updateservers>
<server type="extension" priority="1" name="MokoJoomHero Updates">
https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/raw/branch/main/updates.xml
</server>
</updateservers>
</extension>
-134
View File
@@ -1,134 +0,0 @@
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoJoomHero.Template
* INGROUP: MokoJoomHero
* REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
* PATH: /src/offline.php
* VERSION: 01.00.01
* BRIEF: Offline page template — shown when the site is taken offline via Global Configuration
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\AuthenticationHelper;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
/** @var Joomla\CMS\Document\HtmlDocument $this */
$app = Factory::getApplication();
// Offline message from Global Configuration
$offline_message = $app->get('offline_message', Text::_('JOFFLINE_MESSAGE'));
// Extra login methods
$extra_buttons = AuthenticationHelper::getLoginButtons('form-login');
?>
<!DOCTYPE html>
<html lang="<?php echo $this->language; ?>" dir="<?php echo $this->direction; ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8'); ?> — <?php echo Text::_('JOFFLINE'); ?></title>
<link rel="stylesheet" href="<?php echo Uri::root(true); ?>/templates/tpl_mokojoomhero/css/template.css">
<jdoc:include type="head" />
<style>
.offline-page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
text-align: center;
padding: 2rem;
}
.offline-message {
font-size: 1.25rem;
color: #555;
margin: 0 0 2rem;
max-width: 600px;
}
.offline-login {
max-width: 400px;
width: 100%;
padding: 2rem;
border: 1px solid #ddd;
border-radius: 8px;
}
.offline-login .form-group {
margin-bottom: 1rem;
text-align: left;
}
.offline-login label {
display: block;
margin-bottom: 0.25rem;
font-weight: 600;
}
.offline-login input[type="text"],
.offline-login input[type="password"] {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
}
.offline-login button {
width: 100%;
padding: 0.75rem;
background: var(--brand-color, #1a73e8);
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
</style>
</head>
<body class="site offline">
<div class="offline-page">
<h1><?php echo htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8'); ?></h1>
<jdoc:include type="message" />
<p class="offline-message"><?php echo htmlspecialchars($offline_message, ENT_QUOTES, 'UTF-8'); ?></p>
<div class="offline-login">
<h2><?php echo Text::_('JLOGIN'); ?></h2>
<form action="<?php echo Route::_('index.php', true); ?>" method="post" id="form-login">
<div class="form-group">
<label for="username"><?php echo Text::_('JGLOBAL_USERNAME'); ?></label>
<input type="text" name="username" id="username" required>
</div>
<div class="form-group">
<label for="password"><?php echo Text::_('JGLOBAL_PASSWORD'); ?></label>
<input type="password" name="password" id="password" required>
</div>
<button type="submit"><?php echo Text::_('JLOGIN'); ?></button>
<input type="hidden" name="option" value="com_users">
<input type="hidden" name="task" value="user.login">
<input type="hidden" name="return" value="<?php echo base64_encode(Uri::base()); ?>">
<?php echo HTMLHelper::_('form.token'); ?>
</form>
<?php if (!empty($extra_buttons)) : ?>
<div class="offline-login-extra">
<?php foreach ($extra_buttons as $button) : ?>
<div class="mt-1">
<a class="btn btn-secondary w-100" href="<?php echo $button['url']; ?>">
<?php echo htmlspecialchars($button['label'], ENT_QUOTES, 'UTF-8'); ?>
</a>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</div>
</body>
</html>
-129
View File
@@ -1,129 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
This file is part of a Moko Consulting project.
SPDX-License-Identifier: GPL-3.0-or-later
FILE INFORMATION
DEFGROUP: MokoJoomHero.Template
INGROUP: MokoJoomHero
REPO: https://github.com/mokoconsulting-tech/MokoJoomHero
PATH: /src/templateDetails.xml
VERSION: 01.00.01
BRIEF: Joomla template manifest — defines metadata, files, positions, and parameters
-->
<extension type="template" client="site" method="upgrade">
<name>tpl_mokojoomhero</name>
<creationDate>2026-05</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<copyright>Copyright (C) 2026 Moko Consulting. All rights reserved.</copyright>
<license>GPL-3.0-or-later</license>
<version>1.0.0</version>
<description>TPL_MOKOJOOMHERO_DESCRIPTION</description>
<inheritable>0</inheritable>
<files>
<filename>index.php</filename>
<filename>error.php</filename>
<filename>offline.php</filename>
<filename>component.php</filename>
<filename>joomla.asset.json</filename>
<filename>templateDetails.xml</filename>
<folder>css</folder>
<folder>js</folder>
<folder>images</folder>
<folder>html</folder>
<folder>language</folder>
</files>
<media destination="templates/site/tpl_mokojoomhero" folder="media">
<folder>css</folder>
<folder>js</folder>
<folder>images</folder>
</media>
<positions>
<position>topbar</position>
<position>banner</position>
<position>menu</position>
<position>hero</position>
<position>breadcrumbs</position>
<position>sidebar-left</position>
<position>sidebar-right</position>
<position>main-top</position>
<position>main-bottom</position>
<position>footer</position>
<position>debug</position>
</positions>
<languages folder="language">
<language tag="en-GB">en-GB/tpl_mokojoomhero.ini</language>
<language tag="en-GB">en-GB/tpl_mokojoomhero.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="logoFile"
type="media"
label="TPL_MOKOJOOMHERO_LOGO_FILE_LABEL"
description="TPL_MOKOJOOMHERO_LOGO_FILE_DESC"
/>
<field
name="siteDescription"
type="text"
label="TPL_MOKOJOOMHERO_SITE_DESCRIPTION_LABEL"
description="TPL_MOKOJOOMHERO_SITE_DESCRIPTION_DESC"
filter="string"
/>
<field
name="brandColor"
type="color"
label="TPL_MOKOJOOMHERO_BRAND_COLOR_LABEL"
description="TPL_MOKOJOOMHERO_BRAND_COLOR_DESC"
default="#1a73e8"
/>
</fieldset>
<fieldset name="advanced">
<field
name="fluidContainer"
type="radio"
layout="joomla.form.field.radio.switcher"
label="TPL_MOKOJOOMHERO_FLUID_LABEL"
description="TPL_MOKOJOOMHERO_FLUID_DESC"
default="0"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="stickyHeader"
type="radio"
layout="joomla.form.field.radio.switcher"
label="TPL_MOKOJOOMHERO_STICKY_HEADER_LABEL"
description="TPL_MOKOJOOMHERO_STICKY_HEADER_DESC"
default="1"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="backToTop"
type="radio"
layout="joomla.form.field.radio.switcher"
label="TPL_MOKOJOOMHERO_BACK_TO_TOP_LABEL"
description="TPL_MOKOJOOMHERO_BACK_TO_TOP_DESC"
default="1"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
</fields>
</config>
</extension>
+66
View File
@@ -0,0 +1,66 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_mokojoomhero
*
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
* @license GPL-3.0-or-later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Language\Text;
/** @var string $heroMode */
/** @var array $heroImages */
/** @var int $slideInterval */
/** @var string $videoUrl */
/** @var string $heroHeight */
/** @var string $overlayColor */
/** @var float $overlayOpacity */
/** @var string $textAlign */
/** @var string $textColor */
/** @var string $content */
$moduleId = 'mod-mokojoomhero-' . $module->id;
// Convert hex overlay colour to rgba
$r = hexdec(substr($overlayColor, 1, 2));
$g = hexdec(substr($overlayColor, 3, 2));
$b = hexdec(substr($overlayColor, 5, 2));
$rgba = "rgba($r, $g, $b, $overlayOpacity)";
$heightAttr = htmlspecialchars($heroHeight, ENT_QUOTES, 'UTF-8');
?>
<div id="<?php echo $moduleId; ?>" class="mokojoomhero" style="height: <?php echo $heightAttr; ?>;"
<?php if ($heroMode === 'images' && count($heroImages) > 1) : ?>
data-slides="<?php echo htmlspecialchars(json_encode($heroImages), ENT_QUOTES, 'UTF-8'); ?>"
data-interval="<?php echo $slideInterval; ?>"
<?php endif; ?>
>
<?php // Background layer — single image, slideshow, or video ?>
<?php if ($heroMode === 'video' && $videoUrl) : ?>
<video class="mokojoomhero__video" autoplay muted loop playsinline>
<source src="<?php echo htmlspecialchars($videoUrl, ENT_QUOTES, 'UTF-8'); ?>">
</video>
<?php elseif ($heroImages) : ?>
<?php foreach ($heroImages as $i => $img) : ?>
<div class="mokojoomhero__slide<?php echo $i === 0 ? ' mokojoomhero__slide--active' : ''; ?>"
style="background-image: url('<?php echo htmlspecialchars($img, ENT_QUOTES, 'UTF-8'); ?>');"
aria-hidden="<?php echo $i === 0 ? 'false' : 'true'; ?>">
</div>
<?php endforeach; ?>
<?php endif; ?>
<?php // Overlay + content ?>
<div class="mokojoomhero__overlay" style="background-color: <?php echo $rgba; ?>;">
<div class="mokojoomhero__content" style="text-align: <?php echo htmlspecialchars($textAlign, ENT_QUOTES, 'UTF-8'); ?>; color: <?php echo htmlspecialchars($textColor, ENT_QUOTES, 'UTF-8'); ?>;">
<?php if ($content) : ?>
<?php echo $content; ?>
<?php else : ?>
<p><?php echo Text::_('MOD_MOKOJOOMHERO_NO_CONTENT'); ?></p>
<?php endif; ?>
</div>
</div>
</div>
+13 -17
View File
@@ -1,17 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Joomla Extension Update Server XML
See: https://docs.joomla.org/Deploying_an_Update_Server
This file is the update server manifest for {{EXTENSION_NAME}}.
This file is the update server manifest for mod_mokojoomhero.
The Joomla installer polls this URL to check for new versions.
The manifest.xml in this repository must reference this file:
The manifest in this repository must reference this file:
<updateservers>
<server type="extension" priority="1" name="{{EXTENSION_NAME}}">
https://git.mokoconsulting.tech/mokoconsulting-tech/MokoJoomHero/raw/branch/main/update.xml
</server>
<server type="extension" priority="2" name="{{EXTENSION_NAME}}">
https://raw.githubusercontent.com/mokoconsulting-tech/MokoJoomHero/main/update.xml
<server type="extension" priority="1" name="MokoJoomHero Updates">
https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/raw/branch/main/updates.xml
</server>
</updateservers>
@@ -20,20 +18,18 @@
-->
<updates>
<update>
<name>{{EXTENSION_NAME}}</name>
<description>MokoJoomHero — Moko Consulting Joomla extension</description>
<element>{{EXTENSION_ELEMENT}}</element>
<type>{{EXTENSION_TYPE}}</type>
<name>Module - MokoJoomHero</name>
<description>MokoJoomHero — A Joomla hero image module by Moko Consulting</description>
<element>mod_mokojoomhero</element>
<type>module</type>
<client>site</client>
<version>{{VERSION}}</version>
<downloads>
<downloadurl type="full" format="zip">
https://git.mokoconsulting.tech/mokoconsulting-tech/MokoJoomHero/releases/download/v{{VERSION}}/{{EXTENSION_ELEMENT}}.zip
</downloadurl>
<downloadurl type="full" format="zip">
https://github.com/mokoconsulting-tech/MokoJoomHero/releases/download/v{{VERSION}}/{{EXTENSION_ELEMENT}}.zip
https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/v{{VERSION}}/mod_mokojoomhero.zip
</downloadurl>
</downloads>
<targetplatform name="joomla" version="[56].*"/>
<targetplatform name="joomla" version="(5|6).*" />
<php_minimum>8.1</php_minimum>
</update>
</updates>
</updates>
+13 -53
View File
@@ -1,59 +1,19 @@
<!--
Joomla Extension Update Server XML
See: https://docs.joomla.org/Deploying_an_Update_Server
This file is the update server manifest for {{EXTENSION_NAME}}.
The Joomla installer polls this URL to check for new versions.
The manifest.xml in this repository must reference this file:
<updateservers>
<server type="extension" priority="1" name="{{EXTENSION_NAME}}">
https://git.mokoconsulting.tech/mokoconsulting-tech/MokoJoomHero/raw/branch/main/updates.xml
</server>
<server type="extension" priority="2" name="{{EXTENSION_NAME}}">
https://raw.githubusercontent.com/mokoconsulting-tech/MokoJoomHero/main/updates.xml
</server>
</updateservers>
When a new release is made, run `make release` or the release workflow to
prepend a new <update> entry to this file automatically.
-->
<?xml version="1.0" encoding="utf-8"?>
<updates>
<update>
<name>{{EXTENSION_NAME}}</name>
<description>MokoJoomHero — Moko Consulting Joomla extension</description>
<element>{{EXTENSION_ELEMENT}}</element>
<type>{{EXTENSION_TYPE}}</type>
<version>{{VERSION}}</version>
<name>Module - MokoJoomHero</name>
<description>MokoJoomHero — A Joomla hero image module by Moko Consulting</description>
<element>mod_mokojoomhero</element>
<type>module</type>
<client>site</client>
<version>1.0.0</version>
<infourl title="Moko JoomHero">https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero</infourl>
<downloads>
<downloadurl type="full" format="zip">
https://git.mokoconsulting.tech/mokoconsulting-tech/MokoJoomHero/releases/download/v{{VERSION}}/{{EXTENSION_ELEMENT}}.zip
</downloadurl>
<downloadurl type="full" format="zip">
https://github.com/mokoconsulting-tech/MokoJoomHero/releases/download/v{{VERSION}}/{{EXTENSION_ELEMENT}}.zip
</downloadurl>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/v1.0.0/mod_mokojoomhero-1.0.0.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="[56].*"/>
<targetplatform name="joomla" version="(5|6).*" />
<php_minimum>8.1</php_minimum>
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>tpl_mokojoomhero</name>
<description>tpl_mokojoomhero development build.</description>
<element>mokojoomhero</element>
<type>template</type>
<client>site</client>
<version>01.00.02</version>
<creationDate>2026-05-16</creationDate>
<infourl title='tpl_mokojoomhero'>https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/tag/development</infourl>
<downloads>
<downloadurl type='full' format='zip'>https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/development/mokojoomhero-01.00.02-dev.zip</downloadurl>
</downloads>
<sha256>7c85c337030507e2a07c79d333a652bcb1fd8497be221fcb2aeaa2ca038c0b22</sha256>
<tags><tag>development</tag></tags>
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
<targetplatform name='joomla' version='(5|6).*'/>
</update>
</updates>
</updates>