案例研究:每种语言一个不同的域名
处理多语言网站可能会很困难,尤其是当你为每种语言处理不同的域名时。让我们看看如何使用 Joomla 4 在一个成功的多语言和多域名实施中。
每种语言一个不同的域名
几个月前,我必须将一个拥有数万篇文章的网站从 Joomla 3 迁移到 Joomla 4,这个网站有三种不同的语言。
使用 Joomla 管理多语言网站是小菜一碟。
我唯一的问题是,这个多语言网站有三个域名
当然,想法是在用户每次切换语言时都使用正确的域名(并且确保内容不会被仅以其正确域名索引)。
有两个小巧的插件为此 J3 做了这件事
- Language2Domain,一个由 Jisse Reitsma 开发并由 Peter Martin 承接的免费插件
- GJ 多语言域名,现在甚至不再在 Joomla 扩展目录中
可能会在将来对 Language2Domain 进行适配以适应 J4,而且有一天我也可能在 J4 中有“多站点”功能,但据我所知,甚至没有关于“多站点”的明确定义。
我不能等几个月或几年才从外部得到解决方案,所以我开始考虑解决方案/解决方案,并且我找到了它!
所以,这里就是,只有三个小步骤
- 在您的 .htaccess 文件中添加几行
- 添加一个第一个 Regular Labs ReReplacer 规则,以适应您页面中的 <head> 部分
- 添加一个第二个 Regular Labs ReReplacer 规则,以适应您页面中的 <body> 部分
步骤 2 和 3 确保所有链接 在 Joomla 中 都是正确的(请注意,如果您愿意,可以通过使用一些正则表达式将它们组合在一起)。
但这并不能阻止人类或机器人手动到达一个“错误”的域名和语言标签组合:在这种情况下,Joomla会简单地显示页面,保留“错误的”域名...但我们显然希望强制使用正确的域名(以ao为例,以避免因重复内容或重定向等原因损害SEO)。这就是第一步所做的事情。
想做同样的事情吗?
只需访问https://github.com/woluweb/a_different_domain_name_for_each_language 以查看详细的解释。
利用子模板
迁移的主要目标之一是利用Joomla 4的通用功能和默认前端模板“Cassiopeia”的特定功能。
由于Cassiopeia也是子模板准备就绪(如果你不知道子模板是什么,你应该查看2022年5月发布的Joomla社区杂志的这篇先前文章),我们认为这可以是一种改善我们网站构建方式的好方法。
一切从复制原始/templates/cassiopeia/index.php文件到/template/cassiopeia_mychild/index.php开始。
拥有更复杂的页眉
正如你在网站上所看到的,我需要在我的<header>中添加3行。
因此,我编辑了我的子模板的index.php文件,以便在<header>部分添加一行和几个位置
仅在文章视图时调用脚本
这个网站大量使用HighCharts构建的图形。这意味着我必须加载大约10个javascript文件(highcharts.js以及额外的如heatmap.js、export.js等)。
由于我有子模板,我只需要将这些脚本的调用复制/粘贴到我们自己的index.php文件的<head>部分。
示例
<script src="https://code.highcharts.com/highcharts.js"></script>
但是,在每一页都加载这个脚本并不利于性能。实际上,这个脚本确实只需要在单个文章视图中(而不是博客视图或其他视图)加载。
所以我只是在以下内容之间包装我的所有脚本行
<?php if ('article' == $view) { ?>
和
<?php } ?>
这意味着它们只在单个文章视图中加载。
仅在未登录时调用脚本
对于分析,网站所有者使用Matomo,因为他们关心隐私。
但统计数据不仅反映了真实访客的点击,还反映了作者自己的点击(当发布并内部审查新研究时,每天的点击量可达数百次)。
因此,我们想到了仅在用户未登录时添加Matomo脚本的想法(如果你熟悉访问控制级别,这也可以称为公共或访客模式)。
为此,我首先需要在我们的index.php文件的<head>部分添加以下行,这将允许我们“玩转”用户
<?php $user = Factory::getUser(); ?>
然后我简单地在我的分析脚本之间包装
<?php if ($user->id == 0) : // 检查用户ID为零,如果为零表示用户未登录Joomla。否则可以使用if ($user->guest) ?>
和
<?php endif; ?>
为Cassiopeia添加动画
最后,我还想能够自动为我们的标题(<h1>、<h2>等)添加动画。
有一个很好的库可以非常简单地添加动画: https://animatecss.node.org.cn/
当您启用animate.style时,要使元素动起来,只需为它们添加几个类即可。示例
<div class="animate__animated animate__bounce animate__repeat-2">示例</div>
当然,您可以手动将这些类添加到元素中。但这里的想法是
- 首先:让这些类通过我们的javascript自动添加
- 其次,也是最重要的:仅在相关元素出现在屏幕上时添加这些类(在我们甚至看不到它们之前就动画化所有元素是没有意义的,因为我们必须先向下滚动页面……)
完成此操作有2个步骤:首先是CSS,其次是JavaScript。
步骤1 - 添加CSS
在我们的index.php文件的
部分,我添加了以下链接<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
步骤2 - 添加JS
正如您可能知道的,您可以通过在/media/templates/site/cassiopeia_mychild/css
文件夹中创建一个user.css
文件来简单地添加自己的CSS规则到Cassiopeia。
实际上,您可以通过在/media/templates/site/cassiopeia_mychild/js
文件夹中创建一个user.js
文件来以相同的方式将您自己的JavaScript添加到Cassiopeia中。
注意:下面的javascript使用所谓的"intersection-observer"来确定元素何时真正出现在屏幕上。
// 我们可以通过intersection-observer来触发动画
// https://cheewebdevelopment.com/vanilla-js-scroll-events-animations-with-intersectionobserver-api/
// https://grafikart.fr/tutoriels/intersection-observer-804
// 脚本应在页面准备好时加载
// https://mdn.org.cn/en-US/docs/Web/API/Document/DOMContentLoaded_event
// https://javascript.js.cn/onload-ondomcontentloaded (许多语言中都可用,如 https://fr.javascript.info/onload-ondomcontentloaded)
document.addEventListener('DOMContentLoaded', function() {
let observer = new IntersectionObserver(function (observables) {
observables.forEach(function (observable) {
// 元素变得可见
if (observable.intersectionRatio > 0.5) {
observable.target.classList.add('animate__animated')
observable.target.classList.add('animate__fadeInUp')
observer.unobserve(observable.target)
}
})
}, {
threshold: [0.5]
});
// 我们观察我们的元素
let items = document.querySelectorAll('.image, h1, h2, h3, h4, h5, h6')
items.forEach(function (item) {
observer.observe(item)
});
});
使用J4的Web Asset Manager
为了使事情简单,在上面的示例中,我们在(子)模板的index.php中直接调用了样式表和脚本。
实际上,从J4开始,调用这些内容的更好方法是使用Web Asset Manager。
以下是如何在使用Web Asset Manager时适应上述示例的一些信息
- 简介:https://www.joomlashack.com/blog/tutorials/web-assets-in-joomla-4/
- 官方文档:https://docs.joomla.org/J4.x:Web_Assets
- Astrid的解释:https://blog.astrid-guenther.de/en/joomla-template-wa/
- 技术信息:https://api.joomla.net.cn/cms-4/classes/Joomla-CMS-WebAsset-WebAssetManager.html
结论
如您所见,在Joomla 3中可能需要扩展才能完成的事情,在Joomla 4中可以非常简单地完成
- 或者通过找到类似于上述第一个示例中的简单解决方案
- 或者通过使用Joomla 4的本地功能,如子模板
我在这里只是刚刚触及J4能做什么的表面。请随时联系我,以改进这些示例或提出更多技巧和窍门!
《Joomla社区杂志》上发表的一些文章代表了作者对特定主题的个人观点或经验,可能并不与Joomla项目的官方立场一致。
通过接受,您将访问 https://magazine.joomla.net.cn/ 外部第三方提供的服务。
评论 4
我们有一个名为MightySites的扩展,可以轻松实现这个功能,还有大量其他功能!
看起来您没有探索JED,甚至没有在Google上搜索“Joomla案例研究:每个语言一个域名”
抱歉AlberBrains。我知道“MightySites”,但鉴于描述“MightySites允许您在同一个Joomla安装上运行多个网站,并在不同的Joomla网站之间共享数据库数据”,我一直以为它是为多站而设计的(不是为多域名)。
此外,我的文章最初计划在8月发布,9月发表...但看到自那时起也发布了一个新的扩展:n3t语言域名。
但本文中不同示例的要点也是想说明,有时一点变通方法或两行代码也可以解决问题。
嗨,Marc:
也许使用新的资产管理器加载所有的 js 和 css 资源可以提高您的性能(检查文章页面上的 LCp 和 FCP 吧^^)。Cassiopea 本身不是一场革命,但它是如何演示使用 J!4 管理一个现代模板的方法。
感谢您的示例和分享;-)
感谢您的建议 @semaphore。
如果您能发送一封简短的电子邮件,其中包含一个示例代码,该代码根据我上面的示例适配使用资产管理器,我将非常乐意调整这篇文章和我的其他演示