Compare commits

..

117 Commits

Author SHA1 Message Date
jmiller 58fb87bb05 chore: create updates.xml with current releases [skip ci] 2026-06-04 18:33:16 +00:00
gitea-actions[bot] 86faa5086f chore(release): build 02.20.00 [skip ci] 2026-06-04 18:29:53 +00:00
jmiller 696c5a45c4 Merge pull request 'chore: update server name + consolidate changelog' (#126) from dev into main
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
chore: update server name + consolidate changelog
2026-06-04 18:29:46 +00:00
Jonathan Miller cbdbdcd553 chore: merge main into dev, resolve version header conflicts [skip bump]
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 9s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 10s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 3m7s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 13:28:34 -05:00
Jonathan Miller a5bab02fd1 chore: consolidate changelog to minor versions only [skip bump]
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Universal: Build & Release / Promote to RC (pull_request) Failing after 8s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 10s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 1m2s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 12:34:20 -05:00
gitea-actions[bot] c9a2cfa15c chore(version): auto-bump 02.19.04-dev [skip ci] 2026-06-04 17:26:29 +00:00
Jonathan Miller af76a8f2cb chore: update server name to 'Template - MokoOnyx' [skip bump]
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Update Server / Update Server (push) Successful in 9s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 12:25:58 -05:00
gitea-actions[bot] 1001df963e fix: ensure all pre-releases marked prerelease=true [skip ci] 2026-06-04 16:10:47 +00:00
jmiller ed7d356e99 chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:58:07 +00:00
jmiller 396b60902a chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:56:18 +00:00
gitea-actions[bot] c7d55e7fdd chore(release): build 02.20.00 [skip ci] 2026-06-04 15:53:48 +00:00
jmiller ad7fc53fb9 Merge pull request 'fix(menu): strip p-2 padding from FA icon classes + CI workflow updates' (#125) from dev into main
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
fix(menu): strip p-2 padding from FA icons + CI improvements
2026-06-04 15:53:39 +00:00
Jonathan Miller ad6a7e90e9 chore: merge main into dev, resolve version header conflicts [skip bump]
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 9s
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 26s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 21s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 10:53:08 -05:00
jmiller 041111b8ab chore: standardize updateservers URL [skip ci] 2026-06-04 15:50:47 +00:00
jmiller b65dd95dc4 chore: standardize updateservers URL [skip ci] 2026-06-04 15:50:46 +00:00
Jonathan Miller 8428f29058 chore: update changelog with unreleased entries [skip bump]
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 8s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 8s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 8s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 30s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 10:47:16 -05:00
jmiller 9e6cebb9aa chore: remove updates.xml [skip ci] 2026-06-04 15:42:19 +00:00
jmiller 595ee55499 chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:40:33 +00:00
jmiller 6e05b6aea0 chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:38:27 +00:00
jmiller 35bc550e0c chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:31:55 +00:00
jmiller c6b52100de chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:28:55 +00:00
jmiller c9470a45fe chore: remove updates.xml [skip ci] 2026-06-04 15:25:59 +00:00
jmiller 7962b370fa chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:18:45 +00:00
jmiller 0e4b0d55cb chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] 2026-06-04 15:13:25 +00:00
jmiller 2f7cbb57f9 chore: point updates.xml to migration release for URL migration [skip ci] 2026-06-04 15:00:06 +00:00
jmiller 006b47bbdf chore: sync updates.xml from development [skip ci] 2026-06-04 14:50:33 +00:00
gitea-actions[bot] 0cc2fea1bc chore: update development channel 02.19.03-dev [skip ci] 2026-06-04 14:50:32 +00:00
gitea-actions[bot] 5a9e8d86a1 chore(version): auto-bump 02.19.03-dev [skip ci] 2026-06-04 14:50:30 +00:00
Jonathan Miller 0cdd186eae fix(menu): strip Joomla-injected p-2 padding from FA icon classes
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 3s
Update Server / Update Server (push) Successful in 10s
Joomla's admin stores Bootstrap padding utility classes (p-0 through
p-5) in menu_icon alongside the Font Awesome class. This makes icon
padding too small. Strip these classes before rendering in all 12
menu override files (default, mainmenu, horizontal variants).

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 09:50:11 -05:00
gitea-actions[bot] 5e77328b66 chore: sync pre-release workflow — auto RC on PR to main [skip ci] 2026-06-04 14:45:39 +00:00
jmiller ac05b97262 chore: sync .mokogitea/workflows/auto-release.yml from moko-platform [skip ci] 2026-06-04 14:23:10 +00:00
jmiller b1391c6d03 chore: sync .mokogitea/workflows/auto-release.yml from moko-platform [skip ci] 2026-06-04 14:20:22 +00:00
jmiller ec75322bed chore: sync updates.xml 02.20.00 from main [skip ci] 2026-06-04 14:03:28 +00:00
gitea-actions[bot] 6a6a8d7c0c chore: update channels for 02.20.00 [skip ci] 2026-06-04 14:03:27 +00:00
gitea-actions[bot] 3d059a0ad8 chore(release): build 02.20.00 [skip ci] 2026-06-04 14:03:26 +00:00
jmiller 28b4916d94 Merge pull request 'release: update server migration + duplicate extension fix' (#123) from dev into main
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
release: update server migration + duplicate extension fix
2026-06-04 14:03:18 +00:00
jmiller 2addc3bdb4 chore: sync updates.xml from development [skip ci] 2026-06-04 14:02:25 +00:00
gitea-actions[bot] b573c6e762 chore: update development channel 02.19.02-dev [skip ci]
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 21s
2026-06-04 14:02:24 +00:00
gitea-actions[bot] 0a1e788f00 chore(version): auto-bump 02.19.02-dev [skip ci] 2026-06-04 14:02:22 +00:00
jmiller b051e49320 Merge pull request 'feat(update): migrate update server URL to Gitea Pages' (#124) from feature/update-server-migration into dev
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Update Server / Update Server (push) Successful in 13s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 29s
feat(update): migrate update server URL to Gitea Pages
2026-06-04 14:02:09 +00:00
Jonathan Miller 4b0c024299 feat(update): migrate update server URL to Gitea Pages
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 3s
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 5s
Update Server / Update Server (pull_request) Failing after 10s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 12s
Changes the Joomla update server URL from the raw file path
(/raw/branch/main/updates.xml) to the Gitea Pages URL
(/updates.xml). Existing installs will pick up the new URL
on their next template update.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 09:01:47 -05:00
jmiller 951221bcc0 chore: sync .mokogitea/workflows/repo-health.yml from moko-platform [skip ci] 2026-06-04 13:46:58 +00:00
jmiller 3d357d1bd3 chore: sync updates.xml from development [skip ci] 2026-06-04 13:44:51 +00:00
gitea-actions[bot] 9062a3141e chore: update development channel 02.19.01-dev [skip ci] 2026-06-04 13:44:50 +00:00
gitea-actions[bot] 41d8ce7a2a chore(version): auto-bump 02.19.01-dev [skip ci] 2026-06-04 13:44:49 +00:00
Jonathan Miller 0e9703f8b0 Merge origin/main into dev — sync version headers
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Update Server / Update Server (push) Successful in 12s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 28s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 08:44:06 -05:00
jmiller 8abadc1709 chore: sync updates.xml from development [skip ci] 2026-06-04 13:25:46 +00:00
gitea-actions[bot] 706f3137b7 chore: update development channel 02.18.04-dev [skip ci] 2026-06-04 13:25:45 +00:00
gitea-actions[bot] d28877fc0c chore(version): auto-bump 02.18.04-dev [skip ci] 2026-06-04 13:25:44 +00:00
jmiller 43a7432f08 Merge pull request 'fix(script): auto-remove duplicate MokoOnyx and stale MokoCassiopeia' (#122) from fix/remove-stale-extensions into dev
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Update Server / Update Server (push) Successful in 9s
Generic: Repo Health / Access control (push) Successful in 1s
2026-06-04 13:25:33 +00:00
Jonathan Miller a12c6ece42 fix(script): auto-remove duplicate MokoOnyx and stale MokoCassiopeia extensions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Update Server / Update Server (pull_request) Failing after 9s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 9s
On update, detects and removes:
- Duplicate MokoOnyx entries in #__extensions (keeps locked/active one)
- Stale MokoCassiopeia extension (only if not default template)

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 08:10:16 -05:00
gitea-actions[bot] adba742cfe chore: update channels for 02.19.00 [skip ci] 2026-06-04 12:18:51 +00:00
jmiller 6929868dd7 chore: sync updates.xml 02.19.00 from main [skip ci] 2026-06-04 12:18:51 +00:00
gitea-actions[bot] 99ab99dfe2 chore(release): build 02.19.00 [skip ci] 2026-06-04 12:18:49 +00:00
jmiller 0e4e329770 Merge pull request 'fix(minify): keyword regex + remove JoomGallery overrides' (#121) from dev into main
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Merge PR #121: fix(minify) keyword regex + remove JoomGallery overrides + upgrade cleanup script
2026-06-04 12:18:42 +00:00
jmiller 35f79bc53e chore: sync updates.xml from development [skip ci] 2026-06-04 12:12:24 +00:00
gitea-actions[bot] 50762b3e20 chore: update development channel 02.18.03-dev [skip ci]
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 19s
2026-06-04 12:12:23 +00:00
gitea-actions[bot] 0e420718cf chore(version): auto-bump 02.18.03-dev [skip ci] 2026-06-04 12:12:21 +00:00
Jonathan Miller 9f88c265bc feat(script): add removeDeletedFiles() to clean up stale overrides on upgrade
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: Auto Version Bump / Version Bump (push) Failing after 3s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Update Server / Update Server (push) Successful in 10s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 39s
Joomla's installer never deletes files on upgrade. This adds a
maintenance list of files/dirs removed from the package so they get
cleaned up on existing installs. Starts with the JoomGallery template
overrides removed in this release.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 07:12:06 -05:00
jmiller 9ace43be1a chore: sync updates.xml from development [skip ci] 2026-06-04 12:03:57 +00:00
gitea-actions[bot] 0b47958b28 chore: update development channel 02.18.02-dev [skip ci] 2026-06-04 12:03:56 +00:00
gitea-actions[bot] ad5bb9d46a chore(version): auto-bump 02.18.02-dev [skip ci] 2026-06-04 12:03:54 +00:00
Jonathan Miller 1cfc8f8669 Merge origin/dev — reconcile auto-bump commits with main merge
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Update Server / Update Server (push) Successful in 11s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 07:03:43 -05:00
Jonathan Miller 28da101822 Merge origin/main into dev
Resolve conflicts: take main for CI/workflows/docs, dev for source.
Remove JoomGallery template overrides. Fix embedded conflict markers
from prior bad merge on main. Bump version to 02.18.01-dev.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 06:48:08 -05:00
Jonathan Miller 0dffd277e0 refactor: remove JoomGallery template overrides
JoomGallery overrides are no longer maintained in the core template.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 00:05:05 -05:00
jmiller be08e707f1 chore: sync updates.xml from development [skip ci] 2026-06-03 23:41:32 +00:00
gitea-actions[bot] e265edb4ba chore: update development channel 02.16.03-dev [skip ci] 2026-06-03 23:41:31 +00:00
gitea-actions[bot] 98fddcbedb chore(version): auto-bump 02.16.03-dev [skip ci] 2026-06-03 23:41:29 +00:00
Jonathan Miller 2886ebdf54 fix(minify): add word boundary assertions to JS keyword restoration regex
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Update Server / Update Server (push) Successful in 13s
The keyword restoration step in minifyJs() was matching 'in' and other
short keywords as substrings inside identifiers (init → in it,
window → win dow, contains → contain s, getBoundingClientRect →
getBoundin gClientRect), corrupting the minified JS output and breaking
all template JavaScript on every MokoOnyx site.

Adding \b word boundaries ensures only standalone keywords are matched.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-03 18:41:13 -05:00
jmiller 36c15a3d86 chore: sync .mokogitea/workflows/repo-health.yml from moko-platform [skip ci] 2026-06-03 09:36:56 +00:00
jmiller 4ceb9efbf0 chore: sync .mokogitea/workflows/repo-health.yml from moko-platform [skip ci] 2026-06-03 03:10:39 +00:00
jmiller 6ce2cdb2cb chore: sync updates.xml from development [skip ci] 2026-06-02 22:11:10 +00:00
gitea-actions[bot] 6c61c13db6 chore: update development channel 02.16.02-dev [skip ci] 2026-06-02 22:11:10 +00:00
gitea-actions[bot] 97466819c5 chore(version): auto-bump 02.16.02-dev [skip ci] 2026-06-02 22:11:08 +00:00
Jonathan Miller 61adcb0bc9 fix(ci): add conflict-marker guard to release and PR workflows
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 3s
Update Server / Update Server (push) Successful in 12s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Prevents releases from shipping with unresolved merge conflict markers.
Adds a validation step to both auto-release.yml (blocks release) and
pr-check.yml (catches at PR time). Also cleans existing conflict markers
from templateDetails.xml.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 16:35:36 -05:00
Moko Consulting 6d1aaa952b chore(ci): sync CI issue reporter from Template-Joomla
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 6s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 21:32:51 +00:00
Moko Consulting 2aeb4d5ecc chore(ci): sync CI issue reporter from Template-Joomla
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 6s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 21:32:49 +00:00
Moko Consulting b1fb0d2294 chore(ci): sync CI issue reporter from Template-Joomla
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Failing after 6s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 21:32:48 +00:00
Moko Consulting da91c6c820 chore(ci): sync CI issue reporter from Template-Joomla
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 21:32:47 +00:00
Moko Consulting f08caa6125 chore(ci): sync CI issue reporter from Template-Joomla
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 21:32:45 +00:00
Moko Consulting 5ab9729694 chore(ci): sync CI issue reporter from Template-Joomla
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 21:32:43 +00:00
Moko Consulting 04ca05ccc3 chore(ci): add CI issue reporter for auto-filing gate failures
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 20:36:51 +00:00
Moko Consulting eac32646cb chore(ci): add CI issue reporter for auto-filing gate failures
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 20:36:50 +00:00
Moko Consulting 1859dd728c chore(ci): add CI issue reporter for auto-filing gate failures
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Failing after 5s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 20:36:50 +00:00
Moko Consulting 7b02af2b76 chore(ci): add CI issue reporter for auto-filing gate failures
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 20:36:49 +00:00
Moko Consulting c4a7925f7f chore(ci): add CI issue reporter for auto-filing gate failures
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 20:36:49 +00:00
Moko Consulting d357bf958a chore(ci): add CI issue reporter for auto-filing gate failures
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
2026-06-02 20:36:47 +00:00
jmiller 2242a61197 chore: sync updates.xml 02.18.00 from main [skip ci] 2026-06-02 19:40:38 +00:00
gitea-actions[bot] 74c433a98b chore: update channels for 02.18.00 [skip ci] 2026-06-02 19:40:37 +00:00
gitea-actions[bot] 3f9e700876 chore(release): build 02.18.00 [skip ci] 2026-06-02 19:40:36 +00:00
jmiller f8aae4c639 Merge pull request 'feat(ci): auto-update MokoOnyx submodule in MokoWaaS' (#120) from dev into main
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
2026-06-02 19:40:28 +00:00
Jonathan Miller a16949fd4d feat(ci): auto-update MokoOnyx submodule in MokoWaaS on release
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 3s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 5s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 41s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 21s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Generic: Repo Health / Release configuration (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Triggers on stable releases, updates src/packages/tpl_mokoonyx
submodule pointer on both main and dev branches of MokoWaaS.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 14:28:13 -05:00
jmiller faead32d07 chore: sync updates.xml 02.17.00 from main [skip ci] 2026-06-02 19:04:26 +00:00
gitea-actions[bot] f3897495ad chore: update channels for 02.17.00 [skip ci] 2026-06-02 19:04:25 +00:00
gitea-actions[bot] 64cbc5674e chore(release): build 02.17.00 [skip ci] 2026-06-02 19:04:24 +00:00
jmiller e7a83e9232 Merge pull request 'chore(release): stable release' (#119) from dev into main
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
chore(release): stable release
2026-06-02 19:04:14 +00:00
Jonathan Miller eaa2c1808c fix: restore release workflows removed during migration
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 6s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 22s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 1m6s
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Generic: Repo Health / Release configuration (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-02 14:02:44 -05:00
gitea-actions[bot] 17ccd019de chore(ci): remove update-server.yml for update server migration [skip ci] 2026-05-31 03:48:35 +00:00
gitea-actions[bot] 3a543aa7c5 chore(ci): remove cascade-dev.yml for update server migration [skip ci] 2026-05-31 03:48:32 +00:00
gitea-actions[bot] 00194a2fdc chore(ci): remove auto-bump.yml for update server migration [skip ci] 2026-05-31 03:48:30 +00:00
gitea-actions[bot] 14eeb80569 chore(ci): remove pre-release.yml for update server migration [skip ci] 2026-05-31 03:48:27 +00:00
gitea-actions[bot] d757e009e3 chore(ci): remove auto-release.yml for update server migration [skip ci] 2026-05-31 03:48:23 +00:00
jmiller 16a7090f29 chore: sync updates.xml from development [skip ci] 2026-05-31 01:51:54 +00:00
gitea-actions[bot] 33cb75af26 chore: update development channel 02.16.01-dev [skip ci] 2026-05-31 01:51:53 +00:00
gitea-actions[bot] e8393b0322 chore(version): auto-bump 02.16.01-dev [skip ci] 2026-05-31 01:51:51 +00:00
Jonathan Miller 3a30f1a088 Merge remote-tracking branch 'origin/main' into dev
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (push) Successful in 6s
Universal: PR Check / Branch Policy (pull_request) Successful in 3s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Universal: Auto Version Bump / Version Bump (push) Failing after 14s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 12s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 11s
Universal: PR Check / Validate PR (pull_request) Failing after 10s
Update Server / Update Server (push) Successful in 18s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 35s
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Generic: Repo Health / Release configuration (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
# Conflicts:
#	.mokogitea/cascade-dev.yml
#	src/templateDetails.xml
#	updates.xml
2026-05-30 20:51:21 -05:00
jmiller 872b5329a3 fix: remove conflict markers [skip ci] 2026-05-31 01:50:07 +00:00
jmiller 8ae203cca0 chore: sync .mokogitea/workflows/cascade-dev.yml from moko-platform [skip ci] 2026-05-31 01:45:22 +00:00
jmiller 7ca7c6713c chore: sync .mokogitea/workflows/cascade-dev.yml from moko-platform [skip ci] 2026-05-31 01:41:47 +00:00
jmiller 18a5934106 chore: sync CONTRIBUTING.md from moko-platform [skip ci] 2026-05-31 01:10:00 +00:00
jmiller 2d25ae2359 fix: remove stale alpha/beta/rc entries from updates.xml [skip ci] 2026-05-31 00:56:44 +00:00
jmiller 94680bbd3f chore: sync updates.xml 02.17.00-rc from rc [skip ci] 2026-05-30 23:37:31 +00:00
jmiller d4e1c96224 chore: sync updates.xml 02.17.00-rc from rc [skip ci] 2026-05-30 23:37:30 +00:00
Jonathan Miller 1170fb21bf fix: disable cascade-dev to prevent version conflicts [skip ci] 2026-05-30 18:34:01 -05:00
jmiller a2d494544b fix: remove version conflict markers [skip ci] 2026-05-30 22:54:29 +00:00
jmiller c42a23d739 chore: sync updates.xml from development [skip ci] 2026-05-30 22:51:33 +00:00
jmiller dda2d4b20e Merge pull request 'chore(release): patch release' (#117) from dev into main
Universal: Cascade Main → Dev / Cascade main → branches (push) Failing after 2s
2026-05-30 22:51:23 +00:00
48 changed files with 2027 additions and 2021 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# DISABLED - auto-release handles dev recreation from main
# DISABLED - auto-release handles dev recreation
name: Cascade (DISABLED)
on: workflow_dispatch
jobs:
+1 -1
View File
@@ -9,7 +9,7 @@
<display-name>Template - MokoOnyx</display-name>
<org>MokoConsulting</org>
<description>MokoOnyx - Joomla site template (successor to MokoCassiopeia)</description>
<version>02.17.00</version>
<version>02.20.00</version>
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
</identity>
<governance>
+18 -3
View File
@@ -102,13 +102,14 @@ jobs:
run: |
php /tmp/moko-platform-api/cli/release_publish.php \
--path . --stability rc --bump minor --branch rc \
--token "${{ secrets.MOKOGITEA_TOKEN }}"
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
--skip-update-stream
- name: Summary
if: always()
run: |
echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
echo "Branch renamed to rc, minor bump, RC + lesser stream releases built, updates.xml synced" >> $GITHUB_STEP_SUMMARY
echo "Branch renamed to rc, minor bump, RC release built (updates.xml managed by Gitea Pages)" >> $GITHUB_STEP_SUMMARY
# ── Merged PR → Build & Release (or promote RC to stable) ────────────────────
release:
@@ -131,6 +132,19 @@ jobs:
git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
- name: Check for merge conflict markers
run: |
CONFLICTS=$(grep -rn '<<<<<<< \|>>>>>>> \|^=======$' --include='*.php' --include='*.xml' --include='*.css' --include='*.js' --include='*.json' --include='*.md' --include='*.yml' --include='*.yaml' --include='*.ini' --include='*.txt' . 2>/dev/null | grep -v '.git/' || true)
if [ -n "$CONFLICTS" ]; then
echo "::error::Merge conflict markers found — aborting release"
echo "## Release Blocked: Conflict Markers" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$CONFLICTS" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "No conflict markers found"
- name: Setup moko-platform tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
@@ -154,7 +168,8 @@ jobs:
run: |
php /tmp/moko-platform-api/cli/release_publish.php \
--path . --stability stable --bump minor --branch main \
--token "${{ secrets.MOKOGITEA_TOKEN }}"
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
--skip-update-stream
# -- STEP 9: Mirror to GitHub (stable only) --------------------------------
- name: "Step 9: Mirror release to GitHub"
+5 -3
View File
@@ -1,8 +1,10 @@
# DISABLED - auto-release handles dev recreation from main
name: Cascade (DISABLED)
# DISABLED auto-release Step 11 recreates dev from main after every release.
# Cascade-dev is redundant and causes version conflicts when both main and dev
# have different version numbers in templateDetails.xml / manifest.xml.
name: "Cascade Main → Dev (DISABLED)"
on: workflow_dispatch
jobs:
noop:
runs-on: ubuntu-latest
steps:
- run: echo disabled
- run: echo "Cascade disabled — auto-release handles dev recreation"
+1 -11
View File
@@ -5,17 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Automation
<<<<<<< HEAD
<<<<<<< HEAD
# VERSION: 02.17.00
=======
# VERSION: 02.17.00
=======
# VERSION: 02.17.00
=======
# VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
# VERSION: 02.20.00
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+508 -236
View File
@@ -1,236 +1,508 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.CI
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform
# PATH: /templates/workflows/universal/pr-check.yml.template
# VERSION: 05.00.00
# BRIEF: PR gate — branch policy + code validation before merge
name: "Universal: PR Check"
on:
pull_request:
types: [opened, synchronize, reopened, edited]
permissions:
contents: read
pull-requests: write
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
# ── Branch Policy ──────────────────────────────────────────────────────
branch-policy:
name: Branch Policy
runs-on: ubuntu-latest
steps:
- name: Check branch merge target
run: |
HEAD="${{ github.head_ref }}"
BASE="${{ github.base_ref }}"
echo "PR: ${HEAD} → ${BASE}"
ALLOWED=true
REASON=""
case "$HEAD" in
feature/*|feat/*)
if [ "$BASE" != "dev" ]; then
ALLOWED=false
REASON="Feature branches must target 'dev', not '${BASE}'"
fi
;;
fix/*|bugfix/*)
if [ "$BASE" != "dev" ]; then
ALLOWED=false
REASON="Fix branches must target 'dev', not '${BASE}'"
fi
;;
patch/*)
if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ]; then
ALLOWED=false
REASON="Patch branches must target 'dev' or 'rc', not '${BASE}'"
fi
;;
hotfix/*)
if [ "$BASE" != "dev" ] && [ "$BASE" != "main" ]; then
ALLOWED=false
REASON="Hotfix branches can only target 'dev' or 'main', not '${BASE}'"
fi
;;
rc)
if [ "$BASE" != "main" ]; then
ALLOWED=false
REASON="RC branch can only merge into 'main', not '${BASE}'"
fi
;;
dev)
if [ "$BASE" != "main" ]; then
ALLOWED=false
REASON="Dev branch can only merge into 'main', not '${BASE}'"
fi
;;
esac
if [ "$ALLOWED" = false ]; then
echo "::error::${REASON}"
echo "## Branch Policy Violation" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "${REASON}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Allowed merge paths:" >> $GITHUB_STEP_SUMMARY
echo "- \`feature/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY
echo "- \`fix/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY
echo "- \`hotfix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY
echo "- \`dev\` → \`main\`" >> $GITHUB_STEP_SUMMARY
echo "- \`rc/*\` → \`main\`" >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "Branch policy: OK (${HEAD} → ${BASE})"
echo "## Branch Policy: Passed" >> $GITHUB_STEP_SUMMARY
# ── Code Validation ────────────────────────────────────────────────────
validate:
name: Validate PR
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Detect platform
id: platform
run: |
# Read platform from XML manifest (<platform> tag) or plain text fallback
PLATFORM=$(sed -n 's/.*<platform>\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1)
[ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogitea/manifest.xml 2>/dev/null | tr -d '[:space:]')
[ -z "$PLATFORM" ] && PLATFORM="generic"
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
- name: Setup PHP
if: steps.platform.outputs.platform == 'joomla' || steps.platform.outputs.platform == 'dolibarr'
run: |
if ! command -v php &> /dev/null; then
sudo apt-get update -qq
sudo apt-get install -y -qq php-cli php-mbstring php-xml >/dev/null 2>&1
fi
- name: PHP syntax check
if: steps.platform.outputs.platform == 'joomla' || steps.platform.outputs.platform == 'dolibarr'
run: |
ERRORS=0
while IFS= read -r -d '' file; do
if ! php -l "$file" 2>&1 | grep -q "No syntax errors"; then
ERRORS=$((ERRORS + 1))
fi
done < <(find . -name "*.php" -not -path "./.git/*" -not -path "./vendor/*" -print0)
echo "PHP lint: ${ERRORS} error(s)"
[ "$ERRORS" -eq 0 ] || { echo "::error::PHP syntax errors found"; exit 1; }
- name: Validate platform manifest
run: |
PLATFORM="${{ steps.platform.outputs.platform }}"
case "$PLATFORM" in
joomla)
MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '<extension' {} \; 2>/dev/null | head -1)
if [ -z "$MANIFEST" ]; then
echo "::warning::No Joomla manifest found (WaaS site)"
exit 0
fi
echo "Manifest: ${MANIFEST}"
if command -v php &> /dev/null; then
php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('$MANIFEST'); if(!\$x){foreach(libxml_get_errors() as \$e) echo \$e->message; exit(1);}" || { echo "::error::Manifest XML is malformed"; exit 1; }
fi
for ELEMENT in name version description; do
grep -q "<${ELEMENT}>" "$MANIFEST" || { echo "::error::Missing <${ELEMENT}> in manifest"; exit 1; }
done
echo "Joomla manifest valid"
;;
dolibarr)
MOD_FILE=$(find . -maxdepth 4 -name "mod*.class.php" ! -path "./.git/*" -exec grep -l 'extends DolibarrModules' {} \; 2>/dev/null | head -1)
if [ -z "$MOD_FILE" ]; then
echo "::error::No mod*.class.php found"
exit 1
fi
echo "Dolibarr module: ${MOD_FILE}"
;;
*)
echo "Generic platform — no manifest validation"
;;
esac
- name: Check update stream format
run: |
PLATFORM="${{ steps.platform.outputs.platform }}"
case "$PLATFORM" in
joomla)
if [ -f "updates.xml" ]; then
if command -v php &> /dev/null; then
php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('updates.xml'); if(!\$x){foreach(libxml_get_errors() as \$e) echo \$e->message; exit(1);}" || { echo "::error::updates.xml is malformed"; exit 1; }
fi
echo "updates.xml valid"
fi
;;
dolibarr)
[ -f "update.txt" ] && echo "update.txt present" || echo "::warning::No update.txt"
;;
esac
- name: Check changelog has unreleased entry
run: |
if [ ! -f "CHANGELOG.md" ]; then
echo "::warning::No CHANGELOG.md found"
exit 0
fi
# Check for content under [Unreleased] section
if ! grep -q "## \[Unreleased\]" CHANGELOG.md; then
echo "::error::CHANGELOG.md missing [Unreleased] section"
exit 1
fi
# Check there's at least one entry (Added/Changed/Fixed/Removed) under Unreleased
UNRELEASED_CONTENT=$(sed -n '/## \[Unreleased\]/,/## \[/p' CHANGELOG.md | grep -cE '^\s*-\s' || true)
if [ "$UNRELEASED_CONTENT" -eq 0 ]; then
echo "::error::CHANGELOG.md [Unreleased] section has no entries. Add a changelog entry describing your changes."
echo "## Changelog Check: Failed" >> $GITHUB_STEP_SUMMARY
echo "The \`[Unreleased]\` section in CHANGELOG.md has no entries." >> $GITHUB_STEP_SUMMARY
echo "Add a line like \`- Description of your change\` under a heading (\`### Added\`, \`### Changed\`, \`### Fixed\`, etc.)" >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "Changelog: ${UNRELEASED_CONTENT} entry/entries in [Unreleased]"
- name: Verify package source
run: |
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
if [ ! -d "$SOURCE_DIR" ]; then
echo "::warning::No src/ or htdocs/ directory"
exit 0
fi
FILE_COUNT=$(find "$SOURCE_DIR" -type f | wc -l)
echo "Source: ${FILE_COUNT} files"
[ "$FILE_COUNT" -gt 0 ] || { echo "::error::Source directory is empty"; exit 1; }
# ── Pre-Release RC Build ─────────────────────────────────────────────────
pre-release:
name: Build RC Package
runs-on: ubuntu-latest
needs: [branch-policy, validate]
steps:
- name: Trigger RC pre-release
env:
GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: ${{ github.head_ref }}
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
run: |
curl -s -X POST "${GITEA_URL}/api/v1/repos/${REPO}/actions/workflows/pre-release.yml/dispatches" -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" -d "{\"ref\":\"${BRANCH}\",\"inputs\":{\"stability\":\"release-candidate\"}}"
echo "### Pre-Release" >> $GITHUB_STEP_SUMMARY
echo "Triggered RC build on branch \`${BRANCH}\`" >> $GITHUB_STEP_SUMMARY
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.CI
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform
# PATH: /templates/workflows/universal/pr-check.yml.template
# VERSION: 09.23.00
# BRIEF: PR gate — branch policy + code validation before merge
name: "Universal: PR Check"
on:
pull_request:
types: [opened, synchronize, reopened, edited]
permissions:
contents: read
pull-requests: write
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
# ── Branch Policy ──────────────────────────────────────────────────────
branch-policy:
name: Branch Policy
runs-on: ubuntu-latest
steps:
- name: Check branch merge target
run: |
HEAD="${{ github.head_ref }}"
BASE="${{ github.base_ref }}"
echo "PR: ${HEAD} → ${BASE}"
ALLOWED=true
REASON=""
case "$HEAD" in
feature/*|feat/*)
if [ "$BASE" != "dev" ]; then
ALLOWED=false
REASON="Feature branches must target 'dev', not '${BASE}'"
fi
;;
fix/*|bugfix/*)
if [ "$BASE" != "dev" ]; then
ALLOWED=false
REASON="Fix branches must target 'dev', not '${BASE}'"
fi
;;
patch/*)
if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ]; then
ALLOWED=false
REASON="Patch branches must target 'dev' or 'rc', not '${BASE}'"
fi
;;
hotfix/*)
if [ "$BASE" != "dev" ] && [ "$BASE" != "main" ]; then
ALLOWED=false
REASON="Hotfix branches can only target 'dev' or 'main', not '${BASE}'"
fi
;;
rc)
if [ "$BASE" != "main" ]; then
ALLOWED=false
REASON="RC branch can only merge into 'main', not '${BASE}'"
fi
;;
dev)
if [ "$BASE" != "main" ]; then
ALLOWED=false
REASON="Dev branch can only merge into 'main', not '${BASE}'"
fi
;;
esac
if [ "$ALLOWED" = false ]; then
echo "::error::${REASON}"
echo "## Branch Policy Violation" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "${REASON}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Allowed merge paths:" >> $GITHUB_STEP_SUMMARY
echo "- \`feature/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY
echo "- \`fix/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY
echo "- \`hotfix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY
echo "- \`dev\` → \`main\`" >> $GITHUB_STEP_SUMMARY
echo "- \`rc/*\` → \`main\`" >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "Branch policy: OK (${HEAD} → ${BASE})"
echo "## Branch Policy: Passed" >> $GITHUB_STEP_SUMMARY
# ── Code Validation ────────────────────────────────────────────────────
validate:
name: Validate PR
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check for merge conflict markers
run: |
CONFLICTS=$(grep -rn '<<<<<<< \|>>>>>>> \|^=======$' --include='*.php' --include='*.xml' --include='*.css' --include='*.js' --include='*.json' --include='*.md' --include='*.yml' --include='*.yaml' --include='*.ini' --include='*.txt' . 2>/dev/null | grep -v '.git/' || true)
if [ -n "$CONFLICTS" ]; then
echo "::error::Merge conflict markers found in source files"
echo "## Conflict Markers Found" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$CONFLICTS" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "No conflict markers found"
- name: Detect platform
id: platform
run: |
# Read platform from XML manifest (<platform> tag) or plain text fallback
PLATFORM=$(sed -n 's/.*<platform>\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1)
[ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogitea/manifest.xml 2>/dev/null | tr -d '[:space:]')
[ -z "$PLATFORM" ] && PLATFORM="generic"
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
- name: Setup PHP
if: steps.platform.outputs.platform == 'joomla' || steps.platform.outputs.platform == 'dolibarr'
run: |
if ! command -v php &> /dev/null; then
sudo apt-get update -qq
sudo apt-get install -y -qq php-cli php-mbstring php-xml >/dev/null 2>&1
fi
- name: PHP syntax check
if: steps.platform.outputs.platform == 'joomla' || steps.platform.outputs.platform == 'dolibarr'
run: |
ERRORS=0
while IFS= read -r -d '' file; do
if ! php -l "$file" 2>&1 | grep -q "No syntax errors"; then
ERRORS=$((ERRORS + 1))
fi
done < <(find . -name "*.php" -not -path "./.git/*" -not -path "./vendor/*" -print0)
echo "PHP lint: ${ERRORS} error(s)"
[ "$ERRORS" -eq 0 ] || { echo "::error::PHP syntax errors found"; exit 1; }
- name: Joomla JEXEC guard check
if: steps.platform.outputs.platform == 'joomla'
run: |
ERRORS=0
while IFS= read -r -d '' file; do
# Skip vendor, node_modules, and index.html stub files
case "$file" in ./vendor/*|./node_modules/*) continue ;; esac
# Check first 10 lines for JEXEC or JPATH guard
if ! head -20 "$file" | grep -qE "defined\s*\(\s*['\"](_JEXEC|JPATH_BASE|\\\\JPATH_PLATFORM)['\"]"; then
echo "::error file=${file}::Missing JEXEC guard: ${file}"
ERRORS=$((ERRORS + 1))
fi
done < <(find . -name "*.php" -path "*/src/*" -not -path "./.git/*" -not -path "./vendor/*" -print0)
if [ "$ERRORS" -gt 0 ]; then
echo "::error::${ERRORS} PHP file(s) missing defined('_JEXEC') or die guard"
echo "## JEXEC Guard Check: Failed" >> $GITHUB_STEP_SUMMARY
echo "${ERRORS} file(s) in src/ are missing the Joomla execution guard." >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "JEXEC guard: OK"
- name: Joomla directory listing protection
if: steps.platform.outputs.platform == 'joomla'
run: |
MISSING=0
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && exit 0
while IFS= read -r dir; do
if [ ! -f "${dir}/index.html" ]; then
echo "::warning::Missing index.html in ${dir} (directory listing protection)"
MISSING=$((MISSING + 1))
fi
done < <(find "$SOURCE_DIR" -type d -not -path "./.git/*" -not -path "*/vendor/*" -not -path "*/node_modules/*")
if [ "$MISSING" -gt 0 ]; then
echo "## Directory Protection" >> $GITHUB_STEP_SUMMARY
echo "${MISSING} director(ies) missing index.html" >> $GITHUB_STEP_SUMMARY
fi
echo "Directory protection: ${MISSING} missing (advisory)"
- name: Joomla script file and asset checks
if: steps.platform.outputs.platform == 'joomla'
run: |
ERRORS=0
MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '<extension' {} \; 2>/dev/null | head -1)
[ -z "$MANIFEST" ] && exit 0
MANIFEST_DIR=$(dirname "$MANIFEST")
# Check scriptfile exists if declared
SCRIPTFILE=$(sed -n 's/.*<scriptfile>\([^<]*\)<\/scriptfile>.*/\1/p' "$MANIFEST" 2>/dev/null)
if [ -n "$SCRIPTFILE" ]; then
if [ ! -f "${MANIFEST_DIR}/${SCRIPTFILE}" ]; then
echo "::error::Manifest declares <scriptfile>${SCRIPTFILE}</scriptfile> but file not found at ${MANIFEST_DIR}/${SCRIPTFILE}"
ERRORS=$((ERRORS + 1))
else
echo "Script file: ${MANIFEST_DIR}/${SCRIPTFILE} (OK)"
fi
fi
# Require joomla.asset.json and validate it
ASSET_JSON=$(find "$MANIFEST_DIR" -name "joomla.asset.json" -not -path "./.git/*" 2>/dev/null | head -1)
if [ -z "$ASSET_JSON" ]; then
echo "::error::joomla.asset.json not found — Joomla asset system is required"
ERRORS=$((ERRORS + 1))
else
if command -v php &> /dev/null; then
php -r "json_decode(file_get_contents('$ASSET_JSON')); if(json_last_error()!==JSON_ERROR_NONE){echo json_last_error_msg();exit(1);}" 2>&1 || {
echo "::error::joomla.asset.json is not valid JSON"
ERRORS=$((ERRORS + 1))
}
fi
echo "joomla.asset.json: valid"
fi
# Validate all XML files in src/ are well-formed
XML_ERRORS=0
if command -v php &> /dev/null; then
while IFS= read -r -d '' xmlfile; do
if ! php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('$xmlfile'); if(!\$x){foreach(libxml_get_errors() as \$e) echo trim(\$e->message) . ' in $xmlfile'; exit(1);}" 2>&1; then
XML_ERRORS=$((XML_ERRORS + 1))
fi
done < <(find "$MANIFEST_DIR" -name "*.xml" -not -path "./.git/*" -print0)
fi
if [ "$XML_ERRORS" -gt 0 ]; then
echo "::error::${XML_ERRORS} XML file(s) are malformed"
ERRORS=$((ERRORS + 1))
else
echo "XML well-formedness: OK"
fi
[ "$ERRORS" -gt 0 ] && exit 1
echo "Joomla asset checks: OK"
- name: Validate platform manifest
run: |
PLATFORM="${{ steps.platform.outputs.platform }}"
case "$PLATFORM" in
joomla)
MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '<extension' {} \; 2>/dev/null | head -1)
if [ -z "$MANIFEST" ]; then
echo "::warning::No Joomla manifest found (WaaS site)"
exit 0
fi
echo "Manifest: ${MANIFEST}"
if command -v php &> /dev/null; then
php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('$MANIFEST'); if(!\$x){foreach(libxml_get_errors() as \$e) echo \$e->message; exit(1);}" || { echo "::error::Manifest XML is malformed"; exit 1; }
fi
for ELEMENT in name version description; do
grep -q "<${ELEMENT}>" "$MANIFEST" || { echo "::error::Missing <${ELEMENT}> in manifest"; exit 1; }
done
# Block legacy raw/branch update server URLs on MokoGitea
RAW_URLS=$(grep -n 'raw/branch' "$MANIFEST" | grep -i 'mokoconsulting\|mokogitea\|git\.mokoconsulting\.tech' || true)
if [ -n "$RAW_URLS" ]; then
echo "::error::Manifest contains legacy raw/branch update server URL on MokoGitea. Use the Gitea Pages URL instead (e.g. /{REPO}/updates.xml not /{REPO}/raw/branch/main/updates.xml)"
echo "$RAW_URLS"
exit 1
fi
echo "Joomla manifest valid"
;;
dolibarr)
MOD_FILE=$(find . -maxdepth 4 -name "mod*.class.php" ! -path "./.git/*" -exec grep -l 'extends DolibarrModules' {} \; 2>/dev/null | head -1)
if [ -z "$MOD_FILE" ]; then
echo "::error::No mod*.class.php found"
exit 1
fi
echo "Dolibarr module: ${MOD_FILE}"
;;
*)
echo "Generic platform — no manifest validation"
;;
esac
- name: Check update stream format
run: |
PLATFORM="${{ steps.platform.outputs.platform }}"
case "$PLATFORM" in
joomla)
if [ -f "updates.xml" ]; then
if command -v php &> /dev/null; then
php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('updates.xml'); if(!\$x){foreach(libxml_get_errors() as \$e) echo \$e->message; exit(1);}" || { echo "::error::updates.xml is malformed"; exit 1; }
fi
echo "updates.xml valid"
fi
;;
dolibarr)
[ -f "update.txt" ] && echo "update.txt present" || echo "::warning::No update.txt"
;;
esac
- name: Validate Joomla language files
if: steps.platform.outputs.platform == 'joomla'
run: |
ERRORS=0
WARNINGS=0
# Require both en-GB and en-US language directories
LANG_ROOT=$(find . -path "*/language" -type d -not -path "./.git/*" 2>/dev/null | head -1)
if [ -z "$LANG_ROOT" ]; then
echo "No language/ directory found — skipping"
exit 0
fi
if [ ! -d "$LANG_ROOT/en-GB" ]; then
echo "::error::Missing en-GB language directory (${LANG_ROOT}/en-GB)"
ERRORS=$((ERRORS + 1))
fi
if [ ! -d "$LANG_ROOT/en-US" ]; then
echo "::error::Missing en-US language directory (${LANG_ROOT}/en-US)"
ERRORS=$((ERRORS + 1))
fi
# Check that en-GB and en-US have matching .ini files
if [ -d "$LANG_ROOT/en-GB" ] && [ -d "$LANG_ROOT/en-US" ]; then
for GB_INI in "$LANG_ROOT/en-GB"/*.ini; do
[ ! -f "$GB_INI" ] && continue
US_INI="$LANG_ROOT/en-US/$(basename "$GB_INI")"
if [ ! -f "$US_INI" ]; then
echo "::error::$(basename "$GB_INI") exists in en-GB but missing from en-US"
ERRORS=$((ERRORS + 1))
fi
done
for US_INI in "$LANG_ROOT/en-US"/*.ini; do
[ ! -f "$US_INI" ] && continue
GB_INI="$LANG_ROOT/en-GB/$(basename "$US_INI")"
if [ ! -f "$GB_INI" ]; then
echo "::error::$(basename "$US_INI") exists in en-US but missing from en-GB"
ERRORS=$((ERRORS + 1))
fi
done
fi
# Find all .ini language files
INI_FILES=$(find . -path "*/language/*/*.ini" -not -path "./.git/*" 2>/dev/null)
if [ -z "$INI_FILES" ]; then
echo "No .ini language files found"
[ "$ERRORS" -gt 0 ] && exit 1
exit 0
fi
echo "Found $(echo "$INI_FILES" | wc -l) language file(s)"
for FILE in $INI_FILES; do
FNAME=$(basename "$FILE")
LINENUM=0
SEEN_KEYS=""
while IFS= read -r line || [ -n "$line" ]; do
LINENUM=$((LINENUM + 1))
# Skip empty lines and comments
[ -z "$line" ] && continue
echo "$line" | grep -qE '^\s*;' && continue
echo "$line" | grep -qE '^\s*$' && continue
# Must match KEY="VALUE" format
if ! echo "$line" | grep -qE '^[A-Z_][A-Z0-9_]*=".*"$'; then
echo "::error file=${FILE},line=${LINENUM}::Malformed line: ${line}"
ERRORS=$((ERRORS + 1))
continue
fi
# Extract key and check for duplicates
KEY=$(echo "$line" | sed 's/=.*//')
if echo "$SEEN_KEYS" | grep -qx "$KEY"; then
echo "::error file=${FILE},line=${LINENUM}::Duplicate key: ${KEY}"
ERRORS=$((ERRORS + 1))
fi
SEEN_KEYS="${SEEN_KEYS}
${KEY}"
done < "$FILE"
echo " ${FILE}: checked ${LINENUM} lines"
done
# Cross-check en-GB vs en-US key consistency
GB_DIR=$(find . -path "*/language/en-GB" -type d -not -path "./.git/*" 2>/dev/null | head -1)
US_DIR=$(find . -path "*/language/en-US" -type d -not -path "./.git/*" 2>/dev/null | head -1)
if [ -n "$GB_DIR" ] && [ -n "$US_DIR" ]; then
for GB_FILE in "$GB_DIR"/*.ini; do
[ ! -f "$GB_FILE" ] && continue
FNAME=$(basename "$GB_FILE")
US_FILE="$US_DIR/$FNAME"
[ ! -f "$US_FILE" ] && continue
GB_KEYS=$(grep -oP '^[A-Z_][A-Z0-9_]*(?==)' "$GB_FILE" 2>/dev/null | sort)
US_KEYS=$(grep -oP '^[A-Z_][A-Z0-9_]*(?==)' "$US_FILE" 2>/dev/null | sort)
# Keys in en-GB but not en-US
MISSING_US=$(comm -23 <(echo "$GB_KEYS") <(echo "$US_KEYS"))
if [ -n "$MISSING_US" ]; then
echo "::warning::Keys in en-GB/$FNAME but missing from en-US/$FNAME:"
echo "$MISSING_US" | while read -r k; do echo " - $k"; done
WARNINGS=$((WARNINGS + 1))
fi
# Keys in en-US but not en-GB
MISSING_GB=$(comm -13 <(echo "$GB_KEYS") <(echo "$US_KEYS"))
if [ -n "$MISSING_GB" ]; then
echo "::warning::Keys in en-US/$FNAME but missing from en-GB/$FNAME:"
echo "$MISSING_GB" | while read -r k; do echo " - $k"; done
WARNINGS=$((WARNINGS + 1))
fi
done
fi
{
echo "### Language File Validation"
echo "| Metric | Count |"
echo "|---|---|"
echo "| Files checked | $(echo "$INI_FILES" | wc -l) |"
echo "| Errors | ${ERRORS} |"
echo "| Warnings | ${WARNINGS} |"
} >> $GITHUB_STEP_SUMMARY
if [ "$ERRORS" -gt 0 ]; then
echo "::error::Language validation failed with ${ERRORS} error(s)"
exit 1
fi
echo "Language files: OK (${WARNINGS} warning(s))"
- name: Check changelog has unreleased entry
run: |
if [ ! -f "CHANGELOG.md" ]; then
echo "::warning::No CHANGELOG.md found"
exit 0
fi
# Check for content under [Unreleased] section
if ! grep -q "## \[Unreleased\]" CHANGELOG.md; then
echo "::error::CHANGELOG.md missing [Unreleased] section"
exit 1
fi
# Check there's at least one entry (Added/Changed/Fixed/Removed) under Unreleased
UNRELEASED_CONTENT=$(sed -n '/## \[Unreleased\]/,/## \[/p' CHANGELOG.md | grep -cE '^\s*-\s' || true)
if [ "$UNRELEASED_CONTENT" -eq 0 ]; then
echo "::error::CHANGELOG.md [Unreleased] section has no entries. Add a changelog entry describing your changes."
echo "## Changelog Check: Failed" >> $GITHUB_STEP_SUMMARY
echo "The \`[Unreleased]\` section in CHANGELOG.md has no entries." >> $GITHUB_STEP_SUMMARY
echo "Add a line like \`- Description of your change\` under a heading (\`### Added\`, \`### Changed\`, \`### Fixed\`, etc.)" >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "Changelog: ${UNRELEASED_CONTENT} entry/entries in [Unreleased]"
- name: Verify package source
run: |
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
if [ ! -d "$SOURCE_DIR" ]; then
echo "::warning::No src/ or htdocs/ directory"
exit 0
fi
FILE_COUNT=$(find "$SOURCE_DIR" -type f | wc -l)
echo "Source: ${FILE_COUNT} files"
[ "$FILE_COUNT" -gt 0 ] || { echo "::error::Source directory is empty"; exit 1; }
# ── Pre-Release RC Build ─────────────────────────────────────────────────
pre-release:
name: Build RC Package
runs-on: ubuntu-latest
needs: [branch-policy, validate]
steps:
- name: Trigger RC pre-release
env:
GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: ${{ github.head_ref }}
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
run: |
curl -s -X POST "${GITEA_URL}/api/v1/repos/${REPO}/actions/workflows/pre-release.yml/dispatches" -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" -d "{\"ref\":\"${BRANCH}\",\"inputs\":{\"stability\":\"release-candidate\"}}"
echo "### Pre-Release" >> $GITHUB_STEP_SUMMARY
echo "Triggered RC build on branch \`${BRANCH}\`" >> $GITHUB_STEP_SUMMARY
# ── Issue Reporter ──────────────────────────────────────────────────────
report-issues:
name: Report Issues
runs-on: ubuntu-latest
needs: [branch-policy, validate]
if: >-
always() &&
needs.validate.result == 'failure'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
sparse-checkout: automation/ci-issue-reporter.sh
sparse-checkout-cone-mode: false
- name: "File issue for PR validation failure"
env:
GITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
run: |
chmod +x automation/ci-issue-reporter.sh
./automation/ci-issue-reporter.sh \
--gate "PR Validation" \
--workflow "PR Check" \
--severity error \
--details "PR validation failed (syntax, manifest, changelog, or source checks). See the CI run for the specific check that failed."
+29 -3
View File
@@ -17,6 +17,10 @@ on:
types: [closed]
branches:
- dev
pull_request_target:
types: [synchronize, opened, reopened]
branches:
- main
workflow_dispatch:
inputs:
stability:
@@ -43,7 +47,8 @@ jobs:
runs-on: release
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev')
(github.event_name == 'pull_request' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev') ||
(github.event_name == 'pull_request_target' && github.event.pull_request.base.ref == 'main')
steps:
- name: Checkout
@@ -51,6 +56,7 @@ jobs:
with:
fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }}
ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }}
- name: Setup moko-platform tools
env:
@@ -60,7 +66,7 @@ jobs:
if ! command -v composer &> /dev/null; then
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
fi
# Always fetch latest CLI tools never use stale cache from previous runs
# Always fetch latest CLI tools — never use stale cache from previous runs
rm -rf /tmp/moko-platform-api
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
@@ -76,7 +82,12 @@ jobs:
- name: Resolve metadata and bump version
id: meta
run: |
STABILITY="${{ inputs.stability || 'development' }}"
# Auto-detect stability: RC for PRs targeting main, else use input or default to development
if [ "${{ github.event_name }}" = "pull_request_target" ] && [ "${{ github.event.pull_request.base.ref }}" = "main" ]; then
STABILITY="release-candidate"
else
STABILITY="${{ inputs.stability || 'development' }}"
fi
case "$STABILITY" in
development) SUFFIX="-dev"; TAG="development" ;;
@@ -144,6 +155,21 @@ jobs:
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --branch dev --prerelease
- name: Ensure prerelease flag
run: |
TAG="${{ steps.meta.outputs.tag }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
# Get release ID by tag and force prerelease=true
RELEASE_ID=$(curl -s "${API_BASE}/releases/tags/${TAG}" \
-H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" | jq -r '.id // empty')
if [ -n "$RELEASE_ID" ]; then
curl -s -X PATCH "${API_BASE}/releases/${RELEASE_ID}" \
-H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"prerelease": true}'
echo "Marked release ${TAG} (id=${RELEASE_ID}) as prerelease"
fi
- name: Build package and upload
id: package
run: |
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,106 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# BRIEF: Update MokoOnyx submodule in MokoWaas on main and dev branches
name: "Update MokoWaas Submodule"
on:
release:
types: [published]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
WAAS_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
WAAS_REPO: MokoWaaS
# Path where MokoOnyx lives as a submodule inside MokoWaaS
SUBMODULE_PATH: src/packages/tpl_mokoonyx
permissions:
contents: read
jobs:
update-submodule:
name: "Update submodule on ${{ matrix.branch }}"
runs-on: ubuntu-latest
strategy:
matrix:
branch: [main, dev]
fail-fast: false
steps:
- name: Get release info
id: release
run: |
TAG="${{ github.event.release.tag_name }}"
IS_PRE="${{ github.event.release.prerelease }}"
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "prerelease=${IS_PRE}" >> $GITHUB_OUTPUT
echo "Release tag: ${TAG} (prerelease: ${IS_PRE})"
# Skip pre-releases (RC) — only update on stable releases
- name: Skip pre-releases
if: steps.release.outputs.prerelease == 'true'
run: |
echo "Skipping pre-release ${TAG} — only stable releases update MokoWaas"
exit 0
- name: Clone MokoWaas
if: steps.release.outputs.prerelease != 'true'
run: |
git clone --branch "${{ matrix.branch }}" --depth 1 --recurse-submodules \
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${WAAS_ORG}/${WAAS_REPO}.git" \
waas
env:
GIT_TERMINAL_PROMPT: 0
- name: Configure git
if: steps.release.outputs.prerelease != 'true'
working-directory: waas
run: |
git config user.email "gitea-actions[bot]@mokoconsulting.tech"
git config user.name "gitea-actions[bot]"
git remote set-url origin \
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${WAAS_ORG}/${WAAS_REPO}.git"
- name: Update submodule to release tag
if: steps.release.outputs.prerelease != 'true'
working-directory: waas
run: |
TAG="${{ steps.release.outputs.tag }}"
SUBPATH="${SUBMODULE_PATH}"
# Verify submodule exists
if [ ! -f ".gitmodules" ] || ! grep -q "${SUBPATH}" .gitmodules; then
echo "::error::Submodule '${SUBPATH}' not found in .gitmodules on ${{ matrix.branch }}"
exit 1
fi
# Fetch the tag in the submodule and update to it
cd "${SUBPATH}"
git fetch origin "refs/tags/${TAG}:refs/tags/${TAG}" --depth 1
git checkout "${TAG}"
cd -
# Stage the submodule pointer change
git add "${SUBPATH}"
# Only commit if there's actually a change
if git diff --cached --quiet; then
echo "Submodule already at ${TAG} on ${{ matrix.branch }} — nothing to do"
else
git commit -m "chore: update MokoOnyx submodule to ${TAG}
Authored-by: Moko Consulting"
git push origin "${{ matrix.branch }}"
echo "Updated MokoOnyx to ${TAG} on ${{ matrix.branch }}"
fi
- name: Summary
if: always() && steps.release.outputs.prerelease != 'true'
run: |
TAG="${{ steps.release.outputs.tag }}"
echo "## MokoWaas Submodule Update (${{ matrix.branch }})" >> $GITHUB_STEP_SUMMARY
echo "Updated \`${SUBMODULE_PATH}\` to \`${TAG}\`" >> $GITHUB_STEP_SUMMARY
+18 -54
View File
@@ -8,65 +8,29 @@
DEFGROUP: Joomla.Template.Site
INGROUP: MokoOnyx.Documentation
PATH: ./CHANGELOG.md
<<<<<<< HEAD
<<<<<<< HEAD
VERSION: 02.17.00
VERSION: 02.20.00
BRIEF: Changelog file documenting version history of MokoOnyx
-->
# Changelog — MokoOnyx (VERSION: 02.17.00)
# Changelog — MokoOnyx (VERSION: 02.20.00)
## [Unreleased]
=======
VERSION: 02.17.00
BRIEF: Changelog file documenting version history of MokoOnyx
-->
# Changelog — MokoOnyx (VERSION: 02.17.00)
>>>>>>> origin/main
=======
VERSION: 02.17.00
BRIEF: Changelog file documenting version history of MokoOnyx
-->
# Changelog — MokoOnyx (VERSION: 02.17.00)
>>>>>>> origin/main
## [02.17.00] --- 2026-05-30
## [02.15.00] --- 2026-05-30
=======
VERSION: 02.17.00
BRIEF: Changelog file documenting version history of MokoOnyx
-->
# Changelog — MokoOnyx (VERSION: 02.17.00)
>>>>>>> origin/main
## [02.14.00] --- 2026-05-30
## [02.13.00] --- 2026-05-30
### Added
- Hero image (`hero.jpg`) to template images
- `.fa-solid`, `.fa-regular`, `.fa-brands`, `.fa-light` icon margin spacing
- `.blog-item .item-image` fixed 250px height with object-fit cover
- Hide header on home page option (`hideHeaderHome` template param)
- Hide main menu on home page option (`hideMenuHome` template param)
- Three distinct menu overrides: mainmenu (collapsible), horizontal (always visible), default (vertical)
- `<php_minimum>8.1.0</php_minimum>` to templateDetails.xml
- `<changelogurl>` support in updates.xml
- CONTRIBUTING.md with universal workflow and version policy
### Changed
- Release pipeline rework: independent update streams, CLI-driven workflows
- Version bumps only trigger on `src/` changes (not docs/config)
- Branch protection: CI bot only for push, force push disabled
- Auto-bump supports dev, rc, feature/*, patch/* branches
## [02.20.00] --- 2026-06-04
### Fixed
- Joomla update loop caused by version mismatch between ZIP and updates.xml
- Duplicate hamburger menu on mobile
- Stacked version suffixes (-dev-dev-dev)
- Template name doubling (Template - Template - MokoOnyx)
- Strip Joomla-injected `p-2` padding class from Font Awesome icons in all menu overrides (default, mainmenu, horizontal)
## [02.08.00] --- 2026-05-29
### Changed
- Migrated update server URL from raw file endpoint to Gitea Pages
- Release workflow no longer manages updates.xml (decoupled to Gitea Pages)
- Added conflict-marker guard to PR check and release workflows
- Added Joomla language file validation (syntax, duplicates, en-GB/en-US consistency)
- Added JEXEC guard, joomla.asset.json, XML well-formedness, and script file CI checks
- Removed RS_FTP_PATH_SUFFIX from repo health requirements
## [02.20.00] --- 2026-06-04
## [02.18.00] --- 2026-06-02
## [02.15.00] --- 2026-05-30
+161 -161
View File
@@ -1,161 +1,161 @@
# Contributing to Moko Consulting Projects
Thank you for your interest in contributing. All Moko Consulting repositories follow this universal workflow and version policy.
## Branching Workflow
```
feature/* ──PR──> dev ──draft PR──> (renamed to rc) ──merge──> main
```
### Step by step
1. **Create a feature branch** from `dev`:
```bash
git checkout dev && git pull
git checkout -b feature/my-change
```
2. **Work and commit** on your feature branch. Push to origin.
3. **Open a PR**: `feature/my-change` → `dev`. After review and checks, merge it.
4. **When ready for release**, open a **draft PR**: `dev` → `main`.
- This automatically renames the source branch to `rc` (release candidate)
- An RC pre-release is built and uploaded
5. **Alpha and beta branches** are created by manually renaming the branch before the RC stage:
- Rename `dev` to `alpha` for early testing → alpha pre-release is built
- Rename `alpha` to `beta` for feature-complete testing → beta pre-release is built
- When the draft PR is created, the branch is renamed to `rc`
6. **Once PR checks pass** on the `rc` branch, mark the PR as ready and merge to `main`.
7. **Merging to main** triggers the stable release pipeline:
- Minor version bump (e.g., `02.09.xx` → `02.10.00`)
- Stability suffix stripped (clean version)
- Gitea release created with ZIP/tar.gz packages
- `updates.xml` updated (Joomla extensions)
- `dev` branch recreated from `main`
### Branch summary
| Branch | Purpose | Created by |
|--------|---------|-----------|
| `feature/*` | New features and fixes | Developer |
| `dev` | Integration branch | Auto-recreated after release |
| `alpha` | Alpha pre-release testing | Manual rename from `dev` |
| `beta` | Beta pre-release testing | Manual rename from `alpha` |
| `rc` | Release candidate | Auto-renamed on draft PR to main |
| `main` | Stable releases | Protected, merge only |
| `version/XX.YY.ZZ` | Archived release snapshots | Auto-created by CI |
### Protected branches
| Branch | Direct push | Merge via |
|--------|------------|-----------|
| `main` | Blocked (CI bot whitelisted) | PR merge only |
| `dev` | Blocked (CI bot whitelisted) | PR merge from feature/* |
| `rc` | Blocked (CI bot whitelisted) | Auto-created on draft PR |
| `alpha` | Blocked (CI bot whitelisted) | Manual rename |
| `beta` | Blocked (CI bot whitelisted) | Manual rename |
| `feature/*` | Open | N/A (source branch) |
## Version Policy
### Format
All versions use `XX.YY.ZZ` — three two-digit segments, zero-padded:
- **XX** — Major version (breaking changes)
- **YY** — Minor version (new features, bumped on release to main)
- **ZZ** — Patch version (auto-incremented on every push to dev/feature branches)
Rollover: patch `99` → `00` increments minor; minor `99` → `00` increments major.
### Stability suffixes
Each branch appends a suffix to indicate stability:
| Branch | Suffix | Example |
|--------|--------|---------|
| `main` | (none) | `02.09.00` |
| `dev` | `-dev` | `02.09.01-dev` |
| `feature/*` | `-dev` | `02.09.01-dev` |
| `alpha` | `-alpha` | `02.09.01-alpha` |
| `beta` | `-beta` | `02.09.01-beta` |
| `rc` | `-rc` | `02.09.01-rc` |
### Auto version bump
On every push to `dev`, `feature/*`, or `patch/*`:
1. Patch version incremented
2. Stability suffix `-dev` applied
3. All version-bearing files updated (manifests, CHANGELOG, PHP headers, etc.)
4. Commit created with `[skip ci]` to avoid loops
### Release version flow
Version bumps happen at specific release events:
| Event | Bump | Example |
|-------|------|---------|
| Feature merged to dev | Patch bump after dev release | `02.09.01-dev` → release → `02.09.02-dev` |
| Dev promoted to RC | Minor bump | `02.09.02-dev` → `02.10.00-rc` |
| RC merged to main | Minor bump | `02.10.00-rc` → `02.11.00` (stable) |
| Dev recreated from main | Patch bump | `02.11.00` → `02.11.01-dev` |
### Release stream copies
When a higher-stability release is published, copies are created for all lesser streams with the same base version:
- **RC `02.10.00-rc`** also creates: `02.10.00-dev`, `02.10.00-alpha`, `02.10.00-beta`
- **Stable `02.11.00`** also creates: `02.11.00-dev`, `02.11.00-alpha`, `02.11.00-beta`, `02.11.00-rc`
This ensures Joomla sites on ANY stability channel see the update (Joomla only shows versions higher than what's installed).
### Version files
The version tools update all files containing version stamps:
- `.mokogitea/manifest.xml` (canonical source)
- Joomla XML manifests (`<version>` tag)
- `README.md`, `CHANGELOG.md` (`VERSION:` pattern)
- `package.json`, `pyproject.toml`
- Any text file with a `VERSION: XX.YY.ZZ` label
Files synced from other repos (with a `# REPO:` header) are not touched.
## Code Standards
- **PHP**: PSR-12, tabs for indentation
- **Copyright**: all files must include the Moko Consulting copyright header
- **License**: SPDX identifier `GPL-3.0-or-later` (or as specified per repo)
- **Attribution**: use `Authored-by: Moko Consulting` in commits, not individual names
## Commit Messages
Use conventional commit format:
```
type(scope): short description
Optional body with context.
Authored-by: Moko Consulting
```
Types: `feat`, `fix`, `chore`, `docs`, `style`, `refactor`, `test`, `ci`
Special flags in commit messages:
- `[skip ci]` — skip all CI workflows
- `[skip bump]` — skip auto version bump only
## Reporting Issues
Use the repository's issue tracker with the appropriate template.
---
*Moko Consulting <hello@mokoconsulting.tech>*
# Contributing to Moko Consulting Projects
Thank you for your interest in contributing. All Moko Consulting repositories follow this universal workflow and version policy.
## Branching Workflow
```
feature/* ──PR──> dev ──draft PR──> (renamed to rc) ──merge──> main
```
### Step by step
1. **Create a feature branch** from `dev`:
```bash
git checkout dev && git pull
git checkout -b feature/my-change
```
2. **Work and commit** on your feature branch. Push to origin.
3. **Open a PR**: `feature/my-change` → `dev`. After review and checks, merge it.
4. **When ready for release**, open a **draft PR**: `dev` → `main`.
- This automatically renames the source branch to `rc` (release candidate)
- An RC pre-release is built and uploaded
5. **Alpha and beta branches** are created by manually renaming the branch before the RC stage:
- Rename `dev` to `alpha` for early testing → alpha pre-release is built
- Rename `alpha` to `beta` for feature-complete testing → beta pre-release is built
- When the draft PR is created, the branch is renamed to `rc`
6. **Once PR checks pass** on the `rc` branch, mark the PR as ready and merge to `main`.
7. **Merging to main** triggers the stable release pipeline:
- Minor version bump (e.g., `02.09.xx` → `02.10.00`)
- Stability suffix stripped (clean version)
- Gitea release created with ZIP/tar.gz packages
- `updates.xml` updated (Joomla extensions)
- `dev` branch recreated from `main`
### Branch summary
| Branch | Purpose | Created by |
|--------|---------|-----------|
| `feature/*` | New features and fixes | Developer |
| `dev` | Integration branch | Auto-recreated after release |
| `alpha` | Alpha pre-release testing | Manual rename from `dev` |
| `beta` | Beta pre-release testing | Manual rename from `alpha` |
| `rc` | Release candidate | Auto-renamed on draft PR to main |
| `main` | Stable releases | Protected, merge only |
| `version/XX.YY.ZZ` | Archived release snapshots | Auto-created by CI |
### Protected branches
| Branch | Direct push | Merge via |
|--------|------------|-----------|
| `main` | Blocked (CI bot whitelisted) | PR merge only |
| `dev` | Blocked (CI bot whitelisted) | PR merge from feature/* |
| `rc` | Blocked (CI bot whitelisted) | Auto-created on draft PR |
| `alpha` | Blocked (CI bot whitelisted) | Manual rename |
| `beta` | Blocked (CI bot whitelisted) | Manual rename |
| `feature/*` | Open | N/A (source branch) |
## Version Policy
### Format
All versions use `XX.YY.ZZ` — three two-digit segments, zero-padded:
- **XX** — Major version (breaking changes)
- **YY** — Minor version (new features, bumped on release to main)
- **ZZ** — Patch version (auto-incremented on every push to dev/feature branches)
Rollover: patch `99` → `00` increments minor; minor `99` → `00` increments major.
### Stability suffixes
Each branch appends a suffix to indicate stability:
| Branch | Suffix | Example |
|--------|--------|---------|
| `main` | (none) | `02.09.00` |
| `dev` | `-dev` | `02.09.01-dev` |
| `feature/*` | `-dev` | `02.09.01-dev` |
| `alpha` | `-alpha` | `02.09.01-alpha` |
| `beta` | `-beta` | `02.09.01-beta` |
| `rc` | `-rc` | `02.09.01-rc` |
### Auto version bump
On every push to `dev`, `feature/*`, or `patch/*`:
1. Patch version incremented
2. Stability suffix `-dev` applied
3. All version-bearing files updated (manifests, CHANGELOG, PHP headers, etc.)
4. Commit created with `[skip ci]` to avoid loops
### Release version flow
Version bumps happen at specific release events:
| Event | Bump | Example |
|-------|------|---------|
| Feature merged to dev | Patch bump after dev release | `02.09.01-dev` → release → `02.09.02-dev` |
| Dev promoted to RC | Minor bump | `02.09.02-dev` → `02.10.00-rc` |
| RC merged to main | Minor bump | `02.10.00-rc` → `02.11.00` (stable) |
| Dev recreated from main | Patch bump | `02.11.00` → `02.11.01-dev` |
### Release stream copies
When a higher-stability release is published, copies are created for all lesser streams with the same base version:
- **RC `02.10.00-rc`** also creates: `02.10.00-dev`, `02.10.00-alpha`, `02.10.00-beta`
- **Stable `02.11.00`** also creates: `02.11.00-dev`, `02.11.00-alpha`, `02.11.00-beta`, `02.11.00-rc`
This ensures Joomla sites on ANY stability channel see the update (Joomla only shows versions higher than what's installed).
### Version files
The version tools update all files containing version stamps:
- `.mokogitea/manifest.xml` (canonical source)
- Joomla XML manifests (`<version>` tag)
- `README.md`, `CHANGELOG.md` (`VERSION:` pattern)
- `package.json`, `pyproject.toml`
- Any text file with a `VERSION: XX.YY.ZZ` label
Files synced from other repos (with a `# REPO:` header) are not touched.
## Code Standards
- **PHP**: PSR-12, tabs for indentation
- **Copyright**: all files must include the Moko Consulting copyright header
- **License**: SPDX identifier `GPL-3.0-or-later` (or as specified per repo)
- **Attribution**: use `Authored-by: Moko Consulting` in commits, not individual names
## Commit Messages
Use conventional commit format:
```
type(scope): short description
Optional body with context.
Authored-by: Moko Consulting
```
Types: `feat`, `fix`, `chore`, `docs`, `style`, `refactor`, `test`, `ci`
Special flags in commit messages:
- `[skip ci]` — skip all CI workflows
- `[skip bump]` — skip auto version bump only
## Reporting Issues
Use the repository's issue tracker with the appropriate template.
---
*Moko Consulting <hello@mokoconsulting.tech>*
+1 -11
View File
@@ -10,17 +10,7 @@
INGROUP: MokoOnyx.Governance
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
FILE: SECURITY.md
<<<<<<< HEAD
<<<<<<< HEAD
VERSION: 02.17.00
=======
VERSION: 02.17.00
=======
VERSION: 02.17.00
=======
VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
VERSION: 02.20.00
BRIEF: Security policy and vulnerability reporting process for MokoOnyx.
PATH: /SECURITY.md
NOTE: This policy is process oriented and does not replace secure engineering practices.
+237
View File
@@ -0,0 +1,237 @@
#!/usr/bin/env bash
# ============================================================================
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Automation.CI
# INGROUP: moko-platform.Automation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /automation/ci-issue-reporter.sh
# VERSION: 09.23.00
# BRIEF: Creates or updates a Gitea issue when a CI gate fails.
# Deduplicates by searching open issues with the "ci-auto" label
# whose title matches the gate. If a matching issue exists, a comment
# is appended instead of opening a duplicate.
# ============================================================================
set -euo pipefail
# ── Defaults ────────────────────────────────────────────────────────────────
GITEA_URL="${GITEA_URL:-https://git.mokoconsulting.tech}"
GITEA_TOKEN="${GITEA_TOKEN:-}"
REPO="${GITHUB_REPOSITORY:-}"
RUN_URL="${GITHUB_SERVER_URL:-${GITEA_URL}}/${REPO}/actions/runs/${GITHUB_RUN_ID:-0}"
LABEL_NAME="ci-auto"
LABEL_COLOR="#e11d48"
GATE=""
DETAILS=""
SEVERITY="error"
WORKFLOW=""
# ── Parse arguments ─────────────────────────────────────────────────────────
usage() {
cat <<EOF
Usage: ci-issue-reporter.sh --gate NAME --details TEXT [OPTIONS]
Required:
--gate CI gate name (e.g. "Code Quality", "Self-Health")
--details Human-readable failure description
Optional:
--severity "error" (default) or "warning"
--workflow Workflow name for the issue title
--repo owner/repo (default: \$GITHUB_REPOSITORY)
--run-url URL to the CI run (auto-detected from env)
--token Gitea API token (default: \$GITEA_TOKEN)
--url Gitea base URL (default: \$GITEA_URL)
EOF
exit 1
}
while [[ $# -gt 0 ]]; do
case "$1" in
--gate) GATE="$2"; shift 2 ;;
--details) DETAILS="$2"; shift 2 ;;
--severity) SEVERITY="$2"; shift 2 ;;
--workflow) WORKFLOW="$2"; shift 2 ;;
--repo) REPO="$2"; shift 2 ;;
--run-url) RUN_URL="$2"; shift 2 ;;
--token) GITEA_TOKEN="$2"; shift 2 ;;
--url) GITEA_URL="$2"; shift 2 ;;
-h|--help) usage ;;
*) echo "Unknown option: $1"; usage ;;
esac
done
[[ -z "$GATE" ]] && { echo "ERROR: --gate is required"; usage; }
[[ -z "$DETAILS" ]] && { echo "ERROR: --details is required"; usage; }
[[ -z "$GITEA_TOKEN" ]] && { echo "ERROR: GITEA_TOKEN not set"; exit 1; }
[[ -z "$REPO" ]] && { echo "ERROR: GITHUB_REPOSITORY not set"; exit 1; }
API="${GITEA_URL}/api/v1/repos/${REPO}"
# ── Build title ─────────────────────────────────────────────────────────────
if [[ -n "$WORKFLOW" ]]; then
TITLE="[CI] ${WORKFLOW}: ${GATE} failed"
else
TITLE="[CI] ${GATE} failed"
fi
# ── Ensure label exists ─────────────────────────────────────────────────────
ensure_label() {
local exists
exists=$(curl -sf -o /dev/null -w '%{http_code}' \
-H "Authorization: token ${GITEA_TOKEN}" \
"${API}/labels" 2>/dev/null || echo "000")
if [[ "$exists" == "200" ]]; then
# Check if label already exists
local found
found=$(curl -sf \
-H "Authorization: token ${GITEA_TOKEN}" \
"${API}/labels" 2>/dev/null \
| grep -o "\"name\":\"${LABEL_NAME}\"" || true)
if [[ -z "$found" ]]; then
curl -sf -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/labels" \
-d "{\"name\":\"${LABEL_NAME}\",\"color\":\"${LABEL_COLOR}\",\"description\":\"Auto-created by CI issue reporter\"}" \
> /dev/null 2>&1 || true
fi
fi
}
# ── Search for existing open issue ──────────────────────────────────────────
find_existing_issue() {
# URL-encode the gate name for the query
local query
query=$(printf '%s' "[CI] ${GATE}" | sed 's/ /%20/g; s/\[/%5B/g; s/\]/%5D/g')
local response
response=$(curl -sf \
-H "Authorization: token ${GITEA_TOKEN}" \
"${API}/issues?type=issues&state=open&labels=${LABEL_NAME}&q=${query}&limit=5" \
2>/dev/null || echo "[]")
# Extract the first matching issue number
echo "$response" \
| grep -oP '"number":\s*\K[0-9]+' \
| head -1
}
# ── Build issue body ────────────────────────────────────────────────────────
build_body() {
local severity_badge
if [[ "$SEVERITY" == "error" ]]; then
severity_badge="**Severity:** Error"
else
severity_badge="**Severity:** Warning"
fi
cat <<BODY
## CI Gate Failure: ${GATE}
${severity_badge}
**Workflow:** ${WORKFLOW:-unknown}
**Branch:** ${GITHUB_REF_NAME:-unknown}
**Commit:** \`${GITHUB_SHA:0:8}\`
**Run:** [View CI run](${RUN_URL})
### Details
${DETAILS}
### Resolution
Fix the issue described above and push a new commit. This issue will be closed automatically when the gate passes, or can be closed manually.
---
*Auto-created by [ci-issue-reporter](${GITEA_URL}/${REPO}/src/branch/main/automation/ci-issue-reporter.sh)*
BODY
}
# ── Build comment body (for existing issues) ────────────────────────────────
build_comment() {
cat <<COMMENT
### CI failure recurrence
**Branch:** ${GITHUB_REF_NAME:-unknown}
**Commit:** \`${GITHUB_SHA:0:8}\`
**Run:** [View CI run](${RUN_URL})
${DETAILS}
COMMENT
}
# ── Main ────────────────────────────────────────────────────────────────────
ensure_label
EXISTING=$(find_existing_issue)
if [[ -n "$EXISTING" ]]; then
# Append comment to existing issue
COMMENT_BODY=$(build_comment)
COMMENT_JSON=$(printf '%s' "$COMMENT_BODY" | python3 -c "
import sys, json
print(json.dumps({'body': sys.stdin.read()}))" 2>/dev/null)
HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues/${EXISTING}/comments" \
-d "${COMMENT_JSON}" 2>/dev/null || echo "000")
if [[ "$HTTP" == "201" ]]; then
echo "Commented on existing issue #${EXISTING}"
else
echo "WARNING: Failed to comment on issue #${EXISTING} (HTTP ${HTTP})"
fi
else
# Create new issue
ISSUE_BODY=$(build_body)
ISSUE_JSON=$(python3 -c "
import sys, json
body = sys.stdin.read()
print(json.dumps({
'title': sys.argv[1],
'body': body,
'labels': []
}))" "$TITLE" <<< "$ISSUE_BODY" 2>/dev/null)
# Create the issue
RESPONSE=$(curl -sf -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues" \
-d "${ISSUE_JSON}" 2>/dev/null || echo "{}")
ISSUE_NUM=$(echo "$RESPONSE" | grep -oP '"number":\s*\K[0-9]+' | head -1)
if [[ -n "$ISSUE_NUM" ]]; then
# Apply label (separate call — more reliable across Gitea versions)
LABEL_ID=$(curl -sf \
-H "Authorization: token ${GITEA_TOKEN}" \
"${API}/labels" 2>/dev/null \
| grep -oP "\"id\":\s*\K[0-9]+(?=[^}]*\"name\":\s*\"${LABEL_NAME}\")" \
| head -1 || true)
if [[ -n "$LABEL_ID" ]]; then
curl -sf -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues/${ISSUE_NUM}/labels" \
-d "{\"labels\":[${LABEL_ID}]}" \
> /dev/null 2>&1 || true
fi
echo "Created issue #${ISSUE_NUM}: ${TITLE}"
else
echo "WARNING: Failed to create issue"
echo "Response: ${RESPONSE}"
fi
fi
+1 -1
View File
@@ -161,7 +161,7 @@ class MokoMinifyHelper
$js = preg_replace('/\s*([{}();,=+\-*\/<>!&|?:])\s*/', '$1', $js);
// Restore necessary spaces (after keywords)
$js = preg_replace('/(var|let|const|return|typeof|instanceof|new|delete|throw|case|in|of)([^\s;})><=!&|?:,])/', '$1 $2', $js);
$js = preg_replace('/\b(var|let|const|return|typeof|instanceof|new|delete|throw|case|in|of)\b([^\s;})><=!&|?:,])/', '$1 $2', $js);
return trim($js);
}
@@ -1,61 +0,0 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoOnyx.Override
* INGROUP: MokoOnyx
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /html/com_joomgallery/category/default.php
<<<<<<< HEAD
<<<<<<< HEAD
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
* BRIEF: Category view override — password gate then loads default_cat sub-layout
*/
// No direct access
defined('_JEXEC') or die;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Language\Text;
use Joomla\CMS\HTML\HTMLHelper;
// Import CSS & JS
$wa = $this->document->getWebAssetManager();
$wa->useStyle('com_joomgallery.site');
$wa->useStyle('com_joomgallery.jg-icon-font');
?>
<?php if ($this->item->pw_protected) : ?>
<div class="com-joomgallery-category--locked">
<form action="<?php echo Route::_('index.php?task=category.unlock&catid=' . $this->item->id); ?>" method="post" class="row g-3 align-items-end" autocomplete="off">
<div class="col-12">
<h3><i class="jg-icon-lock me-2" aria-hidden="true"></i><?php echo Text::_('COM_JOOMGALLERY_CATEGORY_PASSWORD_PROTECTED'); ?></h3>
</div>
<div class="col-auto">
<label for="jg_password" class="form-label"><?php echo Text::_('JGLOBAL_PASSWORD'); ?></label>
<input type="password" name="password" id="jg_password" class="form-control" required />
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary" id="jg_unlock_button">
<i class="jg-icon-unlock me-1" aria-hidden="true"></i><?php echo Text::_('COM_JOOMGALLERY_CATEGORY_BUTTON_UNLOCK'); ?>
</button>
</div>
<?php echo HTMLHelper::_('form.token'); ?>
</form>
</div>
<?php else : ?>
<?php echo $this->loadTemplate('cat'); ?>
<?php endif; ?>
@@ -1,229 +0,0 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoOnyx.Override
* INGROUP: MokoOnyx
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /html/com_joomgallery/category/default_cat.php
<<<<<<< HEAD
<<<<<<< HEAD
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
* BRIEF: Category sub-layout — subcategories grid + images grid with pagination
*/
// No direct access
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Session\Session;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Layout\LayoutHelper;
use Joomgallery\Component\Joomgallery\Administrator\Helper\JoomHelper;
// Image params
$image_type = $this->params['configs']->get('jg_category_view_type_image', 'thumbnail', 'STRING');
$gallery_class = $this->params['configs']->get('jg_category_view_class', 'masonry', 'STRING');
$num_columns = $this->params['configs']->get('jg_category_view_num_columns', 3, 'INT');
$image_class = $this->params['configs']->get('jg_category_view_image_class', 0, 'INT');
$justified_height = $this->params['configs']->get('jg_category_view_justified_height', 200, 'INT');
$justified_gap = $this->params['configs']->get('jg_category_view_justified_gap', 5, 'INT');
$image_link = $this->params['configs']->get('jg_category_view_image_link', 'defaultview', 'STRING');
$lightbox_image = $this->params['configs']->get('jg_category_view_lightbox_image', 'detail', 'STRING');
$pagination_type = $this->params['configs']->get('jg_category_view_pagination', 0, 'INT');
$show_subcategories = $this->params['configs']->get('jg_category_view_subcategories', 1, 'INT');
$subcategory_type_image = $this->params['configs']->get('jg_category_view_type_subcategory_image', 'thumbnail', 'STRING');
$num_columns_subcats = $this->params['configs']->get('jg_category_view_subcategories_num_columns', 3, 'INT');
// Import CSS & JS
$wa = $this->document->getWebAssetManager();
if ($gallery_class == 'masonry') {
$wa->useScript('com_joomgallery.masonry');
}
if ($gallery_class == 'justified') {
$wa->useScript('com_joomgallery.justified');
$wa->addInlineStyle('.jg-images[class*=" justified-"] .jg-image-caption-hover { right: ' . $justified_gap . 'px; }');
}
$lightbox = false;
if ($image_link == 'lightgallery') {
$lightbox = true;
$wa->useScript('com_joomgallery.lightgallery');
$wa->useScript('com_joomgallery.lg-thumbnail');
$wa->useStyle('com_joomgallery.lightgallery-bundle');
}
// Initialise the grid script
$iniJS = 'window.joomGrid = {';
$iniJS .= ' itemid: ' . $this->item->id . ',';
$iniJS .= ' pagination: ' . $pagination_type . ',';
$iniJS .= ' layout: "' . $gallery_class . '",';
$iniJS .= ' num_columns: ' . $num_columns . ',';
$iniJS .= ' lightbox: ' . ($lightbox ? 'true' : 'false') . ',';
$iniJS .= ' justified: {height: ' . $justified_height . ', gap: ' . $justified_gap . '}';
$iniJS .= '};';
$wa->addInlineScript($iniJS, ['position' => 'before'], [], ['com_joomgallery.joomgrid']);
$wa->useScript('com_joomgallery.joomgrid');
// Access check
$canEdit = $this->getAcl()->checkACL('edit', 'com_joomgallery.category', $this->item->id, $this->item->parent_id, true);
$canAdd = $this->getAcl()->checkACL('add', 'com_joomgallery.image', 0, $this->item->id, true);
$canDelete = $this->getAcl()->checkACL('delete', 'com_joomgallery.category', $this->item->id, $this->item->parent_id, true);
$canCheckin = $this->getAcl()->checkACL('editstate', 'com_joomgallery.category', $this->item->id, $this->item->parent_id, true) || $this->item->checked_out == Factory::getUser()->id;
$returnURL = base64_encode(JoomHelper::getViewRoute('category', $this->item->id, $this->item->parent_id, $this->item->language, $this->getLayout()));
$hasSubcats = $show_subcategories && !empty($this->item->children->items) && count($this->item->children->items) > 0;
$hasImages = !empty($this->item->images->items) && count($this->item->images->items) > 0;
?>
<div class="com-joomgallery-category" itemscope itemtype="https://schema.org/ImageGallery">
<?php // Page heading ?>
<?php if ($this->params['menu']->get('show_page_heading')) : ?>
<div class="page-header">
<h1><?php echo $this->escape($this->params['menu']->get('page_heading')); ?></h1>
</div>
<?php endif; ?>
<?php // Category title ?>
<h2 itemprop="name"><?php echo $this->escape($this->item->title); ?></h2>
<?php // Category description ?>
<?php if (!empty($this->item->description)) : ?>
<div class="com-joomgallery-category__description mb-3" itemprop="description">
<?php echo $this->item->description; ?>
</div>
<?php endif; ?>
<?php // Admin buttons ?>
<?php if ($canEdit || $canCheckin || $canAdd || $canDelete) : ?>
<div class="com-joomgallery-category__actions btn-toolbar mb-3" role="toolbar" aria-label="<?php echo Text::_('JTOOLBAR'); ?>">
<?php if ($canCheckin && $this->item->checked_out > 0) : ?>
<a class="btn btn-outline-secondary btn-sm me-2" href="<?php echo Route::_('index.php?option=com_joomgallery&task=category.checkin&id=' . $this->item->id . '&return=' . $returnURL . '&' . Session::getFormToken() . '=1'); ?>">
<i class="jg-icon-checkin me-1" aria-hidden="true"></i><?php echo Text::_('JLIB_HTML_CHECKIN'); ?>
</a>
<?php endif; ?>
<?php if ($canEdit) : ?>
<a class="btn btn-outline-primary btn-sm me-2<?php echo ($this->item->checked_out > 0) ? ' disabled' : ''; ?>" href="<?php echo Route::_('index.php?option=com_joomgallery&task=category.edit&id=' . $this->item->id . '&return=' . $returnURL); ?>">
<i class="jg-icon-edit me-1" aria-hidden="true"></i><?php echo Text::_('JGLOBAL_EDIT'); ?>
</a>
<?php endif; ?>
<?php if ($canAdd) : ?>
<a class="btn btn-outline-success btn-sm me-2<?php echo ($this->item->checked_out > 0) ? ' disabled' : ''; ?>" href="<?php echo Route::_('index.php?option=com_joomgallery&task=image.add&catid=' . $this->item->id . '&return=' . $returnURL); ?>">
<i class="jg-icon-upload me-1" aria-hidden="true"></i><?php echo Text::_('COM_JOOMGALLERY_IMG_UPLOAD_IMAGE'); ?>
</a>
<?php endif; ?>
<?php if ($canDelete) : ?>
<a class="btn btn-outline-danger btn-sm<?php echo ($this->item->checked_out > 0) ? ' disabled' : ''; ?>" href="#deleteCatModal" role="button" data-bs-toggle="modal">
<i class="jg-icon-delete me-1" aria-hidden="true"></i><?php echo Text::_('JACTION_DELETE'); ?>
</a>
<?php echo HTMLHelper::_(
'bootstrap.renderModal',
'deleteCatModal',
[
'title' => Text::_('JACTION_DELETE'),
'modalWidth' => '50',
'bodyHeight' => '100',
'footer' => '<button class="btn btn-secondary" data-bs-dismiss="modal">' . Text::_('JCANCEL') . '</button>'
. '<a href="' . Route::_('index.php?option=com_joomgallery&task=category.remove&id=' . $this->item->id . '&return=' . $returnURL . '&' . Session::getFormToken() . '=1', false, 2) . '" class="btn btn-danger">' . Text::_('JACTION_DELETE') . '</a>',
],
Text::_('COM_JOOMGALLERY_COMMON_ALERT_SURE_DELETE_SELECTED_ITEM')
); ?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php // Subcategories ?>
<?php if ($hasSubcats) : ?>
<section class="com-joomgallery-category__subcategories mb-4" aria-label="<?php echo Text::_('COM_JOOMGALLERY_SUBCATEGORIES'); ?>">
<h3><?php echo Text::_('COM_JOOMGALLERY_SUBCATEGORIES'); ?></h3>
<?php
$catsData = [
'id' => (int) $this->item->id,
'items' => $this->item->children->items,
'num_columns' => (int) $num_columns_subcats,
'image_type' => $subcategory_type_image,
];
echo LayoutHelper::render('joomgallery.grids.categories', $catsData);
?>
</section>
<?php endif; ?>
<?php // Images ?>
<?php if ($hasImages) : ?>
<section class="com-joomgallery-category__images" aria-label="<?php echo Text::_('COM_JOOMGALLERY_IMAGES'); ?>">
<?php if ($hasSubcats) : ?>
<h3><?php echo Text::_('COM_JOOMGALLERY_IMAGES'); ?></h3>
<?php endif; ?>
<?php
$imgsData = [
'id' => (int) $this->item->id,
'layout' => $gallery_class,
'items' => $this->item->images->items,
'num_columns' => (int) $num_columns,
'caption_align' => 'center',
'image_class' => $image_class,
'image_type' => $image_type,
'lightbox_type' => $lightbox_image,
'image_link' => $image_link,
'image_title' => false,
'title_link' => 'defaultview',
'image_desc' => false,
'image_date' => false,
'image_author' => false,
'image_tags' => false,
];
echo LayoutHelper::render('joomgallery.grids.images', $imgsData);
?>
<?php // Pagination ?>
<nav class="mt-4" aria-label="<?php echo Text::_('JLIB_HTML_PAGINATION'); ?>">
<?php echo $this->item->images->pagination->getListFooter(); ?>
</nav>
</section>
<?php elseif (!$hasSubcats) : ?>
<div class="alert alert-info" role="alert">
<p class="mb-0"><?php echo Text::_('COM_JOOMGALLERY_GALLERY_NO_IMAGES'); ?></p>
</div>
<?php endif; ?>
<?php // Back to parent category ?>
<?php if ($this->item->parent_id > 0 && $this->item->parent_id != 1) : ?>
<div class="mt-4">
<a class="btn btn-outline-secondary" href="<?php echo Route::_('index.php?option=com_joomgallery&view=category&id=' . (int) $this->item->parent_id); ?>">
<i class="jg-icon-arrow-left-alt me-1" aria-hidden="true"></i><?php echo Text::_('COM_JOOMGALLERY_BACK'); ?>
</a>
</div>
<?php endif; ?>
<script>
if (window.joomGrid.layout != 'justified') {
document.querySelectorAll('.' + window.joomGrid.imgclass).forEach(function(image) {
image.addEventListener('load', function() {
this.closest('.' + window.joomGrid.imgboxclass).classList.add('loaded');
});
});
}
</script>
</div>
@@ -1 +0,0 @@
<!DOCTYPE html><title></title>
@@ -1,148 +0,0 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoOnyx.Override
* INGROUP: MokoOnyx
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /html/com_joomgallery/gallery/default.php
<<<<<<< HEAD
<<<<<<< HEAD
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
* BRIEF: Gallery view override — main image grid with masonry/justified layout
*/
// No direct access
defined('_JEXEC') or die;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
// Image params
$image_type = $this->params['configs']->get('jg_gallery_view_type_image', 'thumbnail', 'STRING');
$gallery_class = $this->params['configs']->get('jg_gallery_view_class', 'masonry', 'STRING');
$num_columns = $this->params['configs']->get('jg_gallery_view_num_columns', 3, 'INT');
$image_class = $this->params['configs']->get('jg_gallery_view_image_class', 0, 'INT');
$justified_height = $this->params['configs']->get('jg_gallery_view_justified_height', 200, 'INT');
$justified_gap = $this->params['configs']->get('jg_gallery_view_justified_gap', 5, 'INT');
$image_link = $this->params['configs']->get('jg_gallery_view_image_link', 'defaultview', 'STRING');
$lightbox_image = $this->params['configs']->get('jg_category_view_lightbox_image', 'detail', 'STRING');
$browse_categories_link = $this->params['configs']->get('jg_gallery_view_browse_categories_link', 1, 'INT');
// Import CSS & JS
$wa = $this->document->getWebAssetManager();
$wa->useStyle('com_joomgallery.site');
$wa->useStyle('com_joomgallery.jg-icon-font');
if ($gallery_class == 'masonry') {
$wa->useScript('com_joomgallery.masonry');
}
if ($gallery_class == 'justified') {
$wa->useScript('com_joomgallery.justified');
$wa->addInlineStyle('.jg-images[class*=" justified-"] .jg-image-caption-hover { right: ' . $justified_gap . 'px; }');
}
$lightbox = false;
if ($image_link == 'lightgallery') {
$lightbox = true;
$wa->useScript('com_joomgallery.lightgallery');
$wa->useScript('com_joomgallery.lg-thumbnail');
$wa->useStyle('com_joomgallery.lightgallery-bundle');
}
// Initialise the grid script
$iniJS = 'window.joomGrid = {';
$iniJS .= ' itemid: ' . $this->item->id . ',';
$iniJS .= ' pagination: 0,';
$iniJS .= ' layout: "' . $gallery_class . '",';
$iniJS .= ' num_columns: ' . $num_columns . ',';
$iniJS .= ' lightbox: ' . ($lightbox ? 'true' : 'false') . ',';
$iniJS .= ' justified: {height: ' . $justified_height . ', gap: ' . $justified_gap . '}';
$iniJS .= '};';
$wa->addInlineScript($iniJS, ['position' => 'before'], [], ['com_joomgallery.joomgrid']);
$wa->useScript('com_joomgallery.joomgrid');
?>
<div class="com-joomgallery-gallery" itemscope itemtype="https://schema.org/ImageGallery">
<?php if ($this->params['menu']->get('show_page_heading')) : ?>
<div class="page-header">
<h1><?php echo $this->escape($this->params['menu']->get('page_heading')); ?></h1>
</div>
<?php endif; ?>
<?php // Browse categories link (top) ?>
<?php if ($browse_categories_link == '1') : ?>
<div class="text-center mb-4">
<a class="btn btn-outline-primary" href="<?php echo Route::_('index.php?option=com_joomgallery&view=category&id=1'); ?>">
<i class="jg-icon-folder me-1" aria-hidden="true"></i><?php echo Text::_('COM_JOOMGALLERY_GALLERY_VIEW_BROWSE_CATEGORIES'); ?>
</a>
</div>
<?php endif; ?>
<?php if (count($this->item->images->items) == 0) : ?>
<div class="alert alert-info" role="alert">
<p class="mb-0"><?php echo Text::_('COM_JOOMGALLERY_GALLERY_NO_IMAGES'); ?></p>
</div>
<?php else : ?>
<?php
$imgsData = [
'id' => (int) $this->item->id,
'layout' => $gallery_class,
'items' => $this->item->images->items,
'num_columns' => (int) $num_columns,
'caption_align' => 'center',
'image_class' => $image_class,
'image_type' => $image_type,
'lightbox_type' => $lightbox_image,
'image_link' => $image_link,
'image_title' => false,
'title_link' => 'defaultview',
'image_desc' => false,
'image_date' => false,
'image_author' => false,
'image_tags' => false,
];
?>
<?php echo LayoutHelper::render('joomgallery.grids.images', $imgsData); ?>
<?php // Pagination ?>
<nav class="mt-4" aria-label="<?php echo Text::_('JLIB_HTML_PAGINATION'); ?>">
<?php echo $this->item->images->pagination->getListFooter(); ?>
</nav>
<?php endif; ?>
<?php // Browse categories link (bottom) ?>
<?php if ($browse_categories_link == '2') : ?>
<div class="text-center mt-4">
<a class="btn btn-outline-primary" href="<?php echo Route::_('index.php?option=com_joomgallery&view=category&id=1'); ?>">
<i class="jg-icon-folder me-1" aria-hidden="true"></i><?php echo Text::_('COM_JOOMGALLERY_GALLERY_VIEW_BROWSE_CATEGORIES'); ?>
</a>
</div>
<?php endif; ?>
<script>
if (window.joomGrid.layout != 'justified') {
document.querySelectorAll('.' + window.joomGrid.imgclass).forEach(function(image) {
image.addEventListener('load', function() {
this.closest('.' + window.joomGrid.imgboxclass).classList.add('loaded');
});
});
}
</script>
</div>
@@ -1 +0,0 @@
<!DOCTYPE html><title></title>
-259
View File
@@ -1,259 +0,0 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* This file is part of a Moko Consulting project.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: MokoOnyx.Override
* INGROUP: MokoOnyx
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /html/com_joomgallery/image/default.php
<<<<<<< HEAD
<<<<<<< HEAD
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
* BRIEF: Image detail view override — single image with metadata, tags, custom fields
*/
// No direct access
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Session\Session;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Layout\FileLayout;
use Joomla\CMS\User\UserFactoryInterface;
use Joomla\Component\Fields\Administrator\Helper\FieldsHelper;
use Joomgallery\Component\Joomgallery\Administrator\Helper\JoomHelper;
// Image params
$image_type = $this->params['configs']->get('jg_detail_view_type_image', 'detail', 'STRING');
$show_title = $this->params['configs']->get('jg_detail_view_show_title', 0, 'INT');
$show_category = $this->params['configs']->get('jg_detail_view_show_category', 0, 'INT');
$show_description = $this->params['configs']->get('jg_detail_view_show_description', 0, 'INT');
$show_imgdate = $this->params['configs']->get('jg_detail_view_show_imgdate', 0, 'INT');
$show_imgauthor = $this->params['configs']->get('jg_detail_view_show_imgauthor', 0, 'INT');
$show_created_by = $this->params['configs']->get('jg_detail_view_show_created_by', 0, 'INT');
$show_votes = $this->params['configs']->get('jg_detail_view_show_votes', 0, 'INT');
$show_rating = $this->params['configs']->get('jg_detail_view_show_rating', 0, 'INT');
$show_hits = $this->params['configs']->get('jg_detail_view_show_hits', 0, 'INT');
$show_downloads = $this->params['configs']->get('jg_detail_view_show_downloads', 0, 'INT');
$show_tags = $this->params['configs']->get('jg_detail_view_show_tags', 0, 'INT');
$show_metadata = $this->params['configs']->get('jg_detail_view_show_metadata', 0, 'INT');
// Import CSS & JS
$wa = $this->document->getWebAssetManager();
$wa->useStyle('com_joomgallery.site');
$wa->useStyle('com_joomgallery.jg-icon-font');
// Access check
$canEdit = $this->getAcl()->checkACL('edit', 'com_joomgallery.image', $this->item->id, $this->item->catid, true);
$canDelete = $this->getAcl()->checkACL('delete', 'com_joomgallery.image', $this->item->id, $this->item->catid, true);
$canCheckin = $this->getAcl()->checkACL('editstate', 'com_joomgallery.image', $this->item->id, $this->item->catid, true) || $this->item->checked_out == Factory::getUser()->id;
$returnURL = base64_encode(JoomHelper::getViewRoute('image', $this->item->id, $this->item->catid, $this->item->language, $this->getLayout()));
// Tags
$tagLayout = new FileLayout('joomgallery.content.tags');
$tags = $tagLayout->render($this->item->tags);
// Metadata
$metadataLayout = new FileLayout('joomgallery.content.metadata');
$metadata = $metadataLayout->render($this->item->imgmetadata);
// Custom Fields
$fields = FieldsHelper::getFields('com_joomgallery.image', $this->item);
// Check if we have any info rows to show
$hasInfo = $show_category || $show_imgdate || $show_imgauthor || $show_created_by
|| $show_votes || $show_rating || $show_hits || $show_downloads
|| $show_tags || $show_metadata || count($fields) > 0;
?>
<div class="com-joomgallery-image" itemscope itemtype="https://schema.org/ImageObject">
<?php if ($show_title) : ?>
<h2 itemprop="name"><?php echo $this->escape($this->item->title); ?></h2>
<?php endif; ?>
<?php // Back to category ?>
<a class="btn btn-outline-primary btn-sm mb-3" href="<?php echo Route::_('index.php?option=com_joomgallery&view=category&id=' . (int) $this->item->catid); ?>">
<i class="jg-icon-arrow-left-alt me-1" aria-hidden="true"></i><?php echo Text::_('COM_JOOMGALLERY_IMAGE_BACK_TO_CATEGORY') . ' ' . $this->escape($this->item->cattitle); ?>
</a>
<?php // Admin buttons ?>
<?php if ($canEdit || $canCheckin || $canDelete) : ?>
<div class="com-joomgallery-image__actions btn-toolbar mb-3" role="toolbar" aria-label="<?php echo Text::_('JTOOLBAR'); ?>">
<?php if ($canCheckin && $this->item->checked_out > 0) : ?>
<a class="btn btn-outline-secondary btn-sm me-2" href="<?php echo Route::_('index.php?option=com_joomgallery&task=image.checkin&id=' . $this->item->id . '&return=' . $returnURL . '&' . Session::getFormToken() . '=1'); ?>">
<i class="jg-icon-checkin me-1" aria-hidden="true"></i><?php echo Text::_('JLIB_HTML_CHECKIN'); ?>
</a>
<?php endif; ?>
<?php if ($canEdit) : ?>
<a class="btn btn-outline-primary btn-sm me-2<?php echo ($this->item->checked_out > 0) ? ' disabled' : ''; ?>" href="<?php echo Route::_('index.php?option=com_joomgallery&task=image.edit&id=' . $this->item->id . '&return=' . $returnURL); ?>">
<i class="jg-icon-edit me-1" aria-hidden="true"></i><?php echo Text::_('JGLOBAL_EDIT'); ?>
</a>
<?php endif; ?>
<?php if ($canDelete) : ?>
<a class="btn btn-outline-danger btn-sm<?php echo ($this->item->checked_out > 0) ? ' disabled' : ''; ?>" href="#deleteImgModal" role="button" data-bs-toggle="modal">
<i class="jg-icon-delete me-1" aria-hidden="true"></i><?php echo Text::_('JACTION_DELETE'); ?>
</a>
<?php echo HTMLHelper::_(
'bootstrap.renderModal',
'deleteImgModal',
[
'title' => Text::_('JACTION_DELETE'),
'modalWidth' => '50',
'bodyHeight' => '100',
'footer' => '<button class="btn btn-secondary" data-bs-dismiss="modal">' . Text::_('JCANCEL') . '</button>'
. '<a href="' . Route::_('index.php?option=com_joomgallery&task=image.remove&id=' . $this->item->id . '&return=' . $returnURL . '&' . Session::getFormToken() . '=1', false, 2) . '" class="btn btn-danger">' . Text::_('COM_JOOMGALLERY_COMMON_DELETE_IMAGE_TIPCAPTION') . '</a>',
],
Text::_('COM_JOOMGALLERY_COMMON_ALERT_SURE_DELETE_SELECTED_ITEM')
); ?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php // Image ?>
<figure class="figure com-joomgallery-image__figure text-center w-100 mb-4">
<div id="jg-loader"></div>
<img
src="<?php echo JoomHelper::getImg($this->item, $image_type); ?>"
class="figure-img img-fluid rounded"
alt="<?php echo $this->escape($this->item->title); ?>"
style="width:auto;"
itemprop="contentUrl"
loading="lazy"
/>
<?php if ($show_description && !empty($this->item->description)) : ?>
<figcaption class="figure-caption" itemprop="description"><?php echo $this->item->description; ?></figcaption>
<?php endif; ?>
</figure>
<?php // Image info table ?>
<?php if ($hasInfo) : ?>
<div class="com-joomgallery-image__info">
<h3><?php echo Text::_('COM_JOOMGALLERY_IMAGE_INFO'); ?></h3>
<table class="table table-striped">
<tbody>
<?php if ($show_category) : ?>
<tr>
<th scope="row"><?php echo Text::_('JCATEGORY'); ?></th>
<td>
<a href="<?php echo Route::_('index.php?option=com_joomgallery&view=category&id=' . (int) $this->item->catid); ?>">
<?php echo $this->escape($this->item->cattitle); ?>
</a>
</td>
</tr>
<?php endif; ?>
<?php if ($show_imgdate) : ?>
<tr>
<th scope="row"><?php echo Text::_('COM_JOOMGALLERY_DATE'); ?></th>
<td>
<time datetime="<?php echo HTMLHelper::_('date', $this->item->date, 'c'); ?>" itemprop="dateCreated">
<?php echo HTMLHelper::_('date', $this->item->date, Text::_('DATE_FORMAT_LC4')); ?>
</time>
</td>
</tr>
<?php endif; ?>
<?php if ($show_imgauthor) : ?>
<tr>
<th scope="row"><?php echo Text::_('JAUTHOR'); ?></th>
<td itemprop="author"><?php echo $this->escape($this->item->author); ?></td>
</tr>
<?php endif; ?>
<?php if ($show_created_by) : ?>
<?php $user = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById($this->item->created_by); ?>
<tr>
<th scope="row"><?php echo Text::_('COM_JOOMGALLERY_OWNER'); ?></th>
<td><?php echo $this->escape($user->name); ?></td>
</tr>
<?php endif; ?>
<?php if ($show_votes) : ?>
<tr>
<th scope="row"><?php echo Text::_('COM_JOOMGALLERY_VOTES'); ?></th>
<td><?php echo $this->escape($this->item->votes); ?></td>
</tr>
<?php endif; ?>
<?php if ($show_rating) : ?>
<tr>
<th scope="row"><?php echo Text::_('COM_JOOMGALLERY_IMAGE_RATING'); ?></th>
<td><?php echo $this->escape($this->item->rating); ?></td>
</tr>
<?php endif; ?>
<?php if ($show_hits) : ?>
<tr>
<th scope="row"><?php echo Text::_('JGLOBAL_HITS'); ?></th>
<td><?php echo (int) $this->item->hits; ?></td>
</tr>
<?php endif; ?>
<?php if ($show_downloads) : ?>
<tr>
<th scope="row"><?php echo Text::_('COM_JOOMGALLERY_DOWNLOADS'); ?></th>
<td><?php echo (int) $this->item->downloads; ?></td>
</tr>
<?php endif; ?>
<?php if ($show_tags) : ?>
<tr>
<th scope="row"><?php echo Text::_('COM_JOOMGALLERY_TAGS'); ?></th>
<td><?php echo $tags; ?></td>
</tr>
<?php endif; ?>
<?php if ($show_metadata) : ?>
<tr>
<th scope="row"><?php echo Text::_('COM_JOOMGALLERY_IMGMETADATA'); ?></th>
<td><?php echo $metadata; ?></td>
</tr>
<?php endif; ?>
<?php // Custom fields ?>
<?php if (count($fields) > 0) : ?>
<tr>
<th scope="row" colspan="2"><strong><?php echo Text::_('JGLOBAL_FIELDS'); ?></strong></th>
</tr>
<?php foreach ($fields as $field) : ?>
<?php if ($this->component->getAccess()->checkViewLevel($field->access) && $field->params->get('display') > 0) : ?>
<tr class="<?php echo $this->escape($field->params->get('render_class')); ?>">
<?php if ($field->params->get('showlabel', true)) : ?>
<th scope="row" class="<?php echo $this->escape($field->params->get('label_render_class')); ?>"><?php echo $this->escape($field->title); ?></th>
<?php else : ?>
<th scope="row"></th>
<?php endif; ?>
<td class="<?php echo $this->escape($field->params->get('value_render_class')); ?>"><?php echo $field->value; ?></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<script>
window.onload = function() {
var el = document.querySelector('#jg-loader');
if (el) el.classList.add('hidden');
};
</script>
</div>
@@ -1 +0,0 @@
<!DOCTYPE html><title></title>
+1 -11
View File
@@ -10,17 +10,7 @@
* INGROUP: MokoOnyx
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /html/layouts/joomla/module/card.php
<<<<<<< HEAD
<<<<<<< HEAD
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
* VERSION: 02.20.00
* BRIEF: Custom card module chrome — renders module titles for all modules
*/
+1 -11
View File
@@ -11,17 +11,7 @@
* INGROUP: MokoOnyx.Layouts
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /src/html/layouts/mokoonyx/article-metadata.php
<<<<<<< HEAD
<<<<<<< HEAD
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
* VERSION: 02.20.00
* BRIEF: Article metadata footer layout -- renders jcfields grouped by field group
*/
+2
View File
@@ -33,6 +33,8 @@ if ($item->anchor_rel) {
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
if ($itemParams->get('menu_text', 1)) {
$linktype = '<span class="' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
+2
View File
@@ -19,6 +19,8 @@ $anchor_css = $item->anchor_css ?: '';
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
if ($itemParams->get('menu_text', 1)) {
$linktype = '<span class="' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
+2
View File
@@ -19,6 +19,8 @@ $anchor_css = $item->anchor_css ?: '';
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
if ($itemParams->get('menu_text', 1)) {
$linktype = '<span class="' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
+2
View File
@@ -33,6 +33,8 @@ if ($item->anchor_rel) {
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
if ($itemParams->get('menu_text', 1)) {
$linktype = '<span class="' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
@@ -33,6 +33,8 @@ if ($item->anchor_rel) {
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
if ($itemParams->get('menu_text', 1)) {
$linktype = '<span class="' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
+2
View File
@@ -19,6 +19,8 @@ $anchor_css = $item->anchor_css ?: '';
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
if ($itemParams->get('menu_text', 1)) {
$linktype = '<span class="' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
@@ -19,6 +19,8 @@ $anchor_css = $item->anchor_css ?: '';
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
if ($itemParams->get('menu_text', 1)) {
$linktype = '<span class="' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
+2
View File
@@ -33,6 +33,8 @@ if ($item->anchor_rel) {
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
if ($itemParams->get('menu_text', 1)) {
$linktype = '<span class="' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
+2
View File
@@ -33,6 +33,8 @@ if ($item->anchor_rel) {
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
// The link is an icon
if ($itemParams->get('menu_text', 1)) {
// If the link text is to be displayed, the icon is added with aria-hidden
+2
View File
@@ -19,6 +19,8 @@ $anchor_css = $item->anchor_css ?: '';
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
// The link is an icon
if ($itemParams->get('menu_text', 1)) {
// If the link text is to be displayed, the icon is added with aria-hidden
+2
View File
@@ -19,6 +19,8 @@ $anchor_css = $item->anchor_css ?: '';
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
// The link is an icon
if ($itemParams->get('menu_text', 1)) {
// If the link text is to be displayed, the icon is added with aria-hidden
+2
View File
@@ -33,6 +33,8 @@ if ($item->anchor_rel) {
$linktype = $item->title;
if ($item->menu_icon) {
// Strip Joomla-injected padding classes that conflict with FA icon sizing
$item->menu_icon = trim(preg_replace('/\bp-[0-5]\b/', '', $item->menu_icon));
// The link is an icon
if ($itemParams->get('menu_text', 1)) {
// If the link text is to be displayed, the icon is added with aria-hidden
+1 -11
View File
@@ -10,17 +10,7 @@
* INGROUP: MokoOnyx.Accessibility
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: ./media/css/a11y-high-contrast.css
<<<<<<< HEAD
<<<<<<< HEAD
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
=======
* VERSION: 02.17.00
>>>>>>> origin/main
>>>>>>> origin/main
* VERSION: 02.20.00
* BRIEF: High-contrast stylesheet for accessibility toolbar
*/
+154
View File
@@ -93,6 +93,8 @@ class Tpl_MokoonyxInstallerScript implements InstallerScriptInterface
$this->replaceCassiopeiaReferences();
$this->clearFaviconStamp();
$this->cleanMediaFolder();
$this->removeDeletedFiles();
$this->removeDuplicateExtensions();
$this->lockExtension();
}
@@ -483,6 +485,158 @@ class Tpl_MokoonyxInstallerScript implements InstallerScriptInterface
}
}
/**
* Remove duplicate MokoOnyx extension entries from #__extensions.
*
* Re-installs or migrations can leave ghost rows. We keep the one
* that is locked (the active template) and delete any extras.
* Also removes stale MokoCassiopeia entries if present.
*/
private function removeDuplicateExtensions(): void
{
$db = Factory::getDbo();
// Find all MokoOnyx template entries
$rows = $db->setQuery(
$db->getQuery(true)
->select(['extension_id', 'locked'])
->from('#__extensions')
->where($db->quoteName('element') . ' = ' . $db->quote(self::NEW_NAME))
->where($db->quoteName('type') . ' = ' . $db->quote('template'))
->order('locked DESC, extension_id ASC')
)->loadObjectList();
if (count($rows) > 1) {
$keep = (int) $rows[0]->extension_id;
$removed = 0;
for ($i = 1; $i < count($rows); $i++) {
$staleId = (int) $rows[$i]->extension_id;
$db->setQuery(
$db->getQuery(true)
->delete('#__update_sites_extensions')
->where('extension_id = ' . $staleId)
)->execute();
$db->setQuery(
$db->getQuery(true)
->delete('#__extensions')
->where('extension_id = ' . $staleId)
)->execute();
$removed++;
}
if ($removed > 0) {
$this->logMessage("Removed {$removed} duplicate MokoOnyx extension(s). Kept ID {$keep}.");
}
}
// Remove stale MokoCassiopeia if not set as default
$oldExt = (int) $db->setQuery(
$db->getQuery(true)
->select('extension_id')
->from('#__extensions')
->where($db->quoteName('element') . ' = ' . $db->quote(self::OLD_NAME))
->where($db->quoteName('type') . ' = ' . $db->quote('template'))
)->loadResult();
if ($oldExt) {
$isDefault = (int) $db->setQuery(
$db->getQuery(true)
->select('COUNT(*)')
->from('#__template_styles')
->where($db->quoteName('template') . ' = ' . $db->quote(self::OLD_NAME))
->where($db->quoteName('home') . ' = 1')
)->loadResult();
if ($isDefault === 0) {
$db->setQuery(
$db->getQuery(true)
->delete('#__update_sites_extensions')
->where('extension_id = ' . $oldExt)
)->execute();
$db->setQuery(
$db->getQuery(true)
->delete('#__extensions')
->where('extension_id = ' . $oldExt)
)->execute();
$db->setQuery(
$db->getQuery(true)
->delete('#__template_styles')
->where($db->quoteName('template') . ' = ' . $db->quote(self::OLD_NAME))
)->execute();
$this->logMessage('Removed stale MokoCassiopeia extension and styles.');
}
}
}
/**
* Remove files and directories that were shipped in previous versions
* but have since been deleted from the package.
*
* Joomla's installer never deletes files on upgrade — it only
* adds/overwrites. This method fills that gap so stale overrides
* and deprecated assets don't linger on disk.
*
* Maintain this list: when you delete a file from the repo, add its
* path here (relative to the template root) so existing installs
* get cleaned up on the next update.
*/
private function removeDeletedFiles(): void
{
$templateRoot = JPATH_ROOT . '/templates/' . self::NEW_NAME;
// Paths relative to templates/mokoonyx/
$deletedFiles = [
// JoomGallery template overrides — removed in 02.19.00
'html/com_joomgallery/category/default.php',
'html/com_joomgallery/category/default_cat.php',
'html/com_joomgallery/category/index.html',
'html/com_joomgallery/gallery/default.php',
'html/com_joomgallery/gallery/index.html',
'html/com_joomgallery/image/default.php',
'html/com_joomgallery/image/index.html',
];
// Directories to remove (only if empty after file deletion)
$deletedDirs = [
'html/com_joomgallery/image',
'html/com_joomgallery/gallery',
'html/com_joomgallery/category',
'html/com_joomgallery',
];
$removed = 0;
foreach ($deletedFiles as $relPath) {
$file = $templateRoot . '/' . $relPath;
if (is_file($file)) {
@unlink($file);
$removed++;
}
}
foreach ($deletedDirs as $relPath) {
$dir = $templateRoot . '/' . $relPath;
if (is_dir($dir)) {
// Only remove if empty
$entries = @scandir($dir);
if ($entries && count($entries) <= 2) { // . and .. only
@rmdir($dir);
}
}
}
if ($removed > 0) {
$this->logMessage("Removed {$removed} deprecated file(s) from previous versions.");
}
}
private function logMessage(string $message, string $priority = 'info'): void
{
$priorities = [
+2 -8
View File
@@ -31,16 +31,10 @@
-->
<extension type="template" client="site" method="upgrade">
<updateservers>
<server type="extension" priority="1" name="MokoOnyx Update Server (MokoGitea)">
https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/updates.xml
</server>
<server type="extension" name="Template - MokoOnyx">https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/updates.xml</server>
</updateservers>
<name>mokoonyx</name>
<<<<<<< HEAD
<version>02.17.00-rc</version>
=======
<version>02.17.00-rc</version>
>>>>>>> origin/main
<version>02.20.00</version>
<scriptfile>script.php</scriptfile>
<creationDate>2026-05-16</creationDate>
<author>Jonathan Miller || Moko Consulting</author>
+24 -4
View File
@@ -5,6 +5,26 @@
-->
<updates>
<update>
<name>Template - MokoOnyx</name>
<description>Template - MokoOnyx development build.</description>
<element>mokoonyx</element>
<type>template</type>
<client>site</client>
<version>02.19.04-dev</version>
<creationDate>2026-06-04</creationDate>
<infourl title="Template - MokoOnyx">https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/development</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/development/tpl_mokoonyx-02.19.04-dev.zip</downloadurl>
</downloads>
<sha256>b5d1db0be2db98858a16902336fd19a47a39d4597f826a90e1d7fa58e40e29e2</sha256>
<tags><tag>dev</tag></tags>
<changelogurl>https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/CHANGELOG.md</changelogurl>
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
<targetplatform name="joomla" version="(5|6)\..*"/>
<php_minimum>8.1.0</php_minimum>
</update>
<update>
<name>Template - MokoOnyx</name>
<description>Template - MokoOnyx stable build.</description>
@@ -13,16 +33,16 @@
<client>site</client>
<version>02.20.00</version>
<creationDate>2026-06-04</creationDate>
<infourl title='Template - MokoOnyx'>https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/stable</infourl>
<infourl title="Template - MokoOnyx">https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/stable</infourl>
<downloads>
<downloadurl type='full' format='zip'>https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/stable/tpl_mokoonyx-02.20.00.zip</downloadurl>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/stable/tpl_mokoonyx-02.20.00.zip</downloadurl>
</downloads>
<sha256>6b0397fce0e1f9e15f3318a200ad4679a0777940c6cfa3a703b875ca14f9979a</sha256>
<sha256>7fe031b49d2908d161378213a9aa9bcf807ef0ee101d39bba077df4f73a60f30</sha256>
<tags><tag>stable</tag></tags>
<changelogurl>https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/CHANGELOG.md</changelogurl>
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
<targetplatform name="joomla" version="(5|6)\..*" />
<targetplatform name="joomla" version="(5|6)\..*"/>
<php_minimum>8.1.0</php_minimum>
</update>
</updates>
+2 -2
View File
@@ -136,11 +136,11 @@ A read-only reference tab displaying all available CSS custom properties organiz
---
*Built with [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API) -- Moko Consulting*
*Built with [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform) -- Moko Consulting*
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
+2 -2
View File
@@ -223,11 +223,11 @@ Additional variables are defined for: VirtueMart (`--vm-*`), Gable (`--gab-*`),
---
*Built with [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API) -- Moko Consulting*
*Built with [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform) -- Moko Consulting*
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
+2 -2
View File
@@ -114,11 +114,11 @@ For additional overrides beyond theme variables, use these files (also update-sa
---
*Built with [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API) -- Moko Consulting*
*Built with [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform) -- Moko Consulting*
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
+5 -5
View File
@@ -46,7 +46,7 @@ MokoOnyx/
│ ├── dark.custom.css # Custom dark palette template
│ └── brand-showcase.html # Brand showcase HTML template
├── Makefile # Build and validation automation
├── composer.json # PHP dependencies (MokoStandards)
├── composer.json # PHP dependencies (moko-platform)
├── package.json # Node.js dependencies (minification)
├── phpcs.xml # PHP CodeSniffer configuration
├── phpstan.neon # PHPStan static analysis configuration
@@ -63,7 +63,7 @@ MokoOnyx/
## Prerequisites
- **PHP** 8.1+
- **Composer** (for MokoStandards CLI and dependencies)
- **Composer** (for moko-platform CLI and dependencies)
- **Node.js** (optional, for build-time minification with terser/clean-css)
- **Make** (GNU Make or compatible)
- **zip** (or PowerShell for Windows)
@@ -110,7 +110,7 @@ Creates `dist/mokoonyx-{version}-beta.zip` (skips minification).
## Validation
MokoOnyx uses the **MokoStandards Enterprise API** for code quality checks.
MokoOnyx uses the **moko-platform CLI** for code quality checks.
```bash
# Run all validation checks
@@ -277,11 +277,11 @@ vendor/bin/codecept run
---
*Built with [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API) -- Moko Consulting*
*Built with [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform) -- Moko Consulting*
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
+2 -2
View File
@@ -88,11 +88,11 @@ Key parameters include:
---
> **[MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki)** -- central standards hub for all Moko Consulting projects.
> **[moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki)** -- central standards hub for all Moko Consulting projects.
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
+2 -2
View File
@@ -55,11 +55,11 @@ MokoOnyx includes an automatic update server. Joomla will notify you when new ve
---
*Built with [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API) -- Moko Consulting*
*Built with [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform) -- Moko Consulting*
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
+2 -2
View File
@@ -108,11 +108,11 @@ Once you have confirmed everything is working:
---
*Built with [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API) -- Moko Consulting*
*Built with [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform) -- Moko Consulting*
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
+2 -2
View File
@@ -102,11 +102,11 @@ This immediately deletes all `.min` files. The template will load the unminified
---
*Built with [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API) -- Moko Consulting*
*Built with [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform) -- Moko Consulting*
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
+3 -3
View File
@@ -99,11 +99,11 @@ Each layout has sub-templates for different menu item types: `_component`, `_hea
---
*Built with [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API) -- Moko Consulting*
*Built with [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform) -- Moko Consulting*
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Revision | Date | Author | Description |
|---|---|---|---|
@@ -111,7 +111,7 @@ Each layout has sub-templates for different menu item types: `_component`, `_hea
---
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
*Repo: [MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)*
| Field | Value |
|---|---|