diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index 75a6963..fecf179 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.00.00 +# VERSION: 02.26.01 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/CHANGELOG.md b/CHANGELOG.md index ee127e6..b050022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,14 +8,20 @@ DEFGROUP: Joomla.Template.Site INGROUP: MokoOnyx.Documentation PATH: ./CHANGELOG.md - VERSION: 02.26.00 + VERSION: 02.26.01 BRIEF: Changelog file documenting version history of MokoOnyx --> -# Changelog — MokoOnyx (VERSION: 02.26.00) +# Changelog — MokoOnyx (VERSION: 02.26.01) ## [Unreleased] -## [02.26.00] --- 2026-06-20 +### Added +- Collapsible floating social bar with toggle button and localStorage persistence +- Bootstrap tooltips on all social icon links showing platform name on hover +- URL validation on social platform fields (browser, Joomla server-side, and PHP layout logging) + +### Fixed +- Moved footer social icons below footer-menu and footer module positions for correct display order ## [02.26.00] --- 2026-06-20 diff --git a/README.md b/README.md index 4444813..bd0bbb8 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A modern, lightweight Joomla site template built on Cassiopeia with Font Awesome | | | |---|---| | **Type** | Joomla Site Template | -| **Version** | 02.07.00 | +| **Version** | 02.22.00 | | **Joomla** | 5.x / 6.x | | **PHP** | 8.1+ | | **License** | GPL-3.0-or-later | @@ -39,6 +39,7 @@ On install, MokoOnyx automatically migrates settings, content references, and cu | **Table of Contents** | Automatic TOC generation for long articles | | **GTM / GA4** | Google Tag Manager and Analytics integration with smart visitor detection (login status, user group, page type) | | **Template Overrides** | Overrides for all core Joomla modules, Community Builder, and DPCalendar | +| **Social Icons** | Configurable social media links in topbar, footer, or collapsible floating sidebar with tooltips and URL validation | | **Cassiopeia Base** | Minimal core overrides for maximum Joomla upgrade compatibility | --- @@ -79,6 +80,7 @@ Key parameters include: - **Google Tag Manager**: GTM container ID - **GA4**: Measurement ID and tracking options - **Table of Contents**: Auto-generate TOC for articles with heading threshold +- **Social Icons**: Display positions, icon style, and platform URLs --- diff --git a/SECURITY.md b/SECURITY.md index e5760a6..d87b2e6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -10,7 +10,7 @@ INGROUP: MokoOnyx.Governance REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx FILE: SECURITY.md - VERSION: 02.26.00 + VERSION: 02.26.01 BRIEF: Security policy and vulnerability reporting process for MokoOnyx. PATH: /SECURITY.md NOTE: This policy is process oriented and does not replace secure engineering practices. diff --git a/source/html/layouts/joomla/module/card.php b/source/html/layouts/joomla/module/card.php index da381d3..60189d0 100644 --- a/source/html/layouts/joomla/module/card.php +++ b/source/html/layouts/joomla/module/card.php @@ -10,7 +10,7 @@ * INGROUP: MokoOnyx * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx * PATH: /html/layouts/joomla/module/card.php - * VERSION: 02.26.00 + * VERSION: 02.26.01 * BRIEF: Custom card module chrome — renders module titles for all modules */ diff --git a/source/html/layouts/mokoonyx/article-metadata.php b/source/html/layouts/mokoonyx/article-metadata.php index d8611b2..b99aec6 100644 --- a/source/html/layouts/mokoonyx/article-metadata.php +++ b/source/html/layouts/mokoonyx/article-metadata.php @@ -11,7 +11,7 @@ * INGROUP: MokoOnyx.Layouts * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx * PATH: /src/html/layouts/mokoonyx/article-metadata.php - * VERSION: 02.26.00 + * VERSION: 02.26.01 * BRIEF: Article metadata footer layout -- renders jcfields grouped by field group */ diff --git a/source/html/layouts/mokoonyx/social-icons.php b/source/html/layouts/mokoonyx/social-icons.php index 7ba30d5..c575040 100644 --- a/source/html/layouts/mokoonyx/social-icons.php +++ b/source/html/layouts/mokoonyx/social-icons.php @@ -52,13 +52,22 @@ $platforms = [ $active = []; foreach ($platforms as $key => [$iconClass, $langKey]) { $url = trim((string) $params->get('social_' . $key . '_url', '')); - if ($url !== '' && preg_match('#^(https?://|mailto:|/)#i', $url)) { - $active[] = [ - 'url' => $url, - 'iconClass' => $iconClass, - 'label' => Text::_($langKey), - ]; + if ($url === '') { + continue; } + if (!preg_match('#^(https?://[^\s<>"]+|mailto:[^\s<>"]+|/[^\s<>"]*)$#i', $url)) { + \Joomla\CMS\Log\Log::add( + 'MokoOnyx social: skipped invalid URL for "' . $key . '": ' . $url, + \Joomla\CMS\Log\Log::WARNING, + 'template' + ); + continue; + } + $active[] = [ + 'url' => $url, + 'iconClass' => $iconClass, + 'label' => Text::_($langKey), + ]; } if (empty($active)) { @@ -84,6 +93,10 @@ if ($position === 'floating') { $listClass .= ' moko-social-icons--floating-' . $floatingPos; } ?> + +
+ diff --git a/source/language/en-GB/tpl_mokoonyx.ini b/source/language/en-GB/tpl_mokoonyx.ini index 25e16e9..566a177 100644 --- a/source/language/en-GB/tpl_mokoonyx.ini +++ b/source/language/en-GB/tpl_mokoonyx.ini @@ -286,6 +286,7 @@ TPL_MOKOONYX_SOCIAL_FLOATING_POS_LABEL="Floating Position" TPL_MOKOONYX_SOCIAL_FLOATING_POS_DESC="Which side of the screen the floating social bar appears on." TPL_MOKOONYX_SOCIAL_FLOATING_POS_LEFT="Left" TPL_MOKOONYX_SOCIAL_FLOATING_POS_RIGHT="Right" +TPL_MOKOONYX_SOCIAL_FLOATING_TOGGLE="Toggle social icons sidebar" TPL_MOKOONYX_SOCIAL_COLOR_LABEL="Icon Colour" TPL_MOKOONYX_SOCIAL_COLOR_DESC="Choose the colour scheme for social icons." TPL_MOKOONYX_SOCIAL_COLOR_THEME="Theme (CSS variables)" @@ -321,7 +322,7 @@ TPL_MOKOONYX_SOCIAL_MAIL="Email us" ; ===== CSS Variables tab (social) ===== TPL_MOKOONYX_CSS_VARS_SOCIAL_LABEL="Social Icons" -TPL_MOKOONYX_CSS_VARS_SOCIAL_DESC="--social-icon-size — Icon font size (overrides size preset)--social-icon-gap — Gap between icons (default: 0.5rem)--social-icon-color — Icon colour (default: currentColor)--social-icon-hover-color — Hover colour (default: var(--accent-color-primary))--social-icon-bg — Background for circle/rounded styles--social-icon-hover-bg — Hover background--social-icon-radius — Border radius for rounded style (default: 0.375rem)"
+TPL_MOKOONYX_CSS_VARS_SOCIAL_DESC="--social-icon-size — Icon font size (overrides size preset)--social-icon-gap — Gap between icons (default: 0.5rem)--social-icon-color — Icon colour (default: currentColor)--social-icon-hover-color — Hover colour (default: var(--accent-color-primary))--social-icon-bg — Background for circle/rounded styles--social-icon-hover-bg — Hover background--social-icon-radius — Border radius for rounded style (default: 0.375rem)--social-icon-bg, --social-icon-color, and --social-icon-hover-bg. Tooltips appear automatically on hover showing the platform name."
; ===== Misc =====
MOD_BREADCRUMBS_HERE="YOU ARE HERE:"
diff --git a/source/language/en-US/tpl_mokoonyx.ini b/source/language/en-US/tpl_mokoonyx.ini
index 3e60211..a671025 100644
--- a/source/language/en-US/tpl_mokoonyx.ini
+++ b/source/language/en-US/tpl_mokoonyx.ini
@@ -286,6 +286,7 @@ TPL_MOKOONYX_SOCIAL_FLOATING_POS_LABEL="Floating Position"
TPL_MOKOONYX_SOCIAL_FLOATING_POS_DESC="Which side of the screen the floating social bar appears on."
TPL_MOKOONYX_SOCIAL_FLOATING_POS_LEFT="Left"
TPL_MOKOONYX_SOCIAL_FLOATING_POS_RIGHT="Right"
+TPL_MOKOONYX_SOCIAL_FLOATING_TOGGLE="Toggle social icons sidebar"
TPL_MOKOONYX_SOCIAL_COLOR_LABEL="Icon Color"
TPL_MOKOONYX_SOCIAL_COLOR_DESC="Choose the color scheme for social icons."
TPL_MOKOONYX_SOCIAL_COLOR_THEME="Theme (CSS variables)"
@@ -321,7 +322,7 @@ TPL_MOKOONYX_SOCIAL_MAIL="Email us"
; ===== CSS Variables tab (social) =====
TPL_MOKOONYX_CSS_VARS_SOCIAL_LABEL="Social Icons"
-TPL_MOKOONYX_CSS_VARS_SOCIAL_DESC="--social-icon-size — Icon font size (overrides size preset)--social-icon-gap — Gap between icons (default: 0.5rem)--social-icon-color — Icon color (default: currentColor)--social-icon-hover-color — Hover color (default: var(--accent-color-primary))--social-icon-bg — Background for circle/rounded styles--social-icon-hover-bg — Hover background--social-icon-radius — Border radius for rounded style (default: 0.375rem)"
+TPL_MOKOONYX_CSS_VARS_SOCIAL_DESC="--social-icon-size — Icon font size (overrides size preset)--social-icon-gap — Gap between icons (default: 0.5rem)--social-icon-color — Icon color (default: currentColor)--social-icon-hover-color — Hover color (default: var(--accent-color-primary))--social-icon-bg — Background for circle/rounded styles--social-icon-hover-bg — Hover background--social-icon-radius — Border radius for rounded style (default: 0.375rem)--social-icon-bg, --social-icon-color, and --social-icon-hover-bg. Tooltips appear automatically on hover showing the platform name."
; ===== Misc =====
MOD_BREADCRUMBS_HERE="YOU ARE HERE:"
diff --git a/source/media/css/a11y-high-contrast.css b/source/media/css/a11y-high-contrast.css
index 23c5ecf..1e3e014 100644
--- a/source/media/css/a11y-high-contrast.css
+++ b/source/media/css/a11y-high-contrast.css
@@ -10,7 +10,7 @@
* INGROUP: MokoOnyx.Accessibility
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: ./media/css/a11y-high-contrast.css
- * VERSION: 02.26.00
+ * VERSION: 02.26.01
* BRIEF: High-contrast stylesheet for accessibility toolbar
*/
diff --git a/source/media/css/template.css b/source/media/css/template.css
index 9b4762a..c668d1f 100644
--- a/source/media/css/template.css
+++ b/source/media/css/template.css
@@ -23522,7 +23522,7 @@ font-size: 0.8125rem;
.blog-item .item-image img {
width: 100%;
height: 100%;
- object-fit: cover;
+ object-fit: none;
}
.fa-brands {
@@ -23679,26 +23679,42 @@ font-size: 0.8125rem;
}
/* Position: floating — fixed sidebar, hidden on mobile */
-.moko-social-icons--floating {
+.moko-social-floating-wrap {
position: fixed;
top: 50%;
transform: translateY(-50%);
z-index: 1030;
display: flex;
+ align-items: center;
+ transition: transform 0.3s ease;
+}
+
+.moko-social-floating-wrap--left {
+ left: 0;
+ flex-direction: row;
+}
+
+.moko-social-floating-wrap--right {
+ right: 0;
+ flex-direction: row-reverse;
+}
+
+.moko-social-floating-wrap--left.is-collapsed {
+ transform: translateY(-50%) translateX(calc(-100% + 1.5rem));
+}
+
+.moko-social-floating-wrap--right.is-collapsed {
+ transform: translateY(-50%) translateX(calc(100% - 1.5rem));
+}
+
+.moko-social-icons--floating {
+ display: flex;
}
.moko-social-icons--floating ul {
flex-direction: column;
}
-.moko-social-icons--floating-left {
- left: 0;
-}
-
-.moko-social-icons--floating-right {
- right: 0;
-}
-
.moko-social-icons--floating-left a {
border-radius: 0 var(--social-icon-radius, 0.375rem) var(--social-icon-radius, 0.375rem) 0;
}
@@ -23712,8 +23728,48 @@ font-size: 0.8125rem;
border-radius: inherit;
}
+/* Floating toggle button */
+.moko-social-floating-toggle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 1.5rem;
+ height: 2.5rem;
+ padding: 0;
+ border: 1px solid var(--social-icon-bg, var(--border-color, hsl(0, 0%, 80%)));
+ background: var(--social-icon-bg, var(--body-bg, hsl(0, 0%, 100%)));
+ color: var(--social-icon-color, currentColor);
+ cursor: pointer;
+ font-size: 0.65rem;
+ transition: background 0.2s, color 0.2s;
+ flex-shrink: 0;
+}
+
+.moko-social-floating-wrap--left .moko-social-floating-toggle {
+ border-radius: 0 var(--social-icon-radius, 0.375rem) var(--social-icon-radius, 0.375rem) 0;
+ border-left: 0;
+}
+
+.moko-social-floating-wrap--right .moko-social-floating-toggle {
+ border-radius: var(--social-icon-radius, 0.375rem) 0 0 var(--social-icon-radius, 0.375rem);
+ border-right: 0;
+}
+
+.moko-social-floating-toggle:hover {
+ background: var(--social-icon-hover-bg, var(--accent-color-primary, hsl(220, 70%, 50%)));
+ color: #fff;
+}
+
+.moko-social-floating-toggle .fa-solid {
+ transition: transform 0.3s ease;
+}
+
+.is-collapsed .moko-social-floating-toggle .fa-solid {
+ transform: rotate(180deg);
+}
+
@media (max-width: 991.98px) {
- .moko-social-icons--floating {
+ .moko-social-floating-wrap {
display: none;
}
}
diff --git a/source/media/js/template.js b/source/media/js/template.js
index 70a2f6a..b650658 100644
--- a/source/media/js/template.js
+++ b/source/media/js/template.js
@@ -789,6 +789,46 @@
});
}
+ // ========================================================================
+ // FLOATING SOCIAL BAR (collapsible)
+ // ========================================================================
+ var socialStorageKey = "moko-social-collapsed";
+
+ function initSocialFloating() {
+ var wrap = doc.getElementById("mokoSocialFloating");
+ var toggle = doc.getElementById("mokoSocialFloatingToggle");
+ if (!wrap || !toggle) return;
+
+ // Restore saved state
+ try {
+ if (localStorage.getItem(socialStorageKey) === "1") {
+ wrap.classList.add("is-collapsed");
+ toggle.setAttribute("aria-expanded", "false");
+ }
+ } catch (e) {}
+
+ toggle.addEventListener("click", function () {
+ var collapsed = wrap.classList.toggle("is-collapsed");
+ toggle.setAttribute("aria-expanded", collapsed ? "false" : "true");
+ try { localStorage.setItem(socialStorageKey, collapsed ? "1" : "0"); } catch (e) {}
+ });
+ }
+
+ // ========================================================================
+ // SOCIAL ICON TOOLTIPS
+ // ========================================================================
+ function initSocialTooltips() {
+ var triggers = doc.querySelectorAll('.moko-social-icons [data-bs-toggle="tooltip"]');
+ if (!triggers.length) return;
+
+ // Bootstrap 5 tooltip init
+ if (typeof bootstrap !== "undefined" && bootstrap.Tooltip) {
+ triggers.forEach(function (el) {
+ new bootstrap.Tooltip(el, { trigger: "hover focus" });
+ });
+ }
+ }
+
/**
* Run all template JS initializations
*/
@@ -815,6 +855,8 @@
initBackTop();
initSearchToggle();
initSidebarAccordion();
+ initSocialFloating();
+ initSocialTooltips();
initVarCopy();
}
diff --git a/source/templateDetails.xml b/source/templateDetails.xml
index e3ad60a..e2b8820 100644
--- a/source/templateDetails.xml
+++ b/source/templateDetails.xml
@@ -35,7 +35,7 @@