This commit is contained in:
oliver
2026-08-28 10:11:11 -03:00
parent f533ff8e36
commit 585951c8ce
1380 changed files with 1540268 additions and 0 deletions
+299
View File
@@ -0,0 +1,299 @@
// Language Router - Multi-language URL management for Odoo Expertos
// Supports: ES (default, no prefix), EN, DE, FR
const LanguageRouter = {
// Supported languages with their configurations
languages: {
es: { code: 'es', name: 'Español', prefix: '', flag: '🇪🇸', hreflang: 'es' },
en: { code: 'en', name: 'English', prefix: '/en', flag: '🇬🇧', hreflang: 'en' },
de: { code: 'de', name: 'Deutsch', prefix: '/de', flag: '🇩🇪', hreflang: 'de' },
fr: { code: 'fr', name: 'Français', prefix: '/fr', flag: '🇫🇷', hreflang: 'fr' },
pt: { code: 'pt', name: 'Português', prefix: '/pt', flag: '🇧🇷', hreflang: 'pt' },
ar: { code: 'ar', name: 'العربية', prefix: '/ar', flag: '🇸🇦', hreflang: 'ar', rtl: true }
},
// Navigation labels per language
navLabels: {
es: { home: 'Inicio', odoo: 'Odoo', odooIA: 'Odoo IA', hosting: 'Hosting Odoo' },
en: { home: 'Home', odoo: 'Odoo', odooIA: 'Odoo AI', hosting: 'Odoo Hosting' },
de: { home: 'Startseite', odoo: 'Odoo', odooIA: 'Odoo KI', hosting: 'Odoo Hosting' },
fr: { home: 'Accueil', odoo: 'Odoo', odooIA: 'Odoo IA', hosting: 'Hébergement Odoo' },
pt: { home: 'Início', odoo: 'Odoo', odooIA: 'Odoo IA', hosting: 'Hospedagem Odoo' },
ar: { home: 'الرئيسية', odoo: 'Odoo', odooIA: 'Odoo AI', hosting: 'استضافة Odoo' }
},
// Footer labels per language
footerLabels: {
es: {
contact: 'Contacto',
quickLinks: 'Enlaces Rápidos',
legal: 'Legal',
modules: 'Módulos Odoo',
benefits: 'Beneficios',
community: 'Comunidad',
legalNotice: 'Aviso Legal',
privacy: 'Política de Privacidad',
cookies: 'Política de Cookies',
terms: 'Términos de Uso',
copyright: 'Todos los derechos reservados.',
experts: 'Expertos en soluciones Odoo ERP'
},
en: {
contact: 'Contact',
quickLinks: 'Quick Links',
legal: 'Legal',
modules: 'Odoo Modules',
benefits: 'Benefits',
community: 'Community',
legalNotice: 'Legal Notice',
privacy: 'Privacy Policy',
cookies: 'Cookie Policy',
terms: 'Terms of Use',
copyright: 'All rights reserved.',
experts: 'Odoo ERP Solutions Experts'
},
de: {
contact: 'Kontakt',
quickLinks: 'Schnelllinks',
legal: 'Rechtliches',
modules: 'Odoo Module',
benefits: 'Vorteile',
community: 'Community',
legalNotice: 'Impressum',
privacy: 'Datenschutzerklärung',
cookies: 'Cookie-Richtlinie',
terms: 'Nutzungsbedingungen',
copyright: 'Alle Rechte vorbehalten.',
experts: 'Odoo ERP Lösungsexperten'
},
fr: {
contact: 'Contact',
quickLinks: 'Liens Rapides',
legal: 'Mentions Légales',
modules: 'Modules Odoo',
benefits: 'Avantages',
community: 'Communauté',
legalNotice: 'Mentions Légales',
privacy: 'Politique de Confidentialité',
cookies: 'Politique des Cookies',
terms: "Conditions d'Utilisation",
copyright: 'Tous droits réservés.',
experts: 'Experts en solutions Odoo ERP'
},
pt: {
contact: 'Contato',
quickLinks: 'Links Rápidos',
legal: 'Legal',
modules: 'Módulos Odoo',
benefits: 'Benefícios',
community: 'Comunidade',
legalNotice: 'Aviso Legal',
privacy: 'Política de Privacidade',
cookies: 'Política de Cookies',
terms: 'Termos de Uso',
copyright: 'Todos os direitos reservados.',
experts: 'Especialistas em soluções Odoo ERP'
},
ar: {
contact: 'اتصل بنا',
quickLinks: 'روابط سريعة',
legal: 'قانوني',
modules: 'وحدات Odoo',
benefits: 'المزايا',
community: 'المجتمع',
legalNotice: 'إشعار قانوني',
privacy: 'سياسة الخصوصية',
cookies: 'سياسة ملفات تعريف الارتباط',
terms: 'شروط الاستخدام',
copyright: 'جميع الحقوق محفوظة.',
experts: 'خبراء حلول Odoo ERP'
}
},
// Detect current language from URL
detectLanguage: function() {
const path = window.location.pathname;
if (path.startsWith('/en/') || path === '/en') return 'en';
if (path.startsWith('/de/') || path === '/de') return 'de';
if (path.startsWith('/fr/') || path === '/fr') return 'fr';
if (path.startsWith('/pt/') || path === '/pt') return 'pt';
if (path.startsWith('/ar/') || path === '/ar') return 'ar';
return 'es'; // Default
},
// Get current language config
getCurrentLanguage: function() {
const lang = this.detectLanguage();
return this.languages[lang];
},
// Get base path (without language prefix)
getBasePath: function() {
const path = window.location.pathname;
const lang = this.detectLanguage();
if (lang === 'es') return path;
const prefix = this.languages[lang].prefix;
if (path.startsWith(prefix)) {
const basePath = path.substring(prefix.length);
return basePath || '/';
}
return path;
},
// Build URL for a specific language
buildLanguageUrl: function(targetLang) {
const basePath = this.getBasePath();
const config = this.languages[targetLang];
if (targetLang === 'es') {
return basePath;
}
return config.prefix + (basePath === '/' ? '/' : basePath);
},
// Generate all alternate URLs for hreflang
getAlternateUrls: function() {
const basePath = this.getBasePath();
const baseUrl = 'https://odoo-expertos.com';
const alternates = [];
Object.keys(this.languages).forEach(lang => {
const config = this.languages[lang];
let url;
if (lang === 'es') {
url = baseUrl + basePath;
} else {
url = baseUrl + config.prefix + (basePath === '/' ? '/' : basePath);
}
alternates.push({
lang: config.hreflang,
url: url
});
});
// Add x-default (Spanish)
alternates.push({
lang: 'x-default',
url: baseUrl + basePath
});
return alternates;
},
// Generate hreflang link tags HTML
generateHreflangTags: function() {
const alternates = this.getAlternateUrls();
return alternates.map(alt =>
`<link rel="alternate" hreflang="${alt.lang}" href="${alt.url}" />`
).join('\n ');
},
// Inject hreflang tags into document head
injectHreflangTags: function() {
// Remove existing hreflang tags
document.querySelectorAll('link[hreflang]').forEach(el => el.remove());
const alternates = this.getAlternateUrls();
alternates.forEach(alt => {
const link = document.createElement('link');
link.rel = 'alternate';
link.hreflang = alt.lang;
link.href = alt.url;
document.head.appendChild(link);
});
},
// Get navigation labels for current language
getNavLabels: function() {
const lang = this.detectLanguage();
return this.navLabels[lang];
},
// Get footer labels for current language
getFooterLabels: function() {
const lang = this.detectLanguage();
return this.footerLabels[lang];
},
// Get link prefix for current language
getLinkPrefix: function() {
const lang = this.detectLanguage();
return this.languages[lang].prefix;
},
// Switch to another language
switchLanguage: function(targetLang) {
const newUrl = this.buildLanguageUrl(targetLang);
window.location.href = newUrl;
},
// Create language switcher HTML
createLanguageSwitcher: function() {
const currentLang = this.detectLanguage();
const currentConfig = this.languages[currentLang];
let dropdownItems = '';
Object.keys(this.languages).forEach(lang => {
const config = this.languages[lang];
const isActive = lang === currentLang ? ' active' : '';
const url = this.buildLanguageUrl(lang);
dropdownItems += `
<a href="${url}" class="lang-option${isActive}" data-lang="${lang}">
<span class="lang-flag">${config.flag}</span>
<span class="lang-name">${config.name}</span>
</a>`;
});
return `
<div class="language-switcher">
<button class="lang-toggle" aria-label="Select language">
<span class="lang-flag">${currentConfig.flag}</span>
<span class="lang-code">${currentLang.toUpperCase()}</span>
<svg class="lang-arrow" width="12" height="12" viewBox="0 0 12 12" fill="currentColor">
<path d="M2 4L6 8L10 4" stroke="currentColor" stroke-width="2" fill="none"/>
</svg>
</button>
<div class="lang-dropdown">
${dropdownItems}
</div>
</div>
`;
},
// Initialize language switcher functionality
initLanguageSwitcher: function() {
document.addEventListener('click', (e) => {
const toggle = e.target.closest('.lang-toggle');
const switcher = document.querySelector('.language-switcher');
if (toggle) {
e.preventDefault();
switcher.classList.toggle('open');
} else if (!e.target.closest('.language-switcher')) {
if (switcher) switcher.classList.remove('open');
}
});
},
// Initialize all language features
init: function() {
this.injectHreflangTags();
this.initLanguageSwitcher();
// Set html lang attribute
const lang = this.detectLanguage();
document.documentElement.lang = lang;
}
};
// Auto-initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => LanguageRouter.init());
} else {
LanguageRouter.init();
}