Last active
October 1, 2018 20:27
-
-
Save HriBB/1fca4773651948741311a2ccda76d491 to your computer and use it in GitHub Desktop.
Gatsby i18next
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, Fragment } from 'react' | |
import Link from 'gatsby-link' | |
import { translate } from 'utils/i18n' | |
import About from 'components/About' | |
class AboutPage extends Component { | |
componentWillMount() { | |
this.props.setHeader('transparent') | |
} | |
render() { | |
return ( | |
<About {...this.props} /> | |
) | |
} | |
} | |
export default translate('About')(AboutPage) | |
export const query = graphql` | |
query About($lng: String!) { | |
locales: allLocale(filter: { lng: { eq: $lng }, ns: { eq: "About" } }) { | |
...LocaleFragment | |
} | |
laboratoryImage: imageSharp(id: { regex: "/photos/laboratory.jpg/" }) { | |
sizes(maxWidth: 1920 ) { | |
...GatsbyImageSharpSizes | |
} | |
} | |
} | |
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const path = require('path') | |
module.exports = { | |
siteMetadata: { | |
title: `Website`, | |
}, | |
plugins: [ | |
`gatsby-plugin-resolve-src`, | |
`gatsby-plugin-react-helmet`, | |
{ | |
resolve: `gatsby-source-filesystem`, | |
options: { | |
path: `${__dirname}/src/content`, | |
name: `content`, | |
}, | |
}, | |
{ | |
resolve: `gatsby-source-filesystem`, | |
options: { | |
path: `${__dirname}/src/images`, | |
name: `image`, | |
} | |
}, | |
{ | |
resolve: `gatsby-source-filesystem`, | |
options: { | |
path: `${__dirname}/src/locales`, | |
name: `locale`, | |
} | |
}, | |
{ | |
resolve: `gatsby-source-filesystem`, | |
options: { | |
path: `${__dirname}/src/pages`, | |
name: `locale`, | |
} | |
}, | |
{ | |
resolve: `gatsby-transformer-remark`, | |
options: { | |
plugins: [ | |
{ | |
resolve: `gatsby-remark-images`, | |
options: { | |
maxWidth: 1920, | |
maxHeight: 1920, | |
} | |
}, | |
{ | |
resolve: `gatsby-remark-responsive-iframe` | |
}, | |
`gatsby-remark-copy-linked-files` | |
] | |
} | |
}, | |
`gatsby-transformer-sharp`, | |
`gatsby-transformer-javascript-static-exports`, | |
{ | |
resolve: `gatsby-plugin-sharp`, | |
options: { | |
maxWidth: 1920, | |
quality: 75, | |
}, | |
}, | |
{ | |
resolve: `gatsby-plugin-sass`, | |
options: { | |
includePaths: [ | |
path.resolve(__dirname, './node_modules'), | |
path.resolve(__dirname, './src/styles'), | |
], | |
precision: 8, | |
}, | |
}, | |
{ | |
resolve: `gatsby-plugin-netlify-cms`, | |
options: { | |
modulePath: `${__dirname}/src/cms/cms.js`, | |
}, | |
}, | |
{ | |
resolve: `gatsby-plugin-favicon`, | |
options: { | |
logo: `./src/images/favicon.png`, | |
injectHTML: true, | |
icons: { | |
android: true, | |
appleIcon: true, | |
appleStartup: true, | |
coast: false, | |
favicons: true, | |
firefox: true, | |
twitter: false, | |
yandex: false, | |
windows: false, | |
}, | |
}, | |
}, | |
], | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const path = require(`path`) | |
const crypto = require(`crypto`) | |
const createSlug = require(`slug`) | |
const config = require('./src/config') | |
exports.createPages = async ({ boundActionCreators, graphql }) => { | |
const result = await graphql(` | |
{ | |
allMarkdownRemark( | |
sort: { order: DESC, fields: [frontmatter___date] } | |
limit: 1000 | |
) { | |
edges { | |
node { | |
fields { | |
lng | |
slug | |
type | |
} | |
frontmatter { | |
title | |
} | |
} | |
} | |
} | |
} | |
`) | |
if (result.errors) { | |
throw new Error(result.errors) | |
} | |
const { createPage } = boundActionCreators | |
result.data.allMarkdownRemark.edges.forEach(({ node }) => { | |
switch (node.fields.type) { | |
case `news`: | |
case `novice`: | |
createPage({ | |
path: node.fields.slug, | |
component: path.resolve(`src/templates/news.js`), | |
context: node.fields, | |
}) | |
break | |
case `parent-testimonials`: | |
case `izkusnje-starsev`: | |
createPage({ | |
path: node.fields.slug, | |
component: path.resolve(`src/templates/parent-testimonials.js`), | |
context: node.fields, | |
}) | |
break | |
} | |
}) | |
} | |
exports.onCreateNode = async (props) => { | |
const { node, boundActionCreators, loadNodeContent, getNode } = props | |
const { internal: { mediaType }, sourceInstanceName } = node | |
const { createNode, createNodeField, createParentChildLink } = boundActionCreators | |
// create locale node | |
if ( | |
node.internal.type === `File` && | |
sourceInstanceName === `locale` && | |
mediaType === `application/json` | |
) { | |
const content = await loadNodeContent(node) | |
const data = JSON.stringify(JSON.parse(content),undefined,'') | |
const contentDigest = crypto | |
.createHash(`md5`) | |
.update(data) | |
.digest(`hex`) | |
const localeNode = { | |
id: `${node.id} >>> Locale`, | |
children: [], | |
parent: node.id, | |
internal: { content, contentDigest, type: `Locale` }, | |
lng: node.relativeDirectory, | |
ns: node.name, | |
data, | |
} | |
localeNode.fileAbsolutePath = node.absolutePath | |
createNode(localeNode) | |
createParentChildLink({ parent: node, child: localeNode }) | |
} | |
// create content node fields | |
if ( | |
node.internal.type === `File` && | |
sourceInstanceName === `content` && | |
mediaType === `text/markdown` | |
) { | |
const [lng, type, dir] = node.relativeDirectory.split(`/`) | |
const name = dir.substr(dir.indexOf(` `) + 1, dir.length) | |
const prefix = lng === config.defaultLocale ? `` : `/${lng}` | |
const slug = `${prefix}/${type}/${createSlug(name)}/` | |
createNodeField({ node, name: `lng`, value: lng }) | |
createNodeField({ node, name: `slug`, value: slug }) | |
createNodeField({ node, name: `type`, value: type }) | |
} | |
// inherit content node fields on markdown nodes | |
if ( | |
node.internal.type === `MarkdownRemark` && | |
typeof node.slug === `undefined` | |
) { | |
const { fields: { lng, slug, type } } = getNode(node.parent) | |
createNodeField({ node, name: `lng`, value: lng }) | |
createNodeField({ node, name: `slug`, value: slug }) | |
createNodeField({ node, name: `type`, value: type }) | |
} | |
} | |
const router = { | |
'/': { | |
si: '/', | |
en: '/en/', | |
}, | |
'/about/': { | |
si: '/o-nas/', | |
en: '/en/about/', | |
}, | |
'/benefits/': { | |
si: '/prednosti/', | |
en: '/en/benefits/', | |
}, | |
'/donor-centers/': { | |
si: '/donorski-centri/', | |
en: '/en/donor-centers/', | |
}, | |
'/news/': { | |
si: '/novice/', | |
en: '/en/news/', | |
}, | |
'/parent-testimonials/': { | |
si: '/izkusnje-starsev/', | |
en: '/en/parent-testimonials/', | |
}, | |
'/pricing/': { | |
si: '/storitve-in-cene/', | |
en: '/en/pricing/', | |
}, | |
'/process/': { | |
si: '/postopek/', | |
en: '/en/process/', | |
}, | |
'/stem-cells/': { | |
si: '/maticne-celice/', | |
en: '/en/stem-cells/', | |
}, | |
'/why-bank/': { | |
si: '/zakaj-shraniti/', | |
en: '/en/why-bank/', | |
}, | |
} | |
exports.onCreatePage = async ({ page, boundActionCreators }) => { | |
const { createPage, deletePage } = boundActionCreators | |
const route = router[page.path] | |
if (!route) { | |
return | |
} | |
const { locales, defaultLocale } = config | |
const oldPage = Object.assign({}, page) | |
deletePage(oldPage) | |
locales.forEach(locale => { | |
page.path = route[locale] | |
page.context = { | |
lng: locale, | |
route, | |
} | |
createPage(page) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import i18n from 'i18next' | |
import config from 'config' | |
import { | |
reactI18nextModule, | |
translate as t, | |
} from 'react-i18next' | |
i18n | |
.use(reactI18nextModule) | |
.init({ | |
//debug: process.env.NODE_ENV === 'development', | |
fallbackLng: 'si', | |
ns: [], | |
interpolation: { | |
escapeValue: false, // code escaping in interpolated text is not needed with react | |
}, | |
react: { | |
wait: false, | |
}, | |
}) | |
export default i18n | |
export function withPathnameObserver(WrappedComponent) { | |
return class extends Component { | |
changePathname(pathname) { | |
const { locales, defaultLocale } = config | |
const locale = pathname.substr(1,2) | |
const language = locale && locales.indexOf(locale) > -1 ? locale : defaultLocale | |
if (i18n.language !== language) { | |
i18n.changeLanguage(language) | |
} | |
} | |
componentWillMount() { | |
this.changePathname(this.props.location.pathname) | |
} | |
componentWillUpdate(nextProps) { | |
if (this.props.location.pathname !== nextProps.location.pathname) { | |
this.changePathname(nextProps.location.pathname) | |
} | |
} | |
render() { | |
return <WrappedComponent {...this.props} />; | |
} | |
} | |
} | |
export function withLocales(WrappedComponent) { | |
return class extends Component { | |
componentWillMount() { | |
if (this.props.data.locales) { | |
this.props.data.locales.edges.forEach(({ node }) => { | |
const { lng, ns, data } = node | |
if (!i18n.hasResourceBundle(lng, ns)) { | |
i18n.addResources(lng, ns, JSON.parse(data)) | |
} | |
}) | |
} | |
} | |
render() { | |
return <WrappedComponent {...this.props} />; | |
} | |
} | |
} | |
export function translate(ns, options) { | |
return function Wrapper(WrappedComponent) { | |
return withLocales( | |
t(ns, options)(WrappedComponent) | |
) | |
} | |
} | |
export const localeFragment = graphql` | |
fragment LocaleFragment on LocaleConnection { | |
edges { | |
node { | |
id | |
lng | |
ns | |
data | |
} | |
} | |
} | |
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import { withLocales } from 'utils/i18n' | |
import Homepage from 'components/Homepage' | |
class IndexEn extends Component { | |
componentWillMount() { | |
this.props.setHeader('transparent') | |
} | |
render() { | |
console.log(this.props); | |
return ( | |
<Homepage {...this.props} /> | |
) | |
} | |
} | |
export default withLocales(IndexEn) | |
export const query = graphql` | |
query IndexEn($lng: String!) { | |
locales: allLocale(filter: { lng: { eq: $lng }, ns: { eq: "Homepage" } }) { | |
...LocaleFragment | |
} | |
homeImage: imageSharp(id: { regex: "/photos/home.jpg/" }) { | |
sizes(maxWidth: 1920 ) { | |
...GatsbyImageSharpSizes | |
} | |
} | |
} | |
`; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey! Did this work for you?