Skip to content
Permalink
Browse files

feature(www): Translate text through js-lingui (#21633)

* WIP lingui integration

* translate and extract more stuff

* remove extraneous

* add toggle text

* egghead embed

* fix tests

* rename lingui functions

* ignore translation files in typo check

* build lingui in onPreInit

* finish everything

* remove babelrc

* add husky

* add stuff

* redo navigation

* try to do something

* remove husky and lint-saged for now

* fix stuff

* move preset info to packages.json

* move preset to extractCoptions"

* reorganize i18n stuff

* fix locale provider

* move build logic
  • Loading branch information
tesseralis committed Mar 13, 2020
1 parent ccc474d commit aa5979c569796e0422010dbb57f795b23d8648ec
@@ -30,6 +30,7 @@ excluded_files:
- "**/*.ts"
- "**/*.jsx"
- "**/*.tsx"
- "*.po" # PO translation files
# Any typos we should ignore?
excluded_words:
- typoci
@@ -34,3 +34,7 @@ src/cache

# Env variables
.env*

# Lingui

Check warning on line 38 in www/.gitignore

Typo CI / TypoCheck

Lingui

"Lingui" is a typo. Did you mean "Linguine"?
src/data/locales/**/messages.js
src/data/locales/_build
@@ -1,6 +1,7 @@
const Promise = require(`bluebird`)
const fetch = require(`node-fetch`)
const fs = require(`fs-extra`)
const child_process = require(`child_process`)
const startersRedirects = require(`./starter-redirects.json`)
const yaml = require(`js-yaml`)
const redirects = yaml.load(fs.readFileSync(`./redirects.yaml`))
@@ -38,6 +39,10 @@ exports.onCreateNode = helpers => {
sections.forEach(section => section.onCreateNode(helpers))
}

exports.onPostBootstrap = () => {
child_process.execSync(`yarn lingui:build`)
}

exports.onPostBuild = () => {
fs.copySync(
`../docs/blog/2017-02-21-1-0-progress-update-where-came-from-where-going/gatsbygram.mp4`,
@@ -6,6 +6,7 @@
"dependencies": {
"@emotion/styled": "^10.0.23",
"@jamo/graphql-request": "2.0.2",
"@lingui/react": "^2.9.1",

Check warning on line 9 in www/package.json

Typo CI / TypoCheck

lingui

"lingui" is a typo. Did you mean "linguine"?
"@loadable/component": "^5.11.0",
"@mdx-js/mdx": "^1.5.1",
"@reach/skip-nav": "^0.6.2",
@@ -110,6 +111,26 @@
"license": "MIT",
"main": "n/a",
"private": true,
"lingui": {

Check warning on line 114 in www/package.json

Typo CI / TypoCheck

lingui

"lingui" is a typo. Did you mean "linguine"?
"sourceLocale": "en",
"extractBabelOptions": {
"presets": [
"babel-preset-gatsby"
]
},
"localeDir": "src/data/locales",
"srcPathDirs": [
"src/components",
"src/pages",
"src/templates",
"src/views"
],
"srcPathIgnorePatterns": [
"__tests__"
],
"format": "po",
"sorting": "origin"
},
"scripts": {
"build": "gatsby build",
"deploy": "gatsby build --prefix-paths && gh-pages -d public",
@@ -121,11 +142,19 @@
"scrapeStarters": "cd src/data/StarterShowcase && node scraper.js",
"stylelint": "stylelint './src/**/*.js'",
"forestry:preview": "gatsby develop -p 8080 -H 0.0.0.0",
"postinstall": "cd plugins/gatsby-transformer-gatsby-api-calls && npm install"
"postinstall": "cd plugins/gatsby-transformer-gatsby-api-calls && npm install",
"lingui:add-locale": "lingui add-locale",

Check warning on line 146 in www/package.json

Typo CI / TypoCheck

lingui

"lingui" is a typo. Did you mean "linguine"?
"lingui:extract": "lingui extract",

Check warning on line 147 in www/package.json

Typo CI / TypoCheck

lingui

"lingui" is a typo. Did you mean "linguine"?
"lingui:compile": "lingui compile",

Check warning on line 148 in www/package.json

Typo CI / TypoCheck

lingui

"lingui" is a typo. Did you mean "linguine"?
"lingui:build": "yarn lingui:extract && yarn lingui:compile"

Check warning on line 149 in www/package.json

Typo CI / TypoCheck

lingui

"lingui" is a typo. Did you mean "linguine"?
},
"devDependencies": {
"@lingui/cli": "^2.9.1",

Check warning on line 152 in www/package.json

Typo CI / TypoCheck

lingui

"lingui" is a typo. Did you mean "linguine"?
"@lingui/macro": "^2.9.1",

Check warning on line 153 in www/package.json

Typo CI / TypoCheck

lingui

"lingui" is a typo. Did you mean "linguine"?
"@testing-library/react": "^8.0.9",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^24.9.0",
"babel-plugin-macros": "^2.8.0",
"babel-preset-gatsby": "^0.2.23",
"cross-env": "^5.2.1",
"front-matter": "^2.3.0",
@@ -0,0 +1,22 @@
import React from "react"
import { defaultLang } from "../utils/i18n"
import { I18nProvider as LinguiProvider } from "@lingui/react"

// Lingui doesn't give access to the locale, so we need our own provider
// to pass it down to child components
const LocaleContext = React.createContext(defaultLang)

export function I18nProvider({ locale = defaultLang, children }) {
const catalog = require(`../data/locales/${locale}/messages.js`)
return (
<LocaleContext.Provider value={locale}>
<LinguiProvider language={locale} catalogs={{ [locale]: catalog }}>
{children}
</LinguiProvider>
</LocaleContext.Provider>
)
}

export function useLocale() {
return React.useContext(LocaleContext)
}
@@ -1,6 +1,8 @@
import React from "react"
import styled from "@emotion/styled"
import { useColorMode } from "theme-ui"
import { t } from "@lingui/macro"
import { withI18n } from "@lingui/react"

import { mediaQueries } from "gatsby-design-tokens/dist/theme-gatsbyjs-org"

@@ -123,26 +125,27 @@ const MoonMask = styled.div`
width: 24px;
`

function DarkModeToggle() {
function DarkModeToggle({ i18n }) {
const [colorMode, setColorMode] = useColorMode()
const isDark = colorMode === `dark`

function toggleColorMode(event) {
event.preventDefault()
setColorMode(isDark ? `light` : `dark`)
}
const label = isDark ? t`Activate light mode` : t`Activate dark mode`

This comment has been minimized.

Copy link
@armujahid

armujahid Mar 21, 2020

Member

You forgot to call i18n._() here :) I am going to raise a PR to fix this.


return (
<IconWrapper
isDark={isDark}
onClick={toggleColorMode}
aria-label={isDark ? `Activate light mode` : `Activate dark mode`}
title={isDark ? `Activate light mode` : `Activate dark mode`}
aria-label={label}
title={label}
>
<MoonOrSun isDark={isDark} />
<MoonMask isDark={isDark} />
</IconWrapper>
)
}

export default DarkModeToggle
export default withI18n()(DarkModeToggle)
@@ -1,7 +1,11 @@
/** @jsx jsx */
import { jsx } from "theme-ui"
import { Link } from "gatsby"
import { colors, mediaQueries } from "gatsby-design-tokens/dist/theme-gatsbyjs-org"
import { Trans } from "@lingui/macro"
import {
colors,
mediaQueries,
} from "gatsby-design-tokens/dist/theme-gatsbyjs-org"

function isUnderDepthLimit(depth, maxDepth) {
if (maxDepth === null) {
@@ -86,7 +90,7 @@ function TableOfContents({ page, location }) {
textTransform: `uppercase`,
}}
>
Table of Contents
<Trans>Table of Contents</Trans>
</h2>
<ul
sx={{
@@ -1,4 +1,5 @@
import React from "react"
import { Trans } from "@lingui/macro"

import docsHierarchy from "../data/sidebars/doc-links.yaml"
import tutorialHierarchy from "../data/sidebars/tutorial-links.yaml"
@@ -42,7 +43,9 @@ const GuideList = ({ slug }) => {
))
const toc = subitemList.length ? (
<>
<h2>In this section:</h2>
<h2>
<Trans>In this section:</Trans>
</h2>
<ul>{subitemList}</ul>
</>
) : null
@@ -3,7 +3,6 @@ import { jsx } from "theme-ui"
import React from "react"

import { Global } from "@emotion/core"
import { IconContext } from "react-icons"

import { globalStyles } from "../utils/styles/global"
import { breakpointGutter } from "../utils/styles"
@@ -13,37 +12,40 @@ import MobileNavigation from "./navigation-mobile"
import SiteMetadata from "./site-metadata"
import SkipNavLink from "./skip-nav-link"
import "../assets/fonts/futura"
import { defaultLang } from "../utils/i18n"

export const LocaleContext = React.createContext(defaultLang)
export default function DefaultLayout({ location, children }) {
if (location.state?.isModal) {
return (
<>
<SiteMetadata pathname={location.pathname} />
{children}
</>
)
}

export default function DefaultLayout({ location, locale, children }) {
return (
<IconContext.Provider value={{ style: { verticalAlign: "middle" } }}>
<LocaleContext.Provider value={locale || defaultLang}>
<Global styles={globalStyles} />
<SiteMetadata pathname={location.pathname} locale={locale} />
<SkipNavLink />
<Banner />
<Navigation pathname={location.pathname} />
<div
className={`main-body docSearch-content`}
sx={{
px: `env(safe-area-inset-left)`,
pt: t => t.sizes.bannerHeight,
// make room for the mobile navigation
pb: t => t.sizes.headerHeight,
[breakpointGutter]: {
pt: t =>
`calc(${t.sizes.bannerHeight} + ${t.sizes.headerHeight})`,
pb: 0,
},
}}
>
{children}
</div>
<MobileNavigation />
</LocaleContext.Provider>
</IconContext.Provider>
<>
<Global styles={globalStyles} />
<SiteMetadata pathname={location.pathname} />
<SkipNavLink />
<Banner />
<Navigation pathname={location.pathname} />
<div
className={`main-body docSearch-content`}
sx={{
px: `env(safe-area-inset-left)`,
pt: t => t.sizes.bannerHeight,
// make room for the mobile navigation
pb: t => t.sizes.headerHeight,
[breakpointGutter]: {
pt: t => `calc(${t.sizes.bannerHeight} + ${t.sizes.headerHeight})`,
pb: 0,
},
}}
>
{children}
</div>
<MobileNavigation />
</>
)
}
@@ -1,11 +1,11 @@
import React from "react"
import { Link } from "gatsby"
import { LocaleContext } from "./layout"
import { useLocale } from "./I18nContext"
import { localizedPath } from "../utils/i18n"

// Use the globally available context to choose the right path
const LocalizedLink = ({ to, ...props }) => {
const locale = React.useContext(LocaleContext)
const locale = useLocale()

return <Link {...props} to={localizedPath(locale, to)} />
}
@@ -1,6 +1,7 @@
/** @jsx jsx */
import { jsx } from "theme-ui"
import React from "react"
import { Trans } from "@lingui/macro"
import { graphql } from "gatsby"
import { MdCreate as EditIcon } from "react-icons/md"

@@ -20,9 +21,9 @@ export default class MarkdownPageFooter extends React.Component {
this.props.packagePage ? `packages` : `docs`
}/${this.props.page ? this.props.page.parent.relativePath : ``}`}
>
<EditIcon sx={{ marginRight: 2 }} />
{` `}
Edit this page on GitHub
<Trans>
<EditIcon sx={{ marginRight: 2 }} /> Edit this page on GitHub
</Trans>
</a>
)}
</>
@@ -1,6 +1,8 @@
/** @jsx jsx */
import { jsx } from "theme-ui"
import { Link } from "gatsby"
import { t } from "@lingui/macro"
import { withI18n } from "@lingui/react"

import {
BlogIcon,
@@ -39,8 +41,15 @@ const MobileNavItem = ({ linkTo, label, icon }) => (
<div>{label}</div>
</Link>
)
const navItems = [
{ id: "docs", text: t`Docs`, icon: DocsIcon },
{ id: `tutorial`, text: t`Tutorials`, icon: TutorialIcon },
{ id: `plugins`, text: t`Plugins`, icon: PluginsIcon },
{ id: `blog`, text: t`Blog`, icon: BlogIcon },
{ id: `showcase`, text: t`Showcase`, icon: ShowcaseIcon },
]

const MobileNavigation = () => (
const MobileNavigation = ({ i18n }) => (
<div
sx={{
alignItems: `center`,
@@ -62,15 +71,18 @@ const MobileNavigation = () => (
},
}}
>
<MobileNavItem linkTo="/docs/" label="Docs" icon={DocsIcon} />
<MobileNavItem linkTo="/tutorial/" label="Tutorials" icon={TutorialIcon} />
<MobileNavItem linkTo="/plugins/" label="Plugins" icon={PluginsIcon} />
<MobileNavItem linkTo="/blog/" label="Blog" icon={BlogIcon} />
<MobileNavItem linkTo="/showcase/" label="Showcase" icon={ShowcaseIcon} />
{navItems.map(({ id, text, icon }) => (
<MobileNavItem
linkTo={`/${id}/`}
key={id}
text={i18n._(text)}
icon={icon}
/>
))}
</div>
)

export default MobileNavigation
export default withI18n()(MobileNavigation)

const styles = {
svg: {

0 comments on commit aa5979c

Please sign in to comment.
You can’t perform that action at this time.