Multilanguage
创建同一页面的多语言版本
配置参数
- extensions string[]
The list of extensions used for this plugin
Default:[ ".html" ]
- languages string[]
Available languages
- defaultLanguage string
A prefix-free language
描述
此插件提供了一些功能,以简化多语言站点的创建。
安装
在你的 _config.ts
文件中导入此插件以使用它:
import lume from "lume/mod.ts";
import multilanguage from "lume/plugins/multilanguage.ts";
const site = lume();
site.use(multilanguage({
languages: ["en", "gl", "es"], // 可用语言
}));
export default site;
Important
为了正常工作,此插件必须在其他修改页面 URL 的插件之后注册(例如,basePath
):
import lume from "lume/mod.ts";
import basePath from "lume/plugins/base_path.ts";
import multilanguage from "lume/plugins/multilanguage.ts";
site.use(basePath()); // 修改 url 的操作必须在前
site.use(multilanguage({
languages: ["en", "gl", "es"],
}));
export default site;
创建多语言页面
此插件使用变量 id
(如果定义了 type
,则与 type
结合使用)来检测同一页面的不同翻译版本。例如,假设我们有以下两个页面:
---
lang: en
id: about
url: /about-me/
---
# About me
---
lang: gl
id: about
url: /acerca-de-min/
---
# Acerca de min
该插件将这两个页面解释为相同的内容,但使用不同的语言,因为它们具有相同的 id(about
)和相同的 type
(未定义)。
这些页面将导出为 /en/about-me/
、/gl/acerca-de-min/
。 请注意,/en/
和 /gl/
前缀是自动添加的。
可以将一种语言配置为默认语言,因此任何使用此语言的页面在 URL 中都不会带有前缀。 例如,考虑以下配置:
site.use(multilanguage({
languages: ["en", "gl", "es"], // 可用语言
defaultLanguage: "en", // 默认语言
}));
现在,页面将导出为 /about-me/
和 /gl/acerca-de-min/
。 英文版本没有 /en/
前缀,因为它是默认语言。
创建指向翻译版本的链接
自动 rel=alternate 链接
由于此插件检测每个页面的不同语言版本,它会自动在每个页面中插入 <link rel="alternate" hreflang="{lang}" href="{url}" />
元素。例如:
<!DOCTYPE html>
<html lang="en">
<head>
<title>About me</title>
<link rel="alternate" hreflang="gl" href="/gl/acerca-de-min/" />
</head>
<body>
...
</body>
</html>
Note
如果 html
元素中缺少 lang
属性,则会自动插入。
创建语言切换菜单
该插件还公开了 alternates
变量,你可以使用它来构建一个菜单以更改当前页面的语言。 这是 Vento 中的一个示例:
<ul class="languages">
{{ for alt of alternates }}
<li>
<a href="{{ alt.url }}" {{ if alt.lang == lang }}aria-current="page"{{ /if }}>
{{ alt.title }} ({{ alt.lang }})
</a>
</li>
{{ /for }}
</ul>
此代码输出类似于以下内容:
<ul class="languages">
<li>
<a href="/about-me/" aria-current="page">
About me (en)
</a>
</li>
<li>
<a href="/sobre-min/">
Sobre min (gl)
</a>
</li>
<li>
<a href="/acerca-de-mi/">
Acerca de mí (es)
</a>
</li>
</ul>
链接到当前语言的页面
获取当前语言中特定页面的 URL 的最简单方法是使用 id 和 search.page() 并以当前语言作为过滤器。
---
id: home
---
{{ set about = search.page('id=about lang=' + lang) }}
<a href="{{ about.url }}">About</a> <!-- 这将始终输出当前语言的翻译 URL -->
---
id: about
---
<p>This is an About page</p>
Sitemap
Sitemap 插件 与此插件兼容,因此生成的站点地图将包含页面的翻译版本。
x-default 链接
此插件支持 x-default
值,用于不匹配的语言。 此选项对于为语言设置与你网站的任何本地化版本都不匹配的用户指定后备页面很有用。
- 你可以链接到语言选择器页面。
- 或者链接到当前页面的任何翻译版本。
要生成 x-default
链接,请在你的 front matter 中创建 unmatchedLangUrl
值:
lang: gl
unmatchedLangUrl: /language-selector/
在此示例中,此页面将具有指向 /language-selector/
页面的 x-default
链接。 你可以将此变量保存在 _data
文件中,以将此值应用于所有页面。
或者,你可以将可用的语言之一指定为 x-default
语言:
lang: gl
unmatchedLangUrl: en
在此示例中,x-default
链接将具有指向英文版本的 URL。
多语言数据
使用此插件,你可以拥有不同语言的数据,这些数据将根据每个页面的语言正确解析。 例如,假设我们为我们的站点提供了以下 _data.yml
文件,语言为 en
、gl
和 es
:
site_name: The Óscar's blog
gl:
site_name: O blog de Óscar
es:
site_name: El blog de Óscar
变量 site_name
对于语言 gl
和 es
具有不同的值。 任何存储在以可用语言之一命名的变量中的变量都被视为翻译。 我们可以在页面中使用 site_name
变量,其值将根据页面的语言而有所不同:
---
lang: en
---
<h1>{{ site_name }}</h1> <!-- 输出:The Óscar blog -->
---
lang: gl
---
<h1>{{ site_name }}</h1> <!-- 输出:O blog de Óscar -->
---
lang: es
---
<h1>{{ site_name }}</h1> <!-- 输出:El blog de Óscar -->
也可以使用对象来替换特定的内部值。 例如:
site:
name: The Óscar's blog
logo: /logo.png
# 仅翻译 site.name,但保留 site.logo 不变
gl:
site:
name: O blog de Óscar
es:
site:
name: El blog de Óscar
从单个文件创建多语言页面
使用此插件,可以多次导出同一页面,每种语言一次。 要将页面配置为多语言,只需将 lang
变量设置为包含可用语言的数组。 例如:
# 此页面有 3 种不同的语言:英语、加利西亚语和西班牙语。
lang: [en, gl, es]
title: About me
layout: base-layout.vto
Lume 将生成三个页面,每种语言一个页面,并在每个页面的输出路径前加上语言代码:
/en/about-me/index.html
/gl/about-me/index.html
/es/about-me/index.html
我们可以为每种语言分配不同的数据:
lang: [en, gl, es]
# 所有语言的通用值
layout: base-layout.vto
title: About me
url: /about-me/
# 加利西亚语翻译
gl:
title: Acerca de min
url: /sobre-min/
# 西班牙语翻译
es:
title: Acerca de mí
url: /acerca-de-mi/
Warning
这仅在页面级别有效。
多语言 + 分页
如果你的站点正在使用 paginate 插件,则以下示例展示了如何应用多语言:
export const layout = "layouts/my-layout.vto";
export default function* ({ search, paginate }) {
const langs = ["gl", "en"];
for (const lang of langs) {
const pages = search.pages(`type=article lang=${lang}`);
yield* paginate(pages, {
url: (n) => `/${lang}/articles/${n}/`,
each(page, number) {
page.lang = lang;
page.id = `articles-page-${number}`;
},
});
}
}
- 在此示例中,生成器正在生成所有语言的所有页面。
- 在
each
选项中,我们将lang
和id
值添加到新页面。 id
确保页面/gl/articles/1/
和/en/articles/1/
被视为相同内容的翻译,因为它们都具有相同的id
。