本文共 9836 字,大约阅读时间需要 32 分钟。
A friend recently asked me to build a website which has a Japanese and an English version. I never wrote an internationalized website but I have strong opinions about how localization should work. So here is one way to approach internationalization in Gatsby using Cosmic JS, a headless CMS.
最近有一个朋友要我建立一个日文和英文版本的网站。 我从未写过国际化的网站,但对本地化的工作方式有强烈的意见。 因此,这是使用Cosmic JS(无头CMS)在盖茨进行国际化的一种方法。
There are many ways to approach localization and as always there is no silver bullet. Each approach solves the problem in different ways. So here is my context:
有许多方法可以实现本地化,而且一如既往没有灵丹妙药。 每种方法都以不同的方式解决问题。 所以这是我的上下文:
This last point is so important to me. When you are in a foreign country, some websites force you to use the local version of their site. When [array of multinational companies]
forces me to the [long array of languages I don't understand]
version of the website it drives me mad. I have the same issue with automatic translations of a page. If I want an automatic translation of my website, I can use the fantastic .
最后一点对我很重要。 当您在国外时,某些网站会强迫您使用其网站的本地版本。 当[array of multinational companies]
迫使我进入网站的[long array of languages I don't understand]
版本时,我发疯了。 我对页面的自动翻译有相同的问题。 如果我想自动翻译网站,可以使用出色的 。
This website is for both Japanese and English users. So all the pages of the site should have an English version and a Japanese version. If the user wants to change the current version of the website she can click a language menu in the navigation bar.
该网站面向日语和英语用户。 因此,该网站的所有页面均应具有英文版和日文版。 如果用户想要更改网站的当前版本,则可以单击导航栏中的语言菜单。
Gatsby and React offer .
Gatsby和React提供了 。
I first used to easily generate routes.
我首先使用轻松生成路由。
For example, /page/team.ja.js
will generate the following URL: /ja/team
(ja
is the language code for Japan).
例如,/ /page/team.ja.js
/ja/team
/page/team.ja.js
将生成以下URL: /ja/team
( ja
是日本的语言代码)。
This is a really nice plugin but the problem is that it isn’t programmatic. I have to write a new file for each language. In each file, I have to make a specific GraphQL query to fetch the data. So for example, if I introduce a new language to my CMS I have to create all the routes again with the new language extension.
这是一个非常不错的插件,但是问题在于它不是编程的。 我必须为每种语言编写一个新文件。 在每个文件中,我必须进行特定的GraphQL查询以获取数据。 因此,例如,如果我在CMS中引入一种新语言,则必须使用新语言扩展名再次创建所有路由。
So instead, I decided to build l10n without any plugin. All the code for this project is available at .
因此,我决定构建没有任何插件的l10n。 该项目的所有代码都可以在 。
In this context, the content writer is fully responsible for localization. When she writes the Japanese version of the website, she should make sure that the date formats are correct. This is why we are not using react-intl
which relies on the Internationalization API and will be the topic of a future post.
在这种情况下,内容编写者完全负责本地化。 在撰写日语版网站时,应确保日期格式正确。 这就是为什么我们不使用依赖于国际化API的react-intl
原因,它将成为以后文章的主题。
Cosmic JS, a great headless CMS option, allows you do activate localization when you create a new object type.
Cosmic JS,一个很棒的无头CMS选项,允许您在创建新的对象类型时激活本地化。
Don’t forget to select a priority locale otherwise the new object won’t save.
不要忘记选择优先级语言环境,否则新对象将不会保存。
In our new site we have a team page so we create a Team Members object. When we create a new Team Member we now can choose its’ language.
在我们的新站点中,我们有一个团队页面,因此我们创建了一个“团队成员”对象。 现在,当我们创建新的团队成员时,我们可以选择其语言。
Now to access that data from Gatsby we need to add the gatsby-source-cosmicjs
source plugin:
现在,要从Gatsby访问数据,我们需要添加gatsby-source-cosmicjs
源插件:
$ yarn add gatsby-source-cosmicjs
Then we need to configure gatsby-config.js
to use gatsby-source-cosmicjs
by adding the following code in plugins
.
然后,我们需要通过在plugins
添加以下代码来配置gatsby-config.js
以使用gatsby-source-cosmicjs
。
{ resolve: "gatsby-source-cosmicjs", options: { bucketSlug: process.env.COSMIC_BUCKET, // We add the 'team-members' object type to be able to fetch it later objectTypes: ["team-members"], // If you have enabled read_key to fetch data (optional). apiAccess: { read_key: process.env.COSMIC_ENV_KEY, } }}
In the rest of our code we can access the team member data from Cosmic JS by running:
在我们的其余代码中,我们可以通过运行以下命令从Cosmic JS访问团队成员数据:
graphql(` { allCosmicjsTeamMembers { edges { # Here we have the structure of out `team-members` object node { title locale content metadata { profile_picture { imgix_url } } } } } }`)
Now the localization magic happens.
现在,本地化魔术发生了。
I wanted my friend to be able to do any changes he wanted by himself. So I completely dropped the /pages
directory in favor of the /templates
directory. Gatsby templates allow us to have reusable content and programmatically create pages; which is exactly what we need to do!
我希望我的朋友能够自己进行任何更改。 因此,我完全放弃了/pages
目录,转而使用/templates
目录。 Gatsby模板允许我们拥有可重用的内容并以编程方式创建页面; 这正是我们需要做的!
Before we look at our template file let’s see how we can fetch data from Cosmic JS to create new pages.
在查看模板文件之前,让我们看一下如何从Cosmic JS中获取数据以创建新页面。
// langs contains the languages of our blog and default langKey is the default language of the site// To be fully programmatic we could calculate langs// here langs = ['en', 'ja'] and defaultLangKey = 'en'const { langs, defaultLangKey } = require('../config/languages')const path = require(`path`)const { localizeUrl, createLanguagesObject } = require('../utils/localization')exports.createPages = async ({ actions, graphql }) => { const { createPage } = actions const result = await graphql(` { allCosmicjsTeamMembers { edges { node { title locale content metadata { profile_picture { imgix_url } } } } } } `) if (result.errors) { console.error(result.errors) } // Creates a profiles object with out site's languages const profiles = createLanguagesObject(langs) // profiles = { // 'en': [], // 'ja': [] // } // converting the raw cosmic data into a more useable data structure result.data.allCosmicjsTeamMembers.edges.forEach(({ node }) => { profiles[node.locale].push(node) }) // profiles = { // 'en': [...all English profiles], // 'ja': [...all Japanese profiles] // } // we create a new page for each language langs.forEach(lang =>{ createPage({ // the localizeUrl function creates a url which takes into consideration what the default language is path: localizeUrl(lang, defaultLangKey, '/team'), component: path.resolve(`src/templates/team.js`), context: { profiles: profiles[lang] } }) })}
This code will create two new pages with the paths /ja/team
and /team
(There is no /en
since we set English as the default language).
此代码将创建两个新页面,其路径分别为/ja/team
和/team
(因为我们将英语设置为默认语言,所以没有/en
)。
As you can see the createPage
takes as an argument an object with 3 fields path
, component
and context
. Path is simply the path we want our new page to have. component
is the template we want to use. context
is the data we want to pass to our template. Here we pass the profiles written in our desired language.
如您所见, createPage
将具有3个字段path
, component
和context
的对象作为参数。 路径只是我们希望新页面拥有的路径。 component
是我们要使用的模板。 context
是我们要传递给模板的数据。 在这里,我们传递以所需语言编写的配置文件。
Let’s take a look at our team template.
让我们看一下我们的团队模板。
import React from "react"import Layout from "../components/layout"import SEO from "../components/seo"const TeamPage = (props) => { // We will see about pageContext in the next section const {profiles} = props.pageContext return ()}export default TeamPage Team
// Iterating trough the array of profiles {profiles.map((profile,i)=>() )}// Here are some nice profile pictures of our team members{profile.title}// Here is some html content we get from Cosmic
To sum up, the code above takes a profiles
props which is an array of profiles we get from Cosmic JS. Each profile has a profile picture object, a title
and a content
field. The content
is actually a string of HTML so we have to set it using the dangerouslySetInnerHTML
prop.
综上所述,上面的代码采用了一个profiles
props,这是我们从Cosmic JS获得的profiles数组。 每个配置文件都有一个配置文件图片对象,一个title
和一个content
字段。 content
实际上是一串HTML,因此我们必须使用dangerouslySetInnerHTML
SetInnerHTML道具进行设置。
For this template to work, it’s important to prepare your CSS files in advance to get consistent results. My friend won’t be able to add class names or ids in Cosmic’s WYSIWYG.
为了使该模板正常工作,预先准备CSS文件以获得一致的结果很重要。 我的朋友无法在Cosmic的WYSIWYG中添加类名或ID。
There is much more to say and do:
还有更多要做的事情:
You can explore the to find out how I address these issues and see the results on . Or use Alligator.io to see if we uploaded some new content on that topic. But I think it’s already a lot to process in one post. Above I hope this will help a little or a lot to build your own internationalized site and stay tuned for more to come! 😉
您可以浏览以了解我如何解决这些问题,并在上查看结果。 或使用Alligator.io查看我们是否上传了有关该主题的一些新内容。 但是我认为在一篇文章中要处理的事情已经很多了。 在上面,我希望这对建立您自己的国际化站点有所帮助或有所帮助,并请继续关注更多! 😉
翻译自:
转载地址:http://mthgb.baihongyu.com/