feat(i18n): add multilingual OG tag support (closes #11)

- Add language column to #__mokoog_tags (default * for all languages)
- Updated unique key to include language
- SQL migration 01.02.00 for upgrades
- og:locale output from current Joomla language (en-GB to en_GB)
- Language-aware OG data loading: exact match preferred over wildcard

Authored-by: Moko Consulting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan Miller
2026-05-23 18:35:49 -05:00
parent 3d73ea2f9c
commit 4a9433d2bb
3 changed files with 22 additions and 3 deletions
@@ -16,10 +16,11 @@ CREATE TABLE IF NOT EXISTS `#__mokoog_tags` (
`meta_description` VARCHAR(200) NOT NULL DEFAULT '',
`robots` VARCHAR(100) NOT NULL DEFAULT '',
`canonical_url` VARCHAR(512) NOT NULL DEFAULT '',
`language` CHAR(7) NOT NULL DEFAULT '*',
`published` TINYINT(1) NOT NULL DEFAULT 1,
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_content` (`content_type`, `content_id`),
UNIQUE KEY `idx_content_lang` (`content_type`, `content_id`, `language`),
KEY `idx_published` (`published`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -0,0 +1,10 @@
--
-- MokoOpenGraph 01.02.00 — Add multilingual OG tag support
--
ALTER TABLE `#__mokoog_tags`
ADD COLUMN `language` CHAR(7) NOT NULL DEFAULT '*' AFTER `canonical_url`;
ALTER TABLE `#__mokoog_tags`
DROP INDEX `idx_content`,
ADD UNIQUE KEY `idx_content_lang` (`content_type`, `content_id`, `language`);
@@ -106,6 +106,11 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
$doc->setMetaData('og:image', $imageUrl, 'property');
}
// og:locale from current language
$langTag = Factory::getLanguage()->getTag();
$ogLocale = str_replace('-', '_', $langTag);
$doc->setMetaData('og:locale', $ogLocale, 'property');
// Facebook App ID
$fbAppId = $this->params->get('fb_app_id', '');
@@ -237,9 +242,12 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
->from($db->quoteName('#__mokoog_tags'))
->where($db->quoteName('content_type') . ' = ' . $db->quote($option))
->where($db->quoteName('content_id') . ' = ' . (int) $id)
->where($db->quoteName('published') . ' = 1');
->where($db->quoteName('published') . ' = 1')
->where('(' . $db->quoteName('language') . ' = ' . $db->quote(Factory::getLanguage()->getTag())
. ' OR ' . $db->quoteName('language') . ' = ' . $db->quote('*') . ')')
->order('CASE WHEN ' . $db->quoteName('language') . ' = ' . $db->quote('*') . ' THEN 1 ELSE 0 END ASC');
$db->setQuery($query);
$db->setQuery($query, 0, 1);
return $db->loadObject() ?: $empty;
}