以前の投稿Gatsbyで多言語のウェブサイトを作成し、kodou.meを作成しました。 鼓童には日本語版と英語版があります。 投稿は少し長かったので、私が使用したユーティリティのいくつかと、サイトのナビゲーションメニューを作成する方法については話しませんでした。
クイックサマリー
前回の投稿では、日本語と英語でサイトを構築しました。 サイトのデフォルト言語は英語です。 これは、2つのURLタイプがあることを意味します。
- 日本語のページ:
kodou.me/ja/team
- 英語のページ
kodou.me/team
さまざまなページバージョンがCosmicJSで記述されています。 Gatsbyに使用する言語を認識させます /config/languages
. の gatsby-node.js
、CosmicJSからのデータを入力したテンプレートを使用してページを作成します。
これは、 team-members
CosmicJSによって返される配列は次のようになります。
teamMembers = [
{
title: 'CEO',
fullName: 'Jack Misteli',
content: 'The CEO of the Company',
locale: 'en'
},
{
title: 'CEO',
fullName: 'ジャック・ミステリ',
content: '会社のCEO',
locale: 'ja'
}
]
受け取った後 teamMembers
2つのオブジェクトを作成します jaTeamMembers
と enTeamMembers
. 人口を増やす templates/team
と jaTeamMembers
作成する /ja/team
と enTeamMembers
作成する /team
.
サイトを言語対応にする
優れたWeb市民であり、私たちが作成するサイトにアクセスできるようにすることが重要です。 したがって、最初に行う必要があるのは、サイトのメタデータに言語を追加することです。 また、よりターゲットを絞った検索結果を得るのに役立つ場合があります。
module.export = {
siteMetadata: {
title: `Kodou`,
description: `Kodou site description`,
author: `Jack Misteli `,
languages
},
//....
Gatsbyアプリケーションでは、ページのコンテキストで現在の言語をテンプレートに渡します。
// 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')
module.exports = async (options, createPage, graphql) => {
const {query, pageName} = options
let templateName = options.templateName ? options.templateName : pageName
const result = await graphql(query)
if (result.errors)
console.error(result.errors)
const cosmicJSData = createLanguagesObject(langs)
Object.values(result.data)[0].edges.forEach(({ node }) => {
cosmicJSData[node.locale].push(node)
})
// 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],
// Here we pass the current language to the page
lang
}
})
})
}
これでアクセスできます lang
テンプレートで
const { lang } = props.pageContext;
国際化APIの使用
Intl API は、文字列の比較、数値の書式設定、および日付と時刻の書式設定に使用されます。 ここでは取り上げないクールな機能がたくさんあります。 ここでは、日付を適切な形式で表示するために使用します。
追加しています react-intl
私たちのパッケージ Layout
ファイル。
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import "../styles/main.scss"
import Header from "./header"
import { IntlProvider, FormattedDate } from "react-intl"
const Layout = ({ children, location, lang }) => {
// We populated the siteMetaData in `gatsby-config.js` and are extracting it here for some extra language context
// The best practice here would be to directly get that data from `config` but I want to show different ways to do it
const data = useStaticQuery(graphql`
query SiteInfoQuery {
site {
siteMetadata {
title
languages {
defaultLang
langs
}
}
}
}
`)
// langs is an array of all the supported languages
// defaultLang is the default site language
// title is the website's title
const {langs, defaultLang, title} = data.site.siteMetadata
return (
// We use IntlProvider to set the default language of our page
<IntlProvider
locale={lang}
defaultLocale={defaultLang}
>
<Header
location={location}
defaultLang={defaultLang}
languages={langs}
siteTitle={title} />
<main className="section">
<div className="container">
{children}
</div>
</main>
<footer>
<div className="footer">
<div className="content has-text-centered">
{/* FormattedDate will format our date according to the language we set in IntlProvider locale prop */}
© <FormattedDate value={new Date()}
year="numeric"
month="long"
day="numeric"
weekday="long" />, Built by
<a href="https://jmisteli.com"> Jack Misteli</a>
</div>
</div>
</footer>
</IntlProvider>
)
}
export default Layout
ページが英語で生成される場合、 <FormattedDate>
戻ります Monday, December 9, 2019
. ページが日本語で生成される場合 <FormattedDate>
戻ります 2019年12月9日月曜日
.
メニューの作成
あなたはそれを見ることができます Layout
私たちは Header
成分。 現在の言語プロパティを除くすべての言語情報をヘッダーに渡します。 ページの現在の言語への別の方法を紹介したいので、合格しません。
import { Link } from "gatsby"
import PropTypes from "prop-types"
import React from "react"
import { getCurrentLangKey, getLangs, getUrlForLang } from 'ptz-i18n'
import langmap from 'langmap'
import { localizeUrl, buildMenu } from '../../utils/localization'
const Header = ({ languages, location, defaultLang}) => {
const url = location.pathname
const currentLangKey = getCurrentLangKey(languages, defaultLang, url)
// Create a home link by adding a slash before the language and if it
const homeLink = localizeUrl(currentLangKey, defaultLang, '/')
// Get langs return language menu information
// langsMenu will allow us to build a dropdown with all the available language options
const langsMenu = buildMenu(languages, defaultLang, currentLangKey, url)
// On the `/team` page this will return the following array
// [{selected: true, link: "/team/", langKey: "en"},
// {selected: false, link: "/ja/team/", langKey: "ja"}]
// All the navigation menu item titles
const allLanguageTitles = {
'en':['Concept', 'Work', 'Team', 'News', 'Contact'],
'ja': ['コンセプト', '仕事', 'チーム', 'ニュース', '連絡先']
}
// Selecting the current language and default to english titles
const currentLanguageTitles = allLanguageTitles[currentLangKey] || allLanguageTitles['en']
// allNavigationLinks contains all the pages name, with urls in every supported language
const allNavigationLinks = currentLanguageTitles.map((page, i) => ({
name: page,
url: `${homeLink.replace(defaultLang, '')}${allLanguageTitles.en[i].toLowerCase()}`
}))
// On the English page it will return
// [{name: "Concept", url: "/concept"}, {name: "Work", url: "/work"}, {name: "Team", url: "/team"}...]
// [{name: "コンセプト", url: "/ja/concept"}, {name: "仕事", url: "/ja/work"}, {name: "チーム", url: "/ja/team"} ...]
return (
<nav>
<Link to={homeLink} className="navbar-item">
HOME
</Link>
{allLinks.map((link, i) => (
<Link key={i} to={link.url} className="navbar-item">
{link.name.toUpperCase()}
</Link>
))}
<div className="navbar-language-menu">
<div className="current-language">
// langmap is an object with the language keys as object keys and english, original versions of the language
{langmap[langKey]['englishName']}
</div>
<div className="all-languages-dropdown">
{langsMenu.map((lang)=>(
!lang.selected &&
<Link key={lang.langKey} to={lang.link} className="navbar-item">
{langmap[lang.langKey]['englishName']}
</Link>
))}
</div>
</div>
</nav>
)}
export default Header
これで、ユーザーの現在の言語に応じてリンクを調整するさまざまな言語のナビゲーションメニューが表示されます。 私が作成したユーティリティ関数を確認したい場合は、GitHubリポジトリで入手できます。