From 6c8f561e69bdfaa1e06437d61d3dece8118cc251 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:57:55 -0500 Subject: [PATCH 01/47] ci: update AI instructions + auto-release src/ filter Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/CLAUDE.md | 378 ++++++++++++++++------------- .github/copilot-instructions.md | 21 +- .github/workflows/auto-release.yml | 3 + 3 files changed, 227 insertions(+), 175 deletions(-) diff --git a/.github/CLAUDE.md b/.github/CLAUDE.md index 45f7606..e991394 100644 --- a/.github/CLAUDE.md +++ b/.github/CLAUDE.md @@ -1,3 +1,22 @@ + + > [!IMPORTANT] > **πŸ”§ AI Self-Update Required on First Use** > @@ -19,135 +38,34 @@ > |---|---| > | `MokoCassiopeia` | The GitHub repository name (visible in the URL, `README.md` heading, or `git remote -v`) | > | `https://github.com/mokoconsulting-tech/MokoCassiopeia` | Full GitHub URL, e.g. `https://github.com/mokoconsulting-tech/` | -> | `A modern enhancement layer for Joomla’s Cassiopeia template. Moko-Cassiopeia adds Font Awesome 7, Bootstrap 5 helpers, an automatic Table of Contents (TOC) utility, and optional expansions including Google Tag Manager and Google Analytics (GA4) hooks.` | First paragraph of `README.md` body, or the GitHub repo description | > | `{{EXTENSION_NAME}}` | The `` element in `manifest.xml` at the repository root | > | `{{EXTENSION_TYPE}}` | The `type` attribute of the `` tag in `manifest.xml` (`component`, `module`, `plugin`, or `template`) | > | `{{EXTENSION_ELEMENT}}` | The `` tag in `manifest.xml`, or the filename prefix (e.g. `com_myextension`, `mod_mymodule`) | > > --- -# What This Repo Is +# MokoCassiopeia β€” GitHub Copilot Custom Instructions -**MokoCassiopeia** is a Moko Consulting **MokoWaaS** (Joomla) extension repository. +## What This Repo Is -A modern enhancement layer for Joomla’s Cassiopeia template. Moko-Cassiopeia adds Font Awesome 7, Bootstrap 5 helpers, an automatic Table of Contents (TOC) utility, and optional expansions including Google Tag Manager and Google Analytics (GA4) hooks. +This is a **Moko Consulting MokoWaaS** (Joomla) repository governed by [MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards). All coding standards, workflows, and policies are defined there and enforced here via bulk sync. +Repository URL: https://github.com/mokoconsulting-tech/MokoCassiopeia Extension name: **{{EXTENSION_NAME}}** Extension type: **{{EXTENSION_TYPE}}** (`{{EXTENSION_ELEMENT}}`) -Repository URL: https://github.com/mokoconsulting-tech/MokoCassiopeia - -This repository is governed by [MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards) β€” the single source of truth for coding standards, file-header policies, GitHub Actions workflows, and Terraform configuration templates across all Moko Consulting repositories. +Platform: **Joomla 4.x / MokoWaaS** --- -# Repo Structure +## Primary Language -``` -MokoCassiopeia/ -β”œβ”€β”€ manifest.xml # Joomla installer manifest (root β€” required) -β”œβ”€β”€ update.xml # Update server manifest (root β€” required) -β”œβ”€β”€ site/ # Frontend (site) code -β”‚ β”œβ”€β”€ controller.php -β”‚ β”œβ”€β”€ controllers/ -β”‚ β”œβ”€β”€ models/ -β”‚ └── views/ -β”œβ”€β”€ admin/ # Backend (admin) code -β”‚ β”œβ”€β”€ controller.php -β”‚ β”œβ”€β”€ controllers/ -β”‚ β”œβ”€β”€ models/ -β”‚ β”œβ”€β”€ views/ -β”‚ └── sql/ -β”œβ”€β”€ language/ # Language INI files -β”œβ”€β”€ media/ # CSS, JS, images -β”œβ”€β”€ docs/ # Technical documentation -β”œβ”€β”€ tests/ # Test suite -β”œβ”€β”€ .github/ -β”‚ β”œβ”€β”€ workflows/ # CI/CD workflows (synced from MokoStandards) -β”‚ β”œβ”€β”€ copilot-instructions.md -β”‚ └── CLAUDE.md # This file -β”œβ”€β”€ README.md # Version source of truth -β”œβ”€β”€ CHANGELOG.md -β”œβ”€β”€ CONTRIBUTING.md -└── LICENSE # GPL-3.0-or-later -``` +**PHP** (β‰₯ 7.4) is the primary language for this Joomla extension. JavaScript may be used for frontend enhancements. YAML uses 2-space indentation. All other text files use tabs per `.editorconfig`. --- -# Primary Language +## File Header β€” Always Required on New Files -**PHP** (β‰₯ 7.4) is the primary language for this Joomla extension. YAML uses 2-space indentation. All other text files use tabs per `.editorconfig`. - ---- - -# Version Management - -**`README.md` is the single source of truth for the repository version.** - -- **Bump the patch version on every PR** β€” increment `XX.YY.ZZ` (e.g. `01.02.03` β†’ `01.02.04`) in `README.md` before opening the PR; the `sync-version-on-merge` workflow propagates it to all `FILE INFORMATION` headers automatically on merge. -- Version format is zero-padded semver: `XX.YY.ZZ` (e.g. `01.02.03`). -- Never hardcode a version number in body text β€” use the badge or FILE INFORMATION header only. - -### Joomla Version Alignment - -Three files must **always have the same version**: - -| File | Where the version lives | -|------|------------------------| -| `README.md` | `FILE INFORMATION` block + badge | -| `manifest.xml` | `` tag | -| `update.xml` | `` in the most recent `` block | - -The `make release` command / release workflow syncs all three automatically. - ---- - -# update.xml β€” Required in Repo Root - -`update.xml` is the Joomla update server manifest. It allows Joomla installations to check for new versions of this extension via: - -```xml - - - - https://github.com/mokoconsulting-tech/MokoCassiopeia/raw/main/update.xml - - -``` - -**Rules:** -- Every release prepends a new `` block at the top β€” older entries are preserved. -- `` in `update.xml` must exactly match `` in `manifest.xml` and `README.md`. -- `` must be a publicly accessible GitHub Releases asset URL. -- `` β€” backslash is literal (Joomla regex syntax). - -Example `update.xml` entry for a new release: -```xml - - - {{EXTENSION_NAME}} - MokoCassiopeia - {{EXTENSION_ELEMENT}} - {{EXTENSION_TYPE}} - 01.02.04 - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/01.02.04 - - - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip - - - - 7.4 - Moko Consulting - https://mokoconsulting.tech - - -``` - ---- - -# File Header Requirements - -Every new file **must** have a copyright header as its first content. JSON files, binary files, generated files, and third-party files are exempt. +Every new file needs a copyright header as its first content. **PHP:** ```php @@ -162,47 +80,141 @@ Every new file **must** have a copyright header as its first content. JSON files * DEFGROUP: MokoCassiopeia.{{EXTENSION_TYPE}} * INGROUP: MokoCassiopeia * REPO: https://github.com/mokoconsulting-tech/MokoCassiopeia - * PATH: /site/controllers/item.php + * PATH: /path/to/file.php * VERSION: XX.YY.ZZ - * BRIEF: One-line description of file purpose + * BRIEF: One-line description of purpose */ defined('_JEXEC') or die; ``` -**Markdown / YAML / Shell / XML:** Use the appropriate comment syntax with the same fields. +**Markdown:** +```markdown + +``` + +**YAML / Shell / XML:** Use the appropriate comment syntax with the same fields. JSON files are exempt. --- -# Coding Standards +## Version Management -## Naming Conventions +**`README.md` is the single source of truth for the repository version.** -| Context | Convention | Example | -|---------|-----------|---------| -| PHP class | `PascalCase` | `ItemModel` | -| PHP method / function | `camelCase` | `getItems()` | -| PHP variable | `$snake_case` | `$item_id` | -| PHP constant | `UPPER_SNAKE_CASE` | `MAX_ITEMS` | -| PHP class file | `PascalCase.php` | `ItemModel.php` | -| YAML workflow | `kebab-case.yml` | `ci-joomla.yml` | -| Markdown doc | `kebab-case.md` | `installation-guide.md` | +- **Bump the patch version on every PR** β€” increment `XX.YY.ZZ` (e.g. `01.02.03` β†’ `01.02.04`) in `README.md` before opening the PR; the `sync-version-on-merge` workflow propagates it automatically to all badges and `FILE INFORMATION` headers on merge to `main`. +- The `VERSION: XX.YY.ZZ` field in `README.md` governs all other version references. +- Version format is zero-padded semver: `XX.YY.ZZ` (e.g. `01.02.03`). +- Never hardcode a specific version in document body text β€” use the badge or FILE INFORMATION header only. -## Commit Messages +### Joomla Version Alignment -Format: `(): ` β€” imperative, lower-case subject, no trailing period. +The version in `README.md` **must always match** the `` tag in `manifest.xml` and the latest entry in `update.xml`. The `make release` command / release workflow updates all three automatically. -Valid types: `feat` Β· `fix` Β· `docs` Β· `chore` Β· `ci` Β· `refactor` Β· `style` Β· `test` Β· `perf` Β· `revert` Β· `build` +```xml + +01.02.04 -## Branch Naming - -Format: `/[/description]` - -Approved prefixes: `dev/` Β· `rc/` Β· `version/` Β· `patch/` Β· `copilot/` Β· `dependabot/` + + + + {{EXTENSION_NAME}} + 01.02.04 + + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip + + + + + + +``` --- -# GitHub Actions β€” Token Usage +## Joomla Extension Structure + +``` +MokoCassiopeia/ +β”œβ”€β”€ manifest.xml # Joomla installer manifest (root β€” required) +β”œβ”€β”€ update.xml # Update server manifest (root β€” required, see below) +β”œβ”€β”€ site/ # Frontend (site) code +β”‚ β”œβ”€β”€ controller.php +β”‚ β”œβ”€β”€ controllers/ +β”‚ β”œβ”€β”€ models/ +β”‚ └── views/ +β”œβ”€β”€ admin/ # Backend (admin) code +β”‚ β”œβ”€β”€ controller.php +β”‚ β”œβ”€β”€ controllers/ +β”‚ β”œβ”€β”€ models/ +β”‚ β”œβ”€β”€ views/ +β”‚ └── sql/ +β”œβ”€β”€ language/ # Language INI files +β”œβ”€β”€ media/ # CSS, JS, images (deployed to /media/{{EXTENSION_ELEMENT}}/) +β”œβ”€β”€ docs/ # Technical documentation +β”œβ”€β”€ tests/ # Test suite +β”œβ”€β”€ .github/ +β”‚ β”œβ”€β”€ workflows/ +β”‚ β”œβ”€β”€ copilot-instructions.md # This file +β”‚ └── CLAUDE.md +β”œβ”€β”€ README.md # Version source of truth +β”œβ”€β”€ CHANGELOG.md +β”œβ”€β”€ CONTRIBUTING.md +β”œβ”€β”€ LICENSE # GPL-3.0-or-later +└── Makefile # Build automation +``` + +--- + +## update.xml β€” Required in Repo Root + +`update.xml` **must exist at the repository root**. It is the Joomla update server manifest that allows Joomla installations to check for new versions of this extension. + +The `manifest.xml` must reference it via: +```xml + + + https://github.com/mokoconsulting-tech/MokoCassiopeia/raw/main/update.xml + + +``` + +**Rules:** +- Every release must prepend a new `` block at the top of `update.xml` β€” old entries must be preserved below. +- The `` in `update.xml` must exactly match `` in `manifest.xml` and the version in `README.md`. +- The `` must be a publicly accessible direct download link (GitHub Releases asset URL). +- `` β€” the backslash is a **literal backslash character** in the XML attribute value; Joomla's update-server parser treats the value as a regular expression, so `\.` matches a literal dot and `[0-9]+` matches one or more digits. Do not double-escape it. + +--- + +## manifest.xml Rules + +- Lives at the repo root as `manifest.xml` (not inside `site/` or `admin/`). +- `` tag must be kept in sync with `README.md` version and `update.xml`. +- Must include `` block pointing to this repo's `update.xml`. +- Must include `` and `` sections. +- Joomla 4.x requires `Moko\{{EXTENSION_NAME}}` for namespaced extensions. + +--- + +## GitHub Actions β€” Token Usage Every workflow must use **`secrets.GH_TOKEN`** (the org-level Personal Access Token). @@ -217,58 +229,76 @@ env: ``` ```yaml -# ❌ Wrong β€” never use these +# ❌ Wrong β€” never use these in workflows token: ${{ github.token }} token: ${{ secrets.GITHUB_TOKEN }} ``` --- -# Keeping Documentation Current +## MokoStandards Reference -| Change type | Documentation to update | -|-------------|------------------------| -| New or renamed PHP class/method | PHPDoc block; `docs/api/` entry | -| New or changed `manifest.xml` | Sync version to `update.xml` and `README.md` | -| New release | Prepend `` to `update.xml`; update `CHANGELOG.md`; bump `README.md` | -| New or changed workflow | `docs/workflows/.md` | -| Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block | -| **Every PR** | **Bump the patch version** β€” increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it | - ---- - -# What NOT to Do - -- **Never commit directly to `main`** β€” all changes go through a PR. -- **Never hardcode version numbers** in body text β€” update `README.md` and let automation propagate. -- **Never let `manifest.xml`, `update.xml`, and `README.md` versions diverge.** -- **Never skip the FILE INFORMATION block** on a new source file. -- **Never use bare `catch (\Throwable $e) {}`** β€” always log or re-throw. -- **Never mix tabs and spaces** within a file β€” follow `.editorconfig`. -- **Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows** β€” always use `secrets.GH_TOKEN`. -- **Never remove `defined('_JEXEC') or die;`** from web-accessible PHP files. - ---- - -# PR Checklist - -Before opening a PR, verify: - -- [ ] Patch version bumped in `README.md` (e.g. `01.02.03` β†’ `01.02.04`) -- [ ] If this is a release: `manifest.xml` version updated; `update.xml` updated with new entry -- [ ] FILE INFORMATION headers updated in modified files -- [ ] CHANGELOG.md updated -- [ ] Tests pass - ---- - -# Key Policy Documents (MokoStandards) +This repository is governed by [MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards). Authoritative policies: | Document | Purpose | |----------|---------| | [file-header-standards.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/file-header-standards.md) | Copyright-header rules for every file type | | [coding-style-guide.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/coding-style-guide.md) | Naming and formatting conventions | | [branching-strategy.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/branching-strategy.md) | Branch naming, hierarchy, and release workflow | -| [merge-strategy.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/merge-strategy.md) | Squash-merge policy and PR conventions | +| [merge-strategy.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/merge-strategy.md) | Squash-merge policy and PR title/body conventions | | [changelog-standards.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/changelog-standards.md) | How and when to update CHANGELOG.md | -| [joomla-development-guide.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/guide/waas/joomla-development-guide.md) | MokoWaaS Joomla extension development guide | \ No newline at end of file +| [joomla-development-guide.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/guide/waas/joomla-development-guide.md) | MokoWaaS Joomla extension development guide | + +--- + +## Naming Conventions + +| Context | Convention | Example | +|---------|-----------|---------| +| PHP class | `PascalCase` | `MyController` | +| PHP method / function | `camelCase` | `getItems()` | +| PHP variable | `$snake_case` | `$item_id` | +| PHP constant | `UPPER_SNAKE_CASE` | `MAX_ITEMS` | +| PHP class file | `PascalCase.php` | `ItemModel.php` | +| YAML workflow | `kebab-case.yml` | `ci-joomla.yml` | +| Markdown doc | `kebab-case.md` | `installation-guide.md` | + +--- + +## Commit Messages + +Format: `(): ` β€” imperative, lower-case subject, no trailing period. + +Valid types: `feat` Β· `fix` Β· `docs` Β· `chore` Β· `ci` Β· `refactor` Β· `style` Β· `test` Β· `perf` Β· `revert` Β· `build` + +--- + +## Branch Naming + +Format: `/[/description]` + +Approved prefixes: `dev/` Β· `rc/` Β· `version/` Β· `patch/` Β· `copilot/` Β· `dependabot/` + +--- + +## Keeping Documentation Current + +| Change type | Documentation to update | +|-------------|------------------------| +| New or renamed PHP class/method | PHPDoc block; `docs/api/` entry | +| New or changed manifest.xml | Update `update.xml` version; bump README.md version | +| New release | Prepend `` block to `update.xml`; update CHANGELOG.md; bump README.md version | +| New or changed workflow | `docs/workflows/.md` | +| Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block | +| **Every PR** | **Bump the patch version** β€” increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it | + +--- + +## Key Constraints + +- Never commit directly to `main` β€” all changes go via PR, squash-merged +- Never skip the FILE INFORMATION block on a new file +- Never add `defined('_JEXEC') or die;` to CLI scripts or model tests β€” only to web-accessible PHP files +- Never hardcode version numbers in body text β€” update `README.md` and let automation propagate +- Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows β€” always use `secrets.GH_TOKEN` +- Never let `manifest.xml` version, `update.xml` version, and `README.md` version go out of sync diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 3968dc4..e991394 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,3 +1,22 @@ + + > [!IMPORTANT] > **πŸ”§ AI Self-Update Required on First Use** > @@ -282,4 +301,4 @@ Approved prefixes: `dev/` Β· `rc/` Β· `version/` Β· `patch/` Β· `copilot/` Β· `d - Never add `defined('_JEXEC') or die;` to CLI scripts or model tests β€” only to web-accessible PHP files - Never hardcode version numbers in body text β€” update `README.md` and let automation propagate - Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows β€” always use `secrets.GH_TOKEN` -- Never let `manifest.xml` version, `update.xml` version, and `README.md` version go out of sync \ No newline at end of file +- Never let `manifest.xml` version, `update.xml` version, and `README.md` version go out of sync diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index e9c2570..528d4cb 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -39,6 +39,9 @@ on: branches: - main - master + paths: + - 'src/**' + - 'htdocs/**' env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true From 95ff3f6909fce40033f747dd73e873356e267633 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:00:45 -0500 Subject: [PATCH 02/47] =?UTF-8?q?Remove=20update.xml=20=E2=80=94=20updates?= =?UTF-8?q?.xml=20is=20the=20canonical=20manifest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- update.xml | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 update.xml diff --git a/update.xml b/update.xml deleted file mode 100644 index 4370317..0000000 --- a/update.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - MokoCassiopeia - Moko Consulting site template based on Cassiopeia. - mokocassiopeia - template - 03.09.04 - site - - stable - - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03 - - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.09.04.zip - - da85bf5a34cafadbae26df199ed36c04438e7dab440d046e0e4117d25510feaf - - Moko Consulting - https://mokoconsulting.tech - - From cbe681738b2dd0b5f95a979dd9146496ee3c9c23 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:08:55 -0500 Subject: [PATCH 03/47] ci: updates.xml (Joomla standard), multi-stability entries Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/auto-release.yml | 32 +++++++++++------------ .github/workflows/ci-joomla.yml | 6 ++--- .github/workflows/repo_health.yml | 6 ++--- .github/workflows/update-server.yml | 40 ++++++++++++++--------------- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 528d4cb..5acbe07 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -8,7 +8,7 @@ # REPO: https://github.com/mokoconsulting-tech/MokoStandards # PATH: /templates/workflows/joomla/auto-release.yml.template # VERSION: 04.05.13 -# BRIEF: Joomla build & release β€” ZIP package, update.xml, SHA-256 checksum +# BRIEF: Joomla build & release β€” ZIP package, updates.xml, SHA-256 checksum # # +========================================================================+ # | BUILD & RELEASE PIPELINE (JOOMLA) | @@ -20,10 +20,10 @@ # | 1. Read version from README.md | # | 3. Set platform version (Joomla ) | # | 4. Update [VERSION: XX.YY.ZZ] badges in markdown files | -# | 5. Write update.xml (Joomla update server XML) | +# | 5. Write updates.xml (Joomla update server XML) | # | 6. Create git tag vXX.YY.ZZ | # | 7a. Patch: update existing GitHub Release for this minor | -# | 8. Build ZIP, upload asset, write SHA-256 to update.xml | +# | 8. Build ZIP, upload asset, write SHA-256 to updates.xml | # | | # | Every version change: archives main -> version/XX.YY branch | # | Patch 00 = development (no release). First release = patch 01. | @@ -259,8 +259,8 @@ jobs: fi done - # -- STEP 5: Write update.xml (Joomla update server) --------------------- - - name: "Step 5: Write update.xml" + # -- STEP 5: Write updates.xml (Joomla update server) --------------------- + - name: "Step 5: Write updates.xml" if: >- steps.version.outputs.skip != 'true' && steps.check.outputs.already_released != 'true' @@ -271,7 +271,7 @@ jobs: # -- Parse extension metadata from XML manifest ---------------- MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1) if [ -z "$MANIFEST" ]; then - echo "Warning: No Joomla XML manifest found β€” skipping update.xml" >> $GITHUB_STEP_SUMMARY + echo "Warning: No Joomla XML manifest found β€” skipping updates.xml" >> $GITHUB_STEP_SUMMARY exit 0 fi @@ -316,7 +316,7 @@ jobs: DOWNLOAD_URL="https://github.com/${REPO}/releases/download/v${VERSION}/${EXT_ELEMENT}-${VERSION}.zip" INFO_URL="https://github.com/${REPO}/releases/tag/v${VERSION}" - # -- Write update.xml (stable release) -------------------------- + # -- Write updates.xml (stable release) -------------------------- { printf '%s\n' '' printf '%s\n' '' @@ -341,9 +341,9 @@ jobs: printf '%s\n' ' https://mokoconsulting.tech' printf '%s\n' ' ' printf '%s\n' '' - } > update.xml + } > updates.xml - echo "update.xml: ${VERSION} (stable) β€” ${EXT_TYPE}/${EXT_ELEMENT}" >> $GITHUB_STEP_SUMMARY + echo "updates.xml: ${VERSION} (stable) β€” ${EXT_TYPE}/${EXT_ELEMENT}" >> $GITHUB_STEP_SUMMARY # -- Commit all changes --------------------------------------------------- - name: Commit release changes @@ -472,19 +472,19 @@ jobs: gh release upload "$RELEASE_TAG" "/tmp/${PACKAGE_NAME}" 2>/dev/null || true } - # -- Update update.xml with SHA-256 for latest patch ------------- - if [ -f "update.xml" ]; then - if grep -q '' update.xml; then - sed -i "s|.*|sha256:${SHA256}|" update.xml + # -- Update updates.xml with SHA-256 for latest patch ------------- + if [ -f "updates.xml" ]; then + if grep -q '' updates.xml; then + sed -i "s|.*|sha256:${SHA256}|" updates.xml else - sed -i "s||\n sha256:${SHA256}|" update.xml + sed -i "s||\n sha256:${SHA256}|" updates.xml fi # Also update the download URL to point to this patch's ZIP DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}" - sed -i "s|]*>[^<]*|${DOWNLOAD_URL}|" update.xml + sed -i "s|]*>[^<]*|${DOWNLOAD_URL}|" updates.xml - git add update.xml + git add updates.xml git commit -m "chore(release): SHA-256 + download URL for ${VERSION} [skip ci]" \ --author="github-actions[bot] " || true git push || true diff --git a/.github/workflows/ci-joomla.yml b/.github/workflows/ci-joomla.yml index d7995d2..190846e 100644 --- a/.github/workflows/ci-joomla.yml +++ b/.github/workflows/ci-joomla.yml @@ -312,11 +312,11 @@ jobs: fi fi - # Check update.xml exists - if [ -f "update.xml" ] || [ -f "updates.xml" ]; then + # Check updates.xml exists + if [ -f "updates.xml" ] || [ -f "updates.xml" ]; then echo "Update XML present." >> $GITHUB_STEP_SUMMARY else - echo "No update.xml found." >> $GITHUB_STEP_SUMMARY + echo "No updates.xml found." >> $GITHUB_STEP_SUMMARY ERRORS=$((ERRORS + 1)) fi diff --git a/.github/workflows/repo_health.yml b/.github/workflows/repo_health.yml index 0129292..885203a 100644 --- a/.github/workflows/repo_health.yml +++ b/.github/workflows/repo_health.yml @@ -595,9 +595,9 @@ jobs: joomla_findings+=("No .ini language files found") fi - # update.xml must exist in root (Joomla update server) - if [ ! -f 'update.xml' ]; then - joomla_findings+=("update.xml missing in root (required for Joomla update server)") + # updates.xml must exist in root (Joomla update server) + if [ ! -f 'updates.xml' ]; then + joomla_findings+=("updates.xml missing in root (required for Joomla update server)") fi # index.html files for directory listing protection diff --git a/.github/workflows/update-server.yml b/.github/workflows/update-server.yml index 91d9365..4d4fc97 100644 --- a/.github/workflows/update-server.yml +++ b/.github/workflows/update-server.yml @@ -10,7 +10,7 @@ # VERSION: 04.05.13 # BRIEF: Update Joomla update server XML feed with stable/rc/dev entries # -# Writes update.xml with multiple entries: +# Writes updates.xml with multiple entries: # - stable on push to main (from auto-release) # - rc on push to rc/** # - development on push to dev/** @@ -47,7 +47,7 @@ permissions: jobs: update-xml: - name: Update update.xml + name: Update updates.xml runs-on: ubuntu-latest steps: @@ -69,7 +69,7 @@ jobs: cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true fi - - name: Generate update.xml entry + - name: Generate updates.xml entry run: | BRANCH="${{ github.ref_name }}" REPO="${{ github.repository }}" @@ -149,20 +149,20 @@ jobs: XMLEOF ) - # ── Merge into update.xml ───────────────────────────────────── - if [ ! -f "update.xml" ]; then + # ── Merge into updates.xml ───────────────────────────────────── + if [ ! -f "updates.xml" ]; then # Create fresh - printf '%s\n' '' > update.xml - printf '%s\n' '' >> update.xml - echo "$NEW_ENTRY" >> update.xml - printf '%s\n' '' >> update.xml + printf '%s\n' '' > updates.xml + printf '%s\n' '' >> updates.xml + echo "$NEW_ENTRY" >> updates.xml + printf '%s\n' '' >> updates.xml else # Remove existing entry for this stability, add new one # Use python for reliable XML manipulation python3 -c " import re, sys -with open('update.xml', 'r') as f: +with open('updates.xml', 'r') as f: content = f.read() # Remove existing entry with this stability tag @@ -176,29 +176,29 @@ content = content.replace('', new_entry + '\n') # Clean up empty lines content = re.sub(r'\n{3,}', '\n\n', content) -with open('update.xml', 'w') as f: +with open('updates.xml', 'w') as f: f.write(content) " 2>/dev/null || { # Fallback: just rewrite the whole file if python fails # Keep existing stable entry if present STABLE_ENTRY="" - if [ "$STABILITY" != "stable" ] && grep -q 'stable' update.xml; then - STABLE_ENTRY=$(sed -n '//,/<\/update>/{ /stable<\/tag>/,/<\/update>/p; //,/stable<\/tag>/p }' update.xml | sort -u) + if [ "$STABILITY" != "stable" ] && grep -q 'stable' updates.xml; then + STABLE_ENTRY=$(sed -n '//,/<\/update>/{ /stable<\/tag>/,/<\/update>/p; //,/stable<\/tag>/p }' updates.xml | sort -u) fi RC_ENTRY="" - if [ "$STABILITY" != "rc" ] && grep -q 'rc' update.xml; then + if [ "$STABILITY" != "rc" ] && grep -q 'rc' updates.xml; then RC_ENTRY=$(python3 -c " import re -with open('update.xml') as f: c = f.read() +with open('updates.xml') as f: c = f.read() m = re.search(r'(.*?rc.*?)', c, re.DOTALL) if m: print(m.group(1)) " 2>/dev/null || true) fi DEV_ENTRY="" - if [ "$STABILITY" != "development" ] && grep -q 'development' update.xml; then + if [ "$STABILITY" != "development" ] && grep -q 'development' updates.xml; then DEV_ENTRY=$(python3 -c " import re -with open('update.xml') as f: c = f.read() +with open('updates.xml') as f: c = f.read() m = re.search(r'(.*?development.*?)', c, re.DOTALL) if m: print(m.group(1)) " 2>/dev/null || true) @@ -212,16 +212,16 @@ if m: print(m.group(1)) [ -n "$DEV_ENTRY" ] && echo "$DEV_ENTRY" echo "$NEW_ENTRY" printf '%s\n' '' - } > update.xml + } > updates.xml } fi # Commit git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" - git add update.xml + git add updates.xml git diff --cached --quiet || { - git commit -m "chore: update update.xml (${STABILITY}: ${DISPLAY_VERSION}) [skip ci]" \ + git commit -m "chore: update updates.xml (${STABILITY}: ${DISPLAY_VERSION}) [skip ci]" \ --author="github-actions[bot] " git push } From 99bbc06caa090f6eef4b6a13c5049f70de48e4de Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:14:39 -0500 Subject: [PATCH 04/47] Remove build-release.sh, minify.js, and scripts README from main Replaced by MokoStandards API. Only download-google-fonts remains (will be converted to PHP on next merge from dev). Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/README.md | 276 --------------------------------------- scripts/build-release.sh | 132 ------------------- scripts/minify.js | 188 -------------------------- 3 files changed, 596 deletions(-) delete mode 100644 scripts/README.md delete mode 100755 scripts/build-release.sh delete mode 100644 scripts/minify.js diff --git a/scripts/README.md b/scripts/README.md deleted file mode 100644 index 0c3f452..0000000 --- a/scripts/README.md +++ /dev/null @@ -1,276 +0,0 @@ -# Scripts β€” MokoCassiopeia - -This directory contains utility scripts for building, releasing, and managing the MokoCassiopeia Joomla template. - -## Available Scripts - -### build-release.sh - -**Purpose**: Build a release package for MokoCassiopeia template. - -**Usage**: -```bash -# Build with auto-detected version from templateDetails.xml -./scripts/build-release.sh - -# Build with specific version -./scripts/build-release.sh 03.08.03 -``` - -**What it does**: -1. Creates a `build/` directory -2. Copies template files from `src/` -3. Copies media files from `src/media/` to `media/` -4. Creates a ZIP package: `mokocassiopeia-src-{version}.zip` -5. Generates SHA-256 and MD5 checksums -6. Outputs package location and checksums - -**Output**: -- `build/mokocassiopeia-src-{version}.zip` - Installation package -- `build/mokocassiopeia-src-{version}.zip.sha256` - SHA-256 checksum -- `build/mokocassiopeia-src-{version}.zip.md5` - MD5 checksum - -**Requirements**: -- `rsync` for file copying -- `zip` for package creation -- `sha256sum` and `md5sum` for checksums - ---- - -## Automated Workflows - -The repository includes GitHub Actions workflows that automate the build and release process: - -### `.github/workflows/release.yml` - -**Purpose**: Automated release creation when tags are pushed. - -**Triggers**: -- Push of version tag (e.g., `03.08.03`) -- Manual workflow dispatch with version input - -**Process**: -1. Checks out repository -2. Sets up PHP environment -3. Installs dependencies (if composer.json exists) -4. Updates version numbers in manifest files -5. Creates package structure -6. Builds ZIP package -7. Generates checksums -8. Creates GitHub Release with artifacts - -**Usage**: -```bash -# Create and push a tag -git tag 03.08.04 -git push origin 03.08.04 - -# Or use GitHub UI to run manually -``` - ---- - -### `.github/workflows/auto-update-sha.yml` - -**Purpose**: Automatically update SHA-256 hash in `updates.xml` after a release is published. - -**Triggers**: -- GitHub Release published -- Manual workflow dispatch with tag input - -**Process**: -1. Downloads the release package -2. Calculates SHA-256 hash -3. Updates `updates.xml` with: - - New version number - - Current date - - Download URL - - SHA-256 hash -4. Commits and pushes changes to main branch - -**Benefits**: -- Ensures `updates.xml` always has correct SHA-256 hash -- Enables Joomla update server functionality -- Reduces manual update errors -- Automates security verification - ---- - -## Release Process - -### Manual Release (Local Build) - -1. **Update version numbers**: - ```bash - # Update these files manually: - # - src/templateDetails.xml - # - updates.xml - # - CHANGELOG.md - ``` - -2. **Build package**: - ```bash - ./scripts/build-release.sh 03.08.04 - ``` - -3. **Test package**: - - Install ZIP in Joomla test environment - - Verify all features work correctly - -4. **Create GitHub Release**: - - Go to GitHub Releases - - Click "Create a new release" - - Upload the ZIP, SHA256, and MD5 files - - Add release notes from CHANGELOG.md - -5. **Update updates.xml**: - - Copy SHA-256 hash from `.sha256` file - - Update `updates.xml` with new hash - - Commit and push changes - ---- - -### Automated Release (GitHub Actions) - -1. **Update version numbers**: - ```bash - # Update these files in a branch: - # - src/templateDetails.xml - # - CHANGELOG.md - - git checkout -b release/03.08.04 - # Make changes - git commit -m "chore: Prepare release 03.08.04" - git push origin release/03.08.04 - ``` - -2. **Create and merge PR**: - - Create PR from release branch - - Review changes - - Merge to main - -3. **Create and push tag**: - ```bash - git checkout main - git pull - git tag 03.08.04 - git push origin 03.08.04 - ``` - -4. **Automated process**: - - GitHub Actions builds package automatically - - Creates GitHub Release with artifacts - - `auto-update-sha` workflow updates `updates.xml` - -5. **Verify**: - - Check GitHub Release is created - - Verify `updates.xml` has correct SHA-256 - - Test Joomla update server - ---- - -## Development Workflow - -### Testing Local Builds - -```bash -# Build current version -./scripts/build-release.sh - -# Install in Joomla -# Navigate to Extensions > Manage > Install > Upload Package File -# Select: build/mokocassiopeia-src-{version}.zip -``` - -### Pre-Release Checklist - -- [ ] All code changes merged to main -- [ ] Version numbers updated: - - [ ] `src/templateDetails.xml` - - [ ] `CHANGELOG.md` -- [ ] CHANGELOG.md updated with release notes -- [ ] Tests passing -- [ ] Documentation updated -- [ ] Local build tested in Joomla - ---- - -## Troubleshooting - -### Build Fails - -**Problem**: `rsync: command not found` -```bash -# Ubuntu/Debian -sudo apt-get install rsync - -# macOS -brew install rsync -``` - -**Problem**: `zip: command not found` -```bash -# Ubuntu/Debian -sudo apt-get install zip - -# macOS (usually pre-installed) -brew install zip -``` - -### GitHub Actions Fails - -**Problem**: Release workflow fails on tag push - -Check: -1. Tag format matches pattern: `[0-9][0-9].[0-9][0-9].[0-9][0-9]` -2. Repository has write permissions for GITHUB_TOKEN -3. `src/` and `src/media/` directories exist - -**Problem**: auto-update-sha fails - -Check: -1. Release package was published successfully -2. Workflow has write permissions -3. Package naming matches expected format - ---- - -## File Structure - -``` -scripts/ -β”œβ”€β”€ README.md # This file -└── build-release.sh # Local build script - -.github/workflows/ -β”œβ”€β”€ release.yml # Automated release workflow -└── auto-update-sha.yml # SHA hash update workflow -``` - ---- - -## Contributing - -When adding new scripts: - -1. Add GPL-3.0-or-later license header -2. Include FILE INFORMATION block -3. Add usage documentation in this README -4. Make scripts executable: `chmod +x scripts/your-script.sh` -5. Test thoroughly before committing - ---- - -## Support - -- **Issues**: [GitHub Issues](https://github.com/mokoconsulting-tech/MokoCassiopeia/issues) -- **Email**: hello@mokoconsulting.tech -- **Documentation**: [docs/](../docs/) - ---- - -## License - -All scripts are licensed under GPL-3.0-or-later. - -Copyright (C) 2026 Moko Consulting diff --git a/scripts/build-release.sh b/scripts/build-release.sh deleted file mode 100755 index 5e8055d..0000000 --- a/scripts/build-release.sh +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2026 Moko Consulting -# SPDX-License-Identifier: GPL-3.0-or-later -# -# FILE INFORMATION -# DEFGROUP: Build.Scripts -# INGROUP: MokoCassiopeia.Build -# REPO: https://github.com/mokoconsulting-tech/MokoCassiopeia -# PATH: /scripts/build-release.sh -# VERSION: 01.00.00 -# BRIEF: Build release package for MokoCassiopeia template -# USAGE: ./scripts/build-release.sh [version] - -set -e - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Script directory -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" - -# Functions -log_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -log_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -log_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# Check if version is provided -if [ -z "$1" ]; then - # Try to extract version from templateDetails.xml - if [ -f "${PROJECT_ROOT}/src/templateDetails.xml" ]; then - VERSION=$(grep -oP '\K[^<]+' "${PROJECT_ROOT}/src/templateDetails.xml" | head -1) - log_info "Detected version: ${VERSION}" - else - log_error "Please provide version as argument: ./build-release.sh 03.08.03" - exit 1 - fi -else - VERSION="$1" -fi - -log_info "Building MokoCassiopeia release package" -log_info "Version: ${VERSION}" - -# Change to project root -cd "${PROJECT_ROOT}" - -# Create build directory -BUILD_DIR="${PROJECT_ROOT}/build" -PACKAGE_DIR="${BUILD_DIR}/package" -rm -rf "${BUILD_DIR}" -mkdir -p "${PACKAGE_DIR}" - -log_info "Creating package structure..." - -# Copy template files from src (excluding media directory) -if [ -d "src" ]; then - rsync -av --exclude='.git*' --exclude='media' src/ "${PACKAGE_DIR}/" -else - log_error "src directory not found!" - exit 1 -fi - -# Copy media files from src/media -if [ -d "src/media" ]; then - mkdir -p "${PACKAGE_DIR}/media" - rsync -av --exclude='.git*' src/media/ "${PACKAGE_DIR}/media/" -else - log_warning "src/media directory not found, skipping media files" -fi - -log_info "Package structure created" - -# Create ZIP package -cd "${PACKAGE_DIR}" -ZIP_NAME="mokocassiopeia-src-${VERSION}.zip" -log_info "Creating ZIP package: ${ZIP_NAME}" - -zip -r "../${ZIP_NAME}" . -q - -if [ $? -ne 0 ]; then - log_error "Failed to create ZIP package" - exit 1 -fi - -cd "${BUILD_DIR}" -log_success "Created: ${ZIP_NAME}" - -# Generate checksums -log_info "Generating checksums..." -sha256sum "${ZIP_NAME}" > "${ZIP_NAME}.sha256" -md5sum "${ZIP_NAME}" > "${ZIP_NAME}.md5" - -# Extract just the hash -SHA256_HASH=$(sha256sum "${ZIP_NAME}" | cut -d' ' -f1) - -log_success "SHA-256: ${SHA256_HASH}" -log_success "MD5: $(md5sum "${ZIP_NAME}" | cut -d' ' -f1)" - -# Show file info -FILE_SIZE=$(du -h "${ZIP_NAME}" | cut -f1) -log_info "Package size: ${FILE_SIZE}" - -# Summary -echo "" -log_success "Build completed successfully!" -echo "" -echo "Package: ${BUILD_DIR}/${ZIP_NAME}" -echo "SHA-256: ${BUILD_DIR}/${ZIP_NAME}.sha256" -echo "MD5: ${BUILD_DIR}/${ZIP_NAME}.md5" -echo "" -echo "Next steps:" -echo "1. Test the package installation in Joomla" -echo "2. Create a GitHub release with this package" -echo "3. Update updates.xml with the new version and SHA-256 hash" -echo "" diff --git a/scripts/minify.js b/scripts/minify.js deleted file mode 100644 index b6116e8..0000000 --- a/scripts/minify.js +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env node -/* Copyright (C) 2026 Moko Consulting - * - * This file is part of a Moko Consulting project. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - * # FILE INFORMATION - * DEFGROUP: Joomla.Template.Site - * INGROUP: MokoCassiopeia - * REPO: https://github.com/mokoconsulting-tech/MokoCassiopeia - * PATH: ./scripts/minify.js - * VERSION: 03.09.03 - * BRIEF: Generates .min.css and .min.js files from the Joomla asset manifest - */ - -'use strict'; - -const fs = require('fs'); -const path = require('path'); - -const CleanCSS = require('clean-css'); -const { minify: terserMinify } = require('terser'); - -// --------------------------------------------------------------------------- -// Config -// --------------------------------------------------------------------------- - -const ROOT = path.resolve(__dirname, '..'); -const SRC_MEDIA = path.join(ROOT, 'src', 'media'); -const ASSET_JSON = path.join(ROOT, 'src', 'joomla.asset.json'); - -// URI prefix used in the manifest β€” maps to SRC_MEDIA on disk. -// e.g. "media/templates/site/mokocassiopeia/css/template.css" -const URI_PREFIX = 'media/templates/site/mokocassiopeia/'; - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -/** - * Resolve a manifest URI to an absolute disk path under src/media/. - * - * @param {string} uri e.g. "media/templates/site/mokocassiopeia/css/foo.css" - * @returns {string|null} - */ -function uriToPath(uri) { - if (!uri.startsWith(URI_PREFIX)) return null; - return path.join(SRC_MEDIA, uri.slice(URI_PREFIX.length)); -} - -/** - * Return true if the filename looks like an already-minified file or belongs - * to a vendor bundle we don't own. - */ -function isVendorOrUserFile(filePath) { - const rel = filePath.replace(SRC_MEDIA + path.sep, ''); - return rel.startsWith('vendor' + path.sep) - || path.basename(filePath).startsWith('user.'); -} - -// --------------------------------------------------------------------------- -// Pair detection -// --------------------------------------------------------------------------- - -/** - * Read the asset manifest and return an array of { src, dest, type } pairs - * where dest is a minified version of src that doesn't already exist or is - * older than src. - * - * Pairing logic: for every non-.min asset, check whether the manifest also - * contains a corresponding .min asset. If so, that's our pair. - */ -function detectPairs(assets) { - // Build a lookup of all URIs in the manifest. - const uriSet = new Set(assets.map(a => a.uri)); - - const pairs = []; - - for (const asset of assets) { - const { uri, type } = asset; - if (type !== 'style' && type !== 'script') continue; - - // Skip already-minified entries. - if (/\.min\.(css|js)$/.test(uri)) continue; - - // Derive the expected .min URI. - const minUri = uri.replace(/\.(css|js)$/, '.min.$1'); - if (!uriSet.has(minUri)) continue; - - const srcPath = uriToPath(uri); - const destPath = uriToPath(minUri); - if (!srcPath || !destPath) continue; - - if (isVendorOrUserFile(srcPath)) continue; - - if (!fs.existsSync(srcPath)) { - console.warn(` [skip] source missing: ${srcPath}`); - continue; - } - - pairs.push({ src: srcPath, dest: destPath, type }); - } - - return pairs; -} - -// --------------------------------------------------------------------------- -// Minifiers -// --------------------------------------------------------------------------- - -async function minifyCSS(srcPath, destPath) { - const source = fs.readFileSync(srcPath, 'utf8'); - const result = new CleanCSS({ level: 2, returnPromise: true }); - const output = await result.minify(source); - - if (output.errors && output.errors.length) { - throw new Error(output.errors.join('\n')); - } - - fs.mkdirSync(path.dirname(destPath), { recursive: true }); - fs.writeFileSync(destPath, output.styles, 'utf8'); - - const srcSize = Buffer.byteLength(source, 'utf8'); - const destSize = Buffer.byteLength(output.styles, 'utf8'); - const saving = (100 - (destSize / srcSize * 100)).toFixed(1); - - return { srcSize, destSize, saving }; -} - -async function minifyJS(srcPath, destPath) { - const source = fs.readFileSync(srcPath, 'utf8'); - const result = await terserMinify(source, { - compress: { drop_console: false }, - mangle: true, - format: { comments: false } - }); - - if (!result.code) throw new Error('terser returned no output'); - - fs.mkdirSync(path.dirname(destPath), { recursive: true }); - fs.writeFileSync(destPath, result.code, 'utf8'); - - const srcSize = Buffer.byteLength(source, 'utf8'); - const destSize = Buffer.byteLength(result.code, 'utf8'); - const saving = (100 - (destSize / srcSize * 100)).toFixed(1); - - return { srcSize, destSize, saving }; -} - -// --------------------------------------------------------------------------- -// Main -// --------------------------------------------------------------------------- - -(async () => { - const manifest = JSON.parse(fs.readFileSync(ASSET_JSON, 'utf8')); - const pairs = detectPairs(manifest.assets); - - if (pairs.length === 0) { - console.log('No pairs found β€” nothing to minify.'); - return; - } - - console.log(`\nMinifying ${pairs.length} file(s)...\n`); - - let ok = 0, fail = 0; - - for (const { src, dest, type } of pairs) { - const label = path.relative(ROOT, src); - process.stdout.write(` ${label} ... `); - - try { - const stats = type === 'style' - ? await minifyCSS(src, dest) - : await minifyJS(src, dest); - - const kb = n => (n / 1024).toFixed(1) + ' kB'; - console.log(`${kb(stats.srcSize)} β†’ ${kb(stats.destSize)} (${stats.saving}% saved)`); - ok++; - } catch (err) { - console.error(`FAILED\n ${err.message}`); - fail++; - } - } - - console.log(`\nDone. ${ok} succeeded, ${fail} failed.\n`); - if (fail > 0) process.exit(1); -})(); From 1fe22fd22e0685c439abb99250c2c5f1439805fe Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:18:10 -0500 Subject: [PATCH 05/47] ci: sync all workflows from MokoStandards [skip ci] Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/update-server.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update-server.yml b/.github/workflows/update-server.yml index 4d4fc97..cc34448 100644 --- a/.github/workflows/update-server.yml +++ b/.github/workflows/update-server.yml @@ -121,9 +121,32 @@ jobs: MAJOR=$(echo "$VERSION" | awk -F. '{print $1}') RELEASE_TAG="v${MAJOR}" - DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${EXT_ELEMENT}-${VERSION}.zip" + PACKAGE_NAME="${EXT_ELEMENT}-${DISPLAY_VERSION}.zip" + DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}" INFO_URL="https://github.com/${REPO}" + # ── Build install-ready ZIP ───────────────────────────────── + SOURCE_DIR="src" + [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs" + if [ -d "$SOURCE_DIR" ]; then + cd "$SOURCE_DIR" + zip -r "/tmp/${PACKAGE_NAME}" . + cd .. + + SHA256=$(sha256sum "/tmp/${PACKAGE_NAME}" | cut -d' ' -f1) + + # Ensure draft release exists for this major + gh release view "$RELEASE_TAG" --json tagName > /dev/null 2>&1 || \ + gh release create "$RELEASE_TAG" --title "v${MAJOR}" --notes "Development release" --draft --target main 2>/dev/null || true + + # Upload ZIP to the major release + gh release upload "$RELEASE_TAG" "/tmp/${PACKAGE_NAME}" --clobber 2>/dev/null || true + + echo "Package: ${PACKAGE_NAME} (SHA: ${SHA256})" >> $GITHUB_STEP_SUMMARY + else + SHA256="" + fi + # ── Build the new entry ─────────────────────────────────────── NEW_ENTRY=$(cat < @@ -141,6 +164,7 @@ jobs: ${DOWNLOAD_URL} + $([ -n "$SHA256" ] && echo " sha256:${SHA256}") ${TARGET_PLATFORM} $([ -n "$PHP_TAG" ] && echo " ${PHP_TAG}") Moko Consulting From f5217f48d8d74db49ed0a01e7b514d97ba53f641 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:37:08 -0500 Subject: [PATCH 06/47] Fix updates.xml: correct URLs and SHA for all channels Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/updates.xml b/updates.xml index 723cc4a..b25c606 100644 --- a/updates.xml +++ b/updates.xml @@ -10,11 +10,15 @@ INGROUP: MokoCassiopeia REPO: https://github.com/mokoconsulting-tech/MokoCassiopeia PATH: ./updates.xml - VERSION: 03.09.04 - BRIEF: Update manifest XML file for MokoCassiopeia + VERSION: 03.09.05 + BRIEF: Update manifest XML β€” stable, rc, and development channels --> + + MokoCassiopeia Moko Consulting's site template based on Cassiopeia. @@ -44,4 +48,71 @@ + + + + MokoCassiopeia + MokoCassiopeia release candidate β€” testing only. + mokocassiopeia + template + site + + 03.09.05 + 2026-04-07 + Jonathan Miller || Moko Consulting + hello@mokoconsulting.tech + (C)GNU General Public License Version 3 - 2026 Moko Consulting + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03.09.04-rc + + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03.09.04-rc/mokocassiopeia-03.09.05-rc.zip + + fa0cd74ba37ede0dbb98256feca9a1f6f70b917b8487b778118de3d18b32074b + + + rc + + + Moko Consulting + https://mokoconsulting.tech + + + + + + + MokoCassiopeia + MokoCassiopeia development build β€” unstable. + mokocassiopeia + template + site + + 03.09.05 + 2026-04-07 + Jonathan Miller || Moko Consulting + hello@mokoconsulting.tech + (C)GNU General Public License Version 3 - 2026 Moko Consulting + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03.09.04-dev + + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03.09.04-dev/mokocassiopeia-dev.zip + + e585c4b039f6c88ea7a566b92189ed2d1ab731cd7110727659d6cb08b729585d + + + development + + + Moko Consulting + https://mokoconsulting.tech + + + + From 4884d8ecc7f27ef83dfbe6a2ff5c7b262e4af475 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:38:02 -0500 Subject: [PATCH 07/47] ci: version/04 branch refs, final workflow sync [skip ci] Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/auto-release.yml | 4 ++-- .github/workflows/ci-joomla.yml | 2 +- .github/workflows/standards-compliance.yml | 6 +++--- .github/workflows/sync-version-on-merge.yml | 2 +- .github/workflows/update-server.yml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 5acbe07..f064ceb 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -69,7 +69,7 @@ jobs: GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }} COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}' run: | - git clone --depth 1 --branch version/04.05 --quiet \ + git clone --depth 1 --branch version/04 --quiet \ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \ /tmp/mokostandards cd /tmp/mokostandards @@ -93,7 +93,7 @@ jobs: MINOR_NUM=$(echo "$VERSION" | awk -F. '{print $2}') echo "version=$VERSION" >> "$GITHUB_OUTPUT" - echo "branch=version/${MINOR}" >> "$GITHUB_OUTPUT" + echo "branch=version/${MAJOR}" >> "$GITHUB_OUTPUT" echo "minor=$MINOR" >> "$GITHUB_OUTPUT" echo "major=$MAJOR" >> "$GITHUB_OUTPUT" echo "release_tag=v${MAJOR}" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/ci-joomla.yml b/.github/workflows/ci-joomla.yml index 190846e..6281236 100644 --- a/.github/workflows/ci-joomla.yml +++ b/.github/workflows/ci-joomla.yml @@ -57,7 +57,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }} run: | - git clone --depth 1 --branch version/04.05 --quiet \ + git clone --depth 1 --branch version/04 --quiet \ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \ /tmp/mokostandards diff --git a/.github/workflows/standards-compliance.yml b/.github/workflows/standards-compliance.yml index df8413c..773279d 100644 --- a/.github/workflows/standards-compliance.yml +++ b/.github/workflows/standards-compliance.yml @@ -509,7 +509,7 @@ jobs: GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }} COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}' run: | - git clone --depth 1 --branch version/04.05 --quiet \ + git clone --depth 1 --branch version/04 --quiet \ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \ /tmp/mokostandards 2>/dev/null || true if [ -d "/tmp/mokostandards" ] && [ -f "/tmp/mokostandards/composer.json" ]; then @@ -1978,7 +1978,7 @@ jobs: else echo "No composer.json β€” pulling MokoStandards tools" if [ ! -d "/tmp/mokostandards" ]; then - git clone --depth 1 --branch version/04.05 --quiet \ + git clone --depth 1 --branch version/04 --quiet \ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \ /tmp/mokostandards 2>/dev/null || true if [ -f "/tmp/mokostandards/composer.json" ]; then @@ -2050,7 +2050,7 @@ jobs: else echo "No composer.json β€” pulling MokoStandards tools" if [ ! -d "/tmp/mokostandards" ]; then - git clone --depth 1 --branch version/04.05 --quiet \ + git clone --depth 1 --branch version/04 --quiet \ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \ /tmp/mokostandards 2>/dev/null || true if [ -f "/tmp/mokostandards/composer.json" ]; then diff --git a/.github/workflows/sync-version-on-merge.yml b/.github/workflows/sync-version-on-merge.yml index 7b2ef6c..052a7ca 100644 --- a/.github/workflows/sync-version-on-merge.yml +++ b/.github/workflows/sync-version-on-merge.yml @@ -58,7 +58,7 @@ jobs: GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }} COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}' run: | - git clone --depth 1 --branch version/04.05 --quiet \ + git clone --depth 1 --branch version/04 --quiet \ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \ /tmp/mokostandards cd /tmp/mokostandards diff --git a/.github/workflows/update-server.yml b/.github/workflows/update-server.yml index cc34448..fad30ff 100644 --- a/.github/workflows/update-server.yml +++ b/.github/workflows/update-server.yml @@ -62,7 +62,7 @@ jobs: GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }} COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}' run: | - git clone --depth 1 --branch version/04.05 --quiet \ + git clone --depth 1 --branch version/04 --quiet \ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \ /tmp/mokostandards 2>/dev/null || true if [ -d "/tmp/mokostandards" ] && [ -f "/tmp/mokostandards/composer.json" ]; then From db2e54daf8ba6f10dced0b9fb75511ffd84783c4 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:53:35 -0500 Subject: [PATCH 08/47] Point updates.xml to development and release-candidate tags Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/updates.xml b/updates.xml index b25c606..39ab1ee 100644 --- a/updates.xml +++ b/updates.xml @@ -59,18 +59,18 @@ template site - 03.09.05 + 03.09.06 2026-04-07 Jonathan Miller || Moko Consulting hello@mokoconsulting.tech (C)GNU General Public License Version 3 - 2026 Moko Consulting - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03.09.04-rc + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/release-candidate - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03.09.04-rc/mokocassiopeia-03.09.05-rc.zip + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/release-candidate/mokocassiopeia-rc.zip - fa0cd74ba37ede0dbb98256feca9a1f6f70b917b8487b778118de3d18b32074b + 7f75cb1d2a1a9477fbbb0d742569afb1009d79755f23876e4e20cc89d7770720 rc @@ -92,18 +92,18 @@ template site - 03.09.05 + 03.09.06 2026-04-07 Jonathan Miller || Moko Consulting hello@mokoconsulting.tech (C)GNU General Public License Version 3 - 2026 Moko Consulting - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03.09.04-dev + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/development - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03.09.04-dev/mokocassiopeia-dev.zip + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/development/mokocassiopeia-dev.zip - e585c4b039f6c88ea7a566b92189ed2d1ab731cd7110727659d6cb08b729585d + 7f75cb1d2a1a9477fbbb0d742569afb1009d79755f23876e4e20cc89d7770720 development From 2ea06f330d230597a0fa3dc337119b4e6fd464c5 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:55:13 -0500 Subject: [PATCH 09/47] ci: separate release tags (development/release-candidate/vXX) [skip ci] Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/auto-dev-issue.yml | 26 ++++------- .github/workflows/auto-release.yml | 70 +++++++++++++++++++--------- .github/workflows/update-server.yml | 13 +++++- 3 files changed, 68 insertions(+), 41 deletions(-) diff --git a/.github/workflows/auto-dev-issue.yml b/.github/workflows/auto-dev-issue.yml index 38730ab..38c6a53 100644 --- a/.github/workflows/auto-dev-issue.yml +++ b/.github/workflows/auto-dev-issue.yml @@ -156,30 +156,22 @@ jobs: done fi - # ── RC: Create or update draft release ──────────────────────────── + # ── RC: Create or update release-candidate release ────────────── if [[ "$BRANCH" == rc/* ]]; then - MAJOR=$(echo "$VERSION" | awk -F. '{print $1}') - RELEASE_TAG="v${MAJOR}" - DRAFT_EXISTS=$(gh release view "$RELEASE_TAG" --json isDraft -q .isDraft 2>/dev/null || true) + RELEASE_TAG="release-candidate" + EXISTING=$(gh release view "$RELEASE_TAG" --json tagName -q .tagName 2>/dev/null || true) - if [ -z "$DRAFT_EXISTS" ]; then - # No release exists β€” create draft + if [ -z "$EXISTING" ]; then gh release create "$RELEASE_TAG" \ - --title "v${MAJOR} (RC: ${VERSION})" \ + --title "release-candidate (${VERSION})" \ --notes "## Release Candidate ${VERSION}\n\nRC branch: \`${BRANCH}\`\nTracking issue: ${PARENT_URL}" \ - --draft \ + --prerelease \ --target main 2>/dev/null || true - echo "Draft release created: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY - elif [ "$DRAFT_EXISTS" = "true" ]; then - # Draft exists β€” update title - gh release edit "$RELEASE_TAG" \ - --title "v${MAJOR} (RC: ${VERSION})" --draft 2>/dev/null || true - echo "Draft release updated: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY + echo "RC release created: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY else - # Release exists and is published β€” set back to draft for RC gh release edit "$RELEASE_TAG" \ - --title "v${MAJOR} (RC: ${VERSION})" --draft 2>/dev/null || true - echo "Release ${RELEASE_TAG} set to draft for RC" >> $GITHUB_STEP_SUMMARY + --title "release-candidate (${VERSION})" --prerelease 2>/dev/null || true + echo "RC release updated: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY fi fi diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index f064ceb..3e1caf3 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -316,34 +316,60 @@ jobs: DOWNLOAD_URL="https://github.com/${REPO}/releases/download/v${VERSION}/${EXT_ELEMENT}-${VERSION}.zip" INFO_URL="https://github.com/${REPO}/releases/tag/v${VERSION}" - # -- Write updates.xml (stable release) -------------------------- + # -- Build stable entry ────────────────────────────────────── + STABLE_ENTRY=$(cat < + ${EXT_NAME} + ${EXT_NAME} update + ${EXT_ELEMENT} + ${EXT_TYPE} + ${VERSION} + $([ -n "$CLIENT_TAG" ] && echo " ${CLIENT_TAG}") + $([ -n "$FOLDER_TAG" ] && echo " ${FOLDER_TAG}") + + stable + + ${INFO_URL} + + ${DOWNLOAD_URL} + + ${TARGET_PLATFORM} + $([ -n "$PHP_TAG" ] && echo " ${PHP_TAG}") + Moko Consulting + https://mokoconsulting.tech + +XMLEOF +) + + # -- Write updates.xml preserving dev/rc entries ────────────── + # Extract existing dev and rc entries if present + RC_ENTRY="" + DEV_ENTRY="" + if [ -f "updates.xml" ]; then + RC_ENTRY=$(python3 -c " +import re +with open('updates.xml') as f: c = f.read() +m = re.search(r'( .*?rc.*?)', c, re.DOTALL) +if m: print(m.group(1)) +" 2>/dev/null || true) + DEV_ENTRY=$(python3 -c " +import re +with open('updates.xml') as f: c = f.read() +m = re.search(r'( .*?development.*?)', c, re.DOTALL) +if m: print(m.group(1)) +" 2>/dev/null || true) + fi + { printf '%s\n' '' printf '%s\n' '' - printf '%s\n' ' ' - printf '%s\n' " ${EXT_NAME}" - printf '%s\n' " ${EXT_NAME} update" - printf '%s\n' " ${EXT_ELEMENT}" - printf '%s\n' " ${EXT_TYPE}" - printf '%s\n' " ${VERSION}" - [ -n "$CLIENT_TAG" ] && printf '%s\n' " ${CLIENT_TAG}" - [ -n "$FOLDER_TAG" ] && printf '%s\n' " ${FOLDER_TAG}" - printf '%s\n' ' ' - printf '%s\n' ' stable' - printf '%s\n' ' ' - printf '%s\n' " ${INFO_URL}" - printf '%s\n' ' ' - printf '%s\n' " ${DOWNLOAD_URL}" - printf '%s\n' ' ' - printf '%s\n' " ${TARGET_PLATFORM}" - [ -n "$PHP_TAG" ] && printf '%s\n' " ${PHP_TAG}" - printf '%s\n' ' Moko Consulting' - printf '%s\n' ' https://mokoconsulting.tech' - printf '%s\n' ' ' + echo "$STABLE_ENTRY" + [ -n "$RC_ENTRY" ] && echo "$RC_ENTRY" + [ -n "$DEV_ENTRY" ] && echo "$DEV_ENTRY" printf '%s\n' '' } > updates.xml - echo "updates.xml: ${VERSION} (stable) β€” ${EXT_TYPE}/${EXT_ELEMENT}" >> $GITHUB_STEP_SUMMARY + echo "updates.xml: ${VERSION} (stable + rc/dev preserved)" >> $GITHUB_STEP_SUMMARY # -- Commit all changes --------------------------------------------------- - name: Commit release changes diff --git a/.github/workflows/update-server.yml b/.github/workflows/update-server.yml index fad30ff..28a6dd7 100644 --- a/.github/workflows/update-server.yml +++ b/.github/workflows/update-server.yml @@ -120,7 +120,16 @@ jobs: [ "$STABILITY" = "development" ] && DISPLAY_VERSION="${VERSION}-dev" MAJOR=$(echo "$VERSION" | awk -F. '{print $1}') - RELEASE_TAG="v${MAJOR}" + + # Each stability level has its own release tag + if [ "$STABILITY" = "rc" ]; then + RELEASE_TAG="release-candidate" + elif [ "$STABILITY" = "development" ]; then + RELEASE_TAG="development" + else + RELEASE_TAG="v${MAJOR}" + fi + PACKAGE_NAME="${EXT_ELEMENT}-${DISPLAY_VERSION}.zip" DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}" INFO_URL="https://github.com/${REPO}" @@ -137,7 +146,7 @@ jobs: # Ensure draft release exists for this major gh release view "$RELEASE_TAG" --json tagName > /dev/null 2>&1 || \ - gh release create "$RELEASE_TAG" --title "v${MAJOR}" --notes "Development release" --draft --target main 2>/dev/null || true + gh release create "$RELEASE_TAG" --title "${RELEASE_TAG} (${DISPLAY_VERSION})" --notes "${STABILITY} release" --prerelease --target main 2>/dev/null || true # Upload ZIP to the major release gh release upload "$RELEASE_TAG" "/tmp/${PACKAGE_NAME}" --clobber 2>/dev/null || true From 582913c74bb4678e1f5edba155350bd0ee95262a Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:00:23 -0500 Subject: [PATCH 10/47] Update updates.xml: dev 03.09.07 + rc SHA fix Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/updates.xml b/updates.xml index 39ab1ee..5221b78 100644 --- a/updates.xml +++ b/updates.xml @@ -70,7 +70,7 @@ https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/release-candidate/mokocassiopeia-rc.zip - 7f75cb1d2a1a9477fbbb0d742569afb1009d79755f23876e4e20cc89d7770720 + 99b868a54466138d22a544d3e489559e7303960922c8eb3a142c504225b0e647 rc @@ -92,18 +92,19 @@ template site - 03.09.06 + 03.09.07 2026-04-07 Jonathan Miller || Moko Consulting hello@mokoconsulting.tech (C)GNU General Public License Version 3 - 2026 Moko Consulting - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/development + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/development + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/development/mokocassiopeia-dev.zip - 7f75cb1d2a1a9477fbbb0d742569afb1009d79755f23876e4e20cc89d7770720 + b6403918c5f65f4f52b889fbe4bd217c903f0d9c2fcf90f8eb59df1e7b4b7333 development From 71f60c4ec23ea524a25065c5ea96d9855951be88 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:06:33 -0500 Subject: [PATCH 11/47] =?UTF-8?q?Fix=20broken=20XML=20in=20updates.xml=20?= =?UTF-8?q?=E2=80=94=20corrupted=20infourl=20closing=20tag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/updates.xml b/updates.xml index 5221b78..dc45886 100644 --- a/updates.xml +++ b/updates.xml @@ -98,8 +98,7 @@ hello@mokoconsulting.tech (C)GNU General Public License Version 3 - 2026 Moko Consulting - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/development - + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/development https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/development/mokocassiopeia-dev.zip From ca84bb0b999f6a8ed1aeff5c2b18ffc4adb07599 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:10:44 -0500 Subject: [PATCH 12/47] Add alpha and beta channels to updates.xml Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/updates.xml b/updates.xml index dc45886..20100ca 100644 --- a/updates.xml +++ b/updates.xml @@ -115,4 +115,70 @@ + + + MokoCassiopeia + MokoCassiopeia alpha build β€” early testing. + mokocassiopeia + template + site + + 03.09.07 + 2026-04-07 + Jonathan Miller || Moko Consulting + hello@mokoconsulting.tech + (C)GNU General Public License Version 3 - 2026 Moko Consulting + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/alpha + + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/alpha/mokocassiopeia-alpha.zip + + b5f6d073d126f0041ddd475e61bc4eaa050e060e9b51f4fe0e8a348f188c40b2 + + + alpha + + + Moko Consulting + https://mokoconsulting.tech + + + + + + + MokoCassiopeia + MokoCassiopeia beta build β€” feature complete, stability testing. + mokocassiopeia + template + site + + 03.09.07 + 2026-04-07 + Jonathan Miller || Moko Consulting + hello@mokoconsulting.tech + (C)GNU General Public License Version 3 - 2026 Moko Consulting + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/beta + + + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/beta/mokocassiopeia-beta.zip + + b5f6d073d126f0041ddd475e61bc4eaa050e060e9b51f4fe0e8a348f188c40b2 + + + beta + + + Moko Consulting + https://mokoconsulting.tech + + + + From 31304c8dd0e3f9aad43d8dff0775a891d678d446 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:22:34 -0500 Subject: [PATCH 13/47] chore(release): update stable channel to 03.09.07 Co-Authored-By: Claude Opus 4.6 (1M context) --- updates.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/updates.xml b/updates.xml index 20100ca..496bec1 100644 --- a/updates.xml +++ b/updates.xml @@ -26,7 +26,7 @@ template site - 03.09.04 + 03.09.07 2026-04-07 Jonathan Miller || Moko Consulting hello@mokoconsulting.tech @@ -35,9 +35,9 @@ https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03 - https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.09.04.zip + https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/download/v03/mokocassiopeia-03.09.07.zip - da85bf5a34cafadbae26df199ed36c04438e7dab440d046e0e4117d25510feaf + 16a7ac98dd6e26144618a4ba534ea8fae0d115ec8373712743ab6daff0960916 stable From 5ca9a27393c12e828861329914432029dbedc654 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:34:25 -0500 Subject: [PATCH 14/47] Change Joomla badge to red Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e26e701..ccaf755 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ [![Version](https://img.shields.io/badge/version-03.09.04-green.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) -[![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-blue.svg)](https://www.joomla.org) +[![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-blue.svg)](https://www.php.net) MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla's Cassiopeia template. It adds **Font Awesome 7**, **Bootstrap 5** helpers, an automatic **Table of Contents (TOC)** utility, advanced **Dark Mode** theming, and optional integrations for **Google Tag Manager** and **Google Analytics (GA4)**β€”all while maintaining minimal core template overrides for maximum upgrade compatibility. From 422ab4c06730cd78e0cc74ee54b7e841ad713357 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:35:05 -0500 Subject: [PATCH 15/47] Update badges to match MokoWaaS style Version badge blue with 03.09.07, license badge green with GPL-3.0-or-later, Joomla red, PHP blue. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccaf755..dc83563 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/version-03.09.04-green.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) -[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) +[![Version](https://img.shields.io/badge/version-03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-blue.svg)](https://www.php.net) From 3aebcafda7d853d024ab2e6ba23951e385fd2061 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:36:11 -0500 Subject: [PATCH 16/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc83563..4efe6d1 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ BRIEF: Documentation for MokoCassiopeia template --> -# MokoCassiopeia +# MokoCassiopeia Template **A Modern, Lightweight Joomla Template Based on Cassiopeia** From 5389d095ec8582cb595bb989aabb6f15a93c20c8 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:41:53 -0500 Subject: [PATCH 17/47] Distinct badge colors: version blue, license green, Joomla red, PHP purple Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4efe6d1..7b7bbe7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ [![Version](https://img.shields.io/badge/version-03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg)](https://www.joomla.org) -[![PHP](https://img.shields.io/badge/PHP-8.1%2B-blue.svg)](https://www.php.net) +[![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg)](https://www.php.net) MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla's Cassiopeia template. It adds **Font Awesome 7**, **Bootstrap 5** helpers, an automatic **Table of Contents (TOC)** utility, advanced **Dark Mode** theming, and optional integrations for **Google Tag Manager** and **Google Analytics (GA4)**β€”all while maintaining minimal core template overrides for maximum upgrade compatibility. From 150afd5a28739abcd8d406ebed8a9d020eb1e68e Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:46:22 -0500 Subject: [PATCH 18/47] Add Simple Icons logos to Joomla and PHP badges Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7b7bbe7..ea588c2 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ [![Version](https://img.shields.io/badge/version-03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg)](LICENSE) -[![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg)](https://www.joomla.org) -[![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg)](https://www.php.net) +[![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) +[![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla's Cassiopeia template. It adds **Font Awesome 7**, **Bootstrap 5** helpers, an automatic **Table of Contents (TOC)** utility, advanced **Dark Mode** theming, and optional integrations for **Google Tag Manager** and **Google Analytics (GA4)**β€”all while maintaining minimal core template overrides for maximum upgrade compatibility. From 7dce0524f2ad4c06386dfcc96778d2b09da48b5f Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:47:32 -0500 Subject: [PATCH 19/47] Simplify version badge to v03.09.07 Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ea588c2..ad8a7c7 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/version-03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/v03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From d0b48b77bdf76951ec3c5bde5d8e044769f43e17 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:49:28 -0500 Subject: [PATCH 20/47] Add GNU logo to license badge Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad8a7c7..023e505 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** [![Version](https://img.shields.io/badge/v03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) -[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg)](LICENSE) +[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From 700fc824aa64af10a88d1b9fec3cbab377f3a8e6 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:50:05 -0500 Subject: [PATCH 21/47] Version badge: Simple Icons logo with #5D87BF color Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 023e505..1b9f12f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/v03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/v03.09.07-5D87BF.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From e756784f6b44f4fb4d8d25567f6ba7fc66e20f26 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:50:57 -0500 Subject: [PATCH 22/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b9f12f..51ef0cb 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/v03.09.07-5D87BF.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/v03.09.07-#5D87BF.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From e7cf3c03223e95fc00748b04d80c7ca649f84a35 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:51:30 -0500 Subject: [PATCH 23/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 51ef0cb..1b9f12f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/v03.09.07-#5D87BF.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/v03.09.07-5D87BF.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From 827dd9ce134e7b96187ede70c4864796b68ace2a Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:52:01 -0500 Subject: [PATCH 24/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b9f12f..15d1276 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/v03.09.07-5D87BF.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/v03.09.07-000000.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From d88d57617ce78c8720ade4f7ae4f0e244bfe7f31 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:52:46 -0500 Subject: [PATCH 25/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15d1276..04bb11f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/v03.09.07-000000.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/v03.09.07-blue.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From b39a04a37f4f83335552e24e2a9aa31ab0ff7c57 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:53:08 -0500 Subject: [PATCH 26/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 04bb11f..42dd017 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/v03.09.07-blue.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/v03.09.07-blue.svg?logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From 0d6ae6bdb274a8cf6447de6e0caa13f76f42ab8e Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:54:03 -0500 Subject: [PATCH 27/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42dd017..023e505 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/v03.09.07-blue.svg?logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/v03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From 08a240a7efccdd5395b14bdb86f1b6d2b97c9f5e Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:55:26 -0500 Subject: [PATCH 28/47] Add 'version' label text to version badge Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 023e505..a5f88a8 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/v03.09.07-blue.svg)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/version-03.09.07-5D87BF.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) From 55ee68b7a9f0b572ef943027807c549c2a60f464 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:58:17 -0500 Subject: [PATCH 29/47] Standardize badge colors and logos Version: #5D87BF + semver logo License: green + gnu logo Joomla: red + joomla logo PHP: #8892BF + php logo Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a5f88a8..f388525 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/version-03.09.07-5D87BF.svg?logo=simpleicons&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/version-03.09.07-5D87BF.svg?logo=semver&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) -[![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) +[![PHP](https://img.shields.io/badge/PHP-8.1%2B-8892BF.svg?logo=php&logoColor=white)](https://www.php.net) MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla's Cassiopeia template. It adds **Font Awesome 7**, **Bootstrap 5** helpers, an automatic **Table of Contents (TOC)** utility, advanced **Dark Mode** theming, and optional integrations for **Google Tag Manager** and **Google Analytics (GA4)**β€”all while maintaining minimal core template overrides for maximum upgrade compatibility. From 434f4c95031c98c0ad67fa491f4c81da997e04dc Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:59:03 -0500 Subject: [PATCH 30/47] PHP badge color to purple Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f388525..8e6a927 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ [![Version](https://img.shields.io/badge/version-03.09.07-5D87BF.svg?logo=semver&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) -[![PHP](https://img.shields.io/badge/PHP-8.1%2B-8892BF.svg?logo=php&logoColor=white)](https://www.php.net) +[![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla's Cassiopeia template. It adds **Font Awesome 7**, **Bootstrap 5** helpers, an automatic **Table of Contents (TOC)** utility, advanced **Dark Mode** theming, and optional integrations for **Google Tag Manager** and **Google Analytics (GA4)**β€”all while maintaining minimal core template overrides for maximum upgrade compatibility. From d18ee75e6e61009838df53a0b86e03608f0cfd40 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:59:54 -0500 Subject: [PATCH 31/47] PHP badge to official PHP purple (#777BB4) Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e6a927..add8124 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ [![Version](https://img.shields.io/badge/version-03.09.07-5D87BF.svg?logo=semver&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) -[![PHP](https://img.shields.io/badge/PHP-8.1%2B-purple.svg?logo=php&logoColor=white)](https://www.php.net) +[![PHP](https://img.shields.io/badge/PHP-8.1%2B-777BB4.svg?logo=php&logoColor=white)](https://www.php.net) MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla's Cassiopeia template. It adds **Font Awesome 7**, **Bootstrap 5** helpers, an automatic **Table of Contents (TOC)** utility, advanced **Dark Mode** theming, and optional integrations for **Google Tag Manager** and **Google Analytics (GA4)**β€”all while maintaining minimal core template overrides for maximum upgrade compatibility. From fca0dbcb658abcf6f67fd77098d475fa9310a884 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:01:06 -0500 Subject: [PATCH 32/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> From 33292a181aeb7fc9f51277e03d040468cdc0b9e4 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:01:52 -0500 Subject: [PATCH 33/47] Update README.md Signed-off-by: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index add8124..5c16e4d 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/version-03.09.07-5D87BF.svg?logo=semver&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![Version](https://img.shields.io/badge/version-03.09.07-blue.svg?logo=v&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) [![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) [![PHP](https://img.shields.io/badge/PHP-8.1%2B-777BB4.svg?logo=php&logoColor=white)](https://www.php.net) From d6c4af18495b8e8f548be33c2fe5db3a72eb35ea Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:04:31 -0500 Subject: [PATCH 34/47] docs: update README badges to standard format [skip ci] Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5c16e4d..e5fbc90 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,20 @@ BRIEF: Documentation for MokoCassiopeia template --> + +[![Version](https://img.shields.io/badge/version-03.09.03-blue.svg?logo=v&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) +[![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) +[![PHP](https://img.shields.io/badge/PHP-8.1%2B-777BB4.svg?logo=php&logoColor=white)](https://www.php.net) + # MokoCassiopeia Template **A Modern, Lightweight Joomla Template Based on Cassiopeia** -[![Version](https://img.shields.io/badge/version-03.09.07-blue.svg?logo=v&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) -[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) -[![Joomla](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) -[![PHP](https://img.shields.io/badge/PHP-8.1%2B-777BB4.svg?logo=php&logoColor=white)](https://www.php.net) +](https://img.shields.io/badge/version-03.09.07-blue.svg?logo=v&logoColor=white)](https://github.com/mokoconsulting-tech/MokoCassiopeia/releases/tag/v03) +](https://img.shields.io/badge/license-GPL--3.0--or--later-green.svg?logo=gnu&logoColor=white)](LICENSE) +](https://img.shields.io/badge/Joomla-5.x%20%7C%206.x-red.svg?logo=joomla&logoColor=white)](https://www.joomla.org) +](https://img.shields.io/badge/PHP-8.1%2B-777BB4.svg?logo=php&logoColor=white)](https://www.php.net) MokoCassiopeia is a modern, lightweight enhancement layer built on top of Joomla's Cassiopeia template. It adds **Font Awesome 7**, **Bootstrap 5** helpers, an automatic **Table of Contents (TOC)** utility, advanced **Dark Mode** theming, and optional integrations for **Google Tag Manager** and **Google Analytics (GA4)**β€”all while maintaining minimal core template overrides for maximum upgrade compatibility. From d318a365a00c42baeae4efdec1388f0fef82ece5 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:10:21 -0500 Subject: [PATCH 35/47] Fix search module not showing on desktop Remove Bootstrap collapse classes that were hiding the search on desktop. Use CSS media queries instead: hidden on mobile by default, visible on desktop. JS toggles .show class on mobile via the search-toggler button. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/index.php | 2 +- src/media/css/template.css | 6 +++++- src/media/js/template.js | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/index.php b/src/index.php index 5a5abf0..1198dca 100644 --- a/src/index.php +++ b/src/index.php @@ -451,7 +451,7 @@ $wa->useScript('user.js'); // js/user.js -