Skip to content

Add i18n and l10n with lingui and babel #772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"presets": [
"next/babel"
],
"plugins": ["@lingui/babel-plugin-lingui-macro"]
}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,12 @@ yarn-error.log*

.yarn
.vscode/

# Lingui
src/locales/**/*.mo
src/locales/**/*.js

# RSS
atom.xml
rss.json
rss.xml
17 changes: 17 additions & 0 deletions lingui.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const nextConfig = require('./next.config')

/** @type {import('@lingui/conf').LinguiConfig} */
module.exports = {
locales: nextConfig.i18n.locales,
pseudoLocale: 'pseudo',
sourceLocale: nextConfig.i18n.defaultLocale,
fallbackLocales: {
default: 'en',
},
catalogs: [
{
path: 'src/locales/{locale}/messages',
include: ['src/'],
},
],
}
6 changes: 6 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@ export default withMDX({
images: {
domains: ["raw.githubusercontent.com", "numpy.org", "dask.org", "chainer.org", ],
},
i18n: {
// These are all the locales you want to support in
// your application
locales: ["en", "es", "pt"],
defaultLocale: "en",
},
})
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"private": true,
"scripts": {
"build-cards": "node build-cards.js",
"dev": "next dev",
"build": "next build",
"extract": "lingui extract",
"compile": "lingui compile",
"dev": "yarn compile && next dev",
"build": "yarn extract && yarn compile && next build",
"start": "next start",
"lint": "next lint"
},
Expand All @@ -24,6 +26,8 @@
"@emotion/styled": "^11.13.0",
"@fontsource-variable/inter": "^5.2.5",
"@giscus/react": "^3.0.0",
"@lingui/core": "^5.0.0-next.2",
"@lingui/react": "^5.0.0-next.2",
"@mdx-js/loader": "^3.0.1",
"@mdx-js/react": "^3.0.1",
"@next/mdx": "^14.2.14",
Expand All @@ -46,6 +50,9 @@
"swr": "^2.2.5"
},
"devDependencies": {
"@lingui/babel-plugin-lingui-macro": "^5.0.0-next.2",
"@lingui/cli": "^5.0.0-next.2",
"@lingui/loader": "^5.0.0-next.2",
"@types/react": "^18.3.11",
"eslint": "^9.12.0",
"eslint-config-next": "14.2.14",
Expand Down
8 changes: 5 additions & 3 deletions src/components/array-libraries.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import React from 'react'
import { IoIosGlobe, IoLogoGithub } from 'react-icons/io'

import { Image } from '@/components/mdx'
import { Libraries as data } from '@/data/array-libraries'
import { getLibraries } from '@/data/array-libraries'

import { SocialLink } from '@/components/social-link'
import { useLingui } from '@lingui/react/macro'

const Library = ({ name, description, repo, url, logo }) => {
return (
Expand Down Expand Up @@ -41,12 +42,13 @@ const Library = ({ name, description, repo, url, logo }) => {
}

export const ArrayLibraries = () => {
const { t } = useLingui()
let data = getLibraries()
const libraries = React.useMemo(() => data, [])
return (
<Box my={8}>
<Text fontSize={'lg'}>
Xarray supports multiple array backends, allowing users to choose array
types that work best for their application.
{t`Xarray supports multiple array backends, allowing users to choose array types that work best for their application.`}
</Text>

<SimpleGrid
Expand Down
8 changes: 5 additions & 3 deletions src/components/dashboard/issue-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,27 @@ import { GiDuration } from 'react-icons/gi'
import { TimelinePlotContainer } from '@/components/dashboard/timeline-plot-container'
import { TimeseriesAggStatsCard } from '@/components/dashboard/timeseries-agg-stats-card'
import { Heading } from '@/components/mdx'
import { useLingui } from '@lingui/react/macro'

export const IssueTracker = () => {
const { t } = useLingui()
return (
<Box as='section' id='issue-tracker'>
<Container maxW='container.lg'>
<Heading as='h2' size='xl' textAlign={'center'}>
Xarray Issue Tracker
{t`Xarray Issue Tracker`}
</Heading>
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={{ base: 5, lg: 8 }}>
{' '}
<TimeseriesAggStatsCard
title={'Median time a pull request is open'}
title={t`Median time a pull request is open`}
query={
'https://xarray-datasette.fly.dev/github.json?_shape=array&&sql=select%0D%0A++id%2C%0D%0A++number%2C%0D%0A++state%2C%0D%0A++created_at%2C%0D%0A++closed_at%2C%0D%0A++julianday%28closed_at%29+-+julianday%28created_at%29+as+age_in_days%0D%0Afrom%0D%0A++issues+as+data%0D%0Awhere%0D%0A++type+%3D+%27pull%27%0D%0A++and+state+%3D+%27closed%27%0D%0Aorder+by%0D%0A++id'
}
icon={<GiDuration size={'3em'} />}
/>
<TimeseriesAggStatsCard
title={'Median time an issue is open'}
title={t`Median time an issue is open`}
icon={<GiDuration size={'3em'} />}
query={
'https://xarray-datasette.fly.dev/github.json?_shape=array&&sql=select%0D%0A++id%2C%0D%0A++number%2C%0D%0A++state%2C%0D%0A++created_at%2C%0D%0A++closed_at%2C%0D%0A++julianday%28closed_at%29+-+julianday%28created_at%29+as+age_in_days%0D%0Afrom%0D%0A++issues+as+data%0D%0Awhere%0D%0A++type+%3D+%27issue%27%0D%0A++and+state+%3D+%27closed%27%0D%0Aorder+by%0D%0A++id'
Expand Down
19 changes: 10 additions & 9 deletions src/components/dashboard/project-metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import { fetcher } from '@/lib/data-fetching'
import { Box, Container, SimpleGrid, Spinner } from '@chakra-ui/react'
import { BsPeople, BsPerson } from 'react-icons/bs'
import { GoBook, GoPackage, GoStar, GoTag } from 'react-icons/go'
import { useLingui } from '@lingui/react/macro'
import useSWR from 'swr'

export const ProjectMetrics = () => {
const { data, error } = useSWR(
'https://raw.githubusercontent.com/andersy005/xarray-datasette/a73704d803350a2ec059bec1b4cce601cd9efdd9/data/docs-monthly-views.json',
fetcher,
)

if (error) return <div>failed to load data</div>
const { t } = useLingui()
if (error) return <div>{t`failed to load data`}</div>
if (!data)
return (
<Spinner
Expand All @@ -36,17 +37,17 @@ export const ProjectMetrics = () => {
<Container maxW='container.lg'>
{' '}
<Heading as='h2' size='xl' textAlign={'center'}>
Xarray Project Metrics
{t`Xarray Project Metrics`}
</Heading>
<SimpleGrid columns={{ base: 1, md: 3 }} spacing={{ base: 5, lg: 8 }}>
<StatisticsCard
title={'Core Maintainers'}
title={t`Core Maintainers`}
stat={'15'}
icon={<BsPerson size={'3em'} />}
link={'https://docs.xarray.dev/en/stable/team.html'}
/>
<DatasetteStatsCard
title={'Contributors'}
title={t`Contributors`}
query={
'https://xarray-datasette.fly.dev/github/_analyze_tables_/contributors,user_id.json?_shape=array'
}
Expand All @@ -55,7 +56,7 @@ export const ProjectMetrics = () => {
/>

<DatasetteStatsCard
title={'Stargazers'}
title={t`Stargazers`}
icon={<GoStar size={'3em'} />}
query={
'https://xarray-datasette.fly.dev/github/_analyze_tables_/stars,user.json?_shape=array'
Expand All @@ -64,20 +65,20 @@ export const ProjectMetrics = () => {
/>

<StatisticsCard
title={'Dependent Packages/Repos'}
title={t`Dependent Packages/Repos`}
stat={21275}
icon={<GoPackage size={'3em'} />}
link={'https://github.com/pydata/xarray/network/dependents'}
/>

<StatisticsCard
title={`${month}/${year} Docs Visitors`}
title={t`Docs Visitors` + ` - ${month}/${year}`}
stat={monthlyViews.users}
icon={<GoBook size={'3em'} />}
/>

<DatasetteStatsCard
title={'Releases'}
title={t`Releases`}
query={
'https://xarray-datasette.fly.dev/github/_analyze_tables_/releases,id.json?_shape=array'
}
Expand Down
10 changes: 5 additions & 5 deletions src/components/dashboard/timeline-plot-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Tabs,
Text,
} from '@chakra-ui/react'
import { useLingui } from '@lingui/react/macro'
import * as d3 from 'd3'
import useSWR from 'swr'

Expand All @@ -18,8 +19,8 @@ export const TimelinePlotContainer = () => {
'https://pydata-datasette.fly.dev/open_pulls_and_issues.json?_shape=array&&sql=select%0D%0A++time%2C%0D%0A++open_issues%2C%0D%0A++open_pull_requests%0D%0Afrom%0D%0A++open_pulls_and_issues%0D%0Awhere%0D%0A++project+%3D+%27pydata%2Fxarray%27%0D%0Aorder+by%0D%0A++time',
fetcher,
)

if (error) return <div>failed to load data</div>
const { t } = useLingui()
if (error) return <div>{t`failed to load data`}</div>
if (!data)
return (
<Spinner
Expand All @@ -37,16 +38,15 @@ export const TimelinePlotContainer = () => {
return (
<Box my={8}>
<Text fontSize={'md'} align={'center'}>
This is a timeline of how many open issues and pull requests Xarray has
on Github over time from {new Date(start).toLocaleDateString()} to{' '}
{t`This is a timeline of how many open issues and pull requests Xarray has on Github over time from ${new Date(start).toLocaleDateString()} to `}
{new Date(end).toLocaleDateString()}.
</Text>
<br />
<br />
<Tabs align='center' variant='enclosed' isFitted colorScheme='teal'>
<TabList>
<Tab _selected={{ color: 'white', bg: 'teal.500' }}>
Pull Requests
{t`Pull Requests`}
</Tab>
<Tab _selected={{ color: 'white', bg: 'teal.500' }}>Issues</Tab>
</TabList>
Expand Down
11 changes: 7 additions & 4 deletions src/components/dashboard/timeseries-agg-stats-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import { Spinner, Text } from '@chakra-ui/react'
import * as d3 from 'd3'
import { isWithinInterval, lastDayOfMonth, startOfMonth } from 'date-fns'
import useSWR from 'swr'
import { useLingui } from '@lingui/react/macro'

export const TimeseriesAggStatsCard = ({ query, title, icon }) => {
const { t } = useLingui()
let { data, error } = useSWR(query, fetcher)
if (error) return <Text>failed to load</Text>
if (error) return <Text>{t`failed to load`}</Text>
if (!data)
return (
<Spinner
Expand Down Expand Up @@ -43,16 +45,17 @@ export const TimeseriesAggStatsCard = ({ query, title, icon }) => {

const change = {
type: diffPercentage < 0 ? 'increase' : 'decrease',
value: `${d3.format('.2f')(Math.abs(diffPercentage))}% since last month`,
value:
`${d3.format('.2f')(Math.abs(diffPercentage))}% ` + t`since last month`,
}
return (
<StatisticsCard
title={title}
icon={icon}
stat={
result <= 2
? `${d3.format('.1f')(result * 24)} hours`
: `${d3.format('.1f')(result)} days`
? `${d3.format('.1f')(result * 24)} ` + t`hours`
: `${d3.format('.1f')(result)} ` + t`days`
}
diff={change}
/>
Expand Down
18 changes: 10 additions & 8 deletions src/components/donate.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@ import {
Text,
} from '@chakra-ui/react'

import { LanguageSwitcher } from '@/components/language-switcher'

import { Heading, Image, Link } from '@/components/mdx'

import { BiDonateHeart } from 'react-icons/bi'
import { useLingui } from '@lingui/react/macro'

export const Donate = () => {
const { t } = useLingui()
return (
<Box id={'donate'} as='section'>
<Container maxW='container.lg' centerContent>
<Heading as='h1' size='2xl'>
Donate
{t`Donate`}
</Heading>
<SimpleGrid
columns={{ base: 1, md: 2 }}
Expand All @@ -33,7 +37,7 @@ export const Donate = () => {
position={'relative'}
>
<Text fontSize={'lg'}>
Xarray is a Sponsored Project of NumFOCUS, a{' '}
{t`Xarray is a NumFOCUS Sponsored Project, a `}
<Text
as={Link}
href={'https://en.wikipedia.org/wiki/501(c)(3)_organization'}
Expand All @@ -42,9 +46,9 @@ export const Donate = () => {
>
501(c)(3) nonprofit charity
</Text>{' '}
in the United States. NumFOCUS provides Xarray with fiscal, legal,
{t`in the United States. NumFOCUS provides Xarray with fiscal, legal,
and administrative support to help ensure the health and
sustainability of the project. Visit{' '}
sustainability of the project. For more information, visit `}
<Text
as={Link}
useExternalIcon
Expand All @@ -53,11 +57,9 @@ export const Donate = () => {
>
numfocus.org
</Text>{' '}
for more information.
<br />
<br />
If you like Xarray and want to support our mission, please
consider making a donation to support our efforts.
{t`If you like Xarray and want to support our mission, please consider making a donation to support our efforts.`}
</Text>
<Button
as={Link}
Expand All @@ -68,7 +70,7 @@ export const Donate = () => {
rightIcon={<BiDonateHeart />}
href={'https://numfocus.org/donate-to-xarray'}
>
Donate
{t`Donate`}
</Button>
</Stack>

Expand Down
Loading