Skip to content
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

[gatsby-source-contentful]: Add fallback locale support #5328

Merged
merged 3 commits into from
May 10, 2018
Merged
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
18 changes: 12 additions & 6 deletions packages/gatsby-source-contentful/src/__tests__/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,17 @@ describe(`Gets field value based on current locale`, () => {
de: `Playsam Streamliner Klassisches Auto, Espresso`,
"en-US": `Playsam Streamliner Classic Car, Espresso`,
}
const locales = [
{ code: `en-US` },
{ code: `de`, fallbackCode: `en-US` },
{ code: `gsw_CH`, fallbackCode: `de` },
]
const localesFallback = normalize.buildFallbackChain(locales)
it(`Gets the specified locale`, () => {
expect(
normalize.getLocalizedField({
field,
defaultLocale: `en-US`,
localesFallback,
locale: {
code: `en-US`,
},
Expand All @@ -110,7 +116,7 @@ describe(`Gets field value based on current locale`, () => {
expect(
normalize.getLocalizedField({
field,
defaultLocale: `en-US`,
localesFallback,
locale: {
code: `de`,
},
Expand All @@ -125,7 +131,7 @@ describe(`Gets field value based on current locale`, () => {
expect(
normalize.getLocalizedField({
field: falseyField,
defaultLocale: `en-US`,
localesFallback,
locale: {
code: `en-US`,
},
Expand All @@ -135,7 +141,7 @@ describe(`Gets field value based on current locale`, () => {
expect(
normalize.getLocalizedField({
field: falseyField,
defaultLocale: `en-US`,
localesFallback,
locale: {
code: `de`,
},
Expand All @@ -146,7 +152,7 @@ describe(`Gets field value based on current locale`, () => {
expect(
normalize.getLocalizedField({
field,
defaultLocale: `en-US`,
localesFallback,
locale: {
code: `gsw_CH`,
fallbackCode: `de`,
Expand All @@ -158,7 +164,7 @@ describe(`Gets field value based on current locale`, () => {
expect(
normalize.getLocalizedField({
field,
defaultLocale: `en-US`,
localesFallback,
locale: {
code: `es-US`,
fallbackCode: `null`,
Expand Down
41 changes: 33 additions & 8 deletions packages/gatsby-source-contentful/src/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,35 @@ const digest = str =>
const typePrefix = `Contentful`
const makeTypeName = type => _.upperFirst(_.camelCase(`${typePrefix} ${type}`))

const getLocalizedField = ({ field, defaultLocale, locale }) => {
const getLocalizedField = ({ field, locale, localesFallback }) => {
if (!_.isUndefined(field[locale.code])) {
return field[locale.code]
} else if (!_.isUndefined(field[locale.fallbackCode])) {
return field[locale.fallbackCode]
} else if (
!_.isUndefined(locale.code) &&
!_.isUndefined(localesFallback[locale.code])
) {
return getLocalizedField({
field,
locale: { code: localesFallback[locale.code] },
localesFallback,
})
} else {
return null
}
}

const makeGetLocalizedField = ({ locale, defaultLocale }) => field =>
getLocalizedField({ field, locale, defaultLocale })
const buildFallbackChain = locales => {
const localesFallback = {}
_.each(
locales,
locale => (localesFallback[locale.code] = locale.fallbackCode)
)
return localesFallback
}
const makeGetLocalizedField = ({ locale, localesFallback }) => field =>
getLocalizedField({ field, locale, localesFallback })

exports.getLocalizedField = getLocalizedField
exports.buildFallbackChain = buildFallbackChain

// If the id starts with a number, left-pad it with a c (for Contentful of
// course :-))
Expand Down Expand Up @@ -202,8 +217,13 @@ exports.createContentTypeNodes = ({
}) => {
const contentTypeItemId = contentTypeItem.name
locales.forEach(locale => {
const localesFallback = buildFallbackChain(locales)
const mId = makeMakeId({ currentLocale: locale.code, defaultLocale })
const getField = makeGetLocalizedField({ locale, defaultLocale })
const getField = makeGetLocalizedField({
locale,
localesFallback,
defaultLocale,
})

// Warn about any field conflicts
const conflictFields = []
Expand Down Expand Up @@ -401,8 +421,13 @@ exports.createAssetNodes = ({
locales,
}) => {
locales.forEach(locale => {
const localesFallback = buildFallbackChain(locales)
const mId = makeMakeId({ currentLocale: locale.code, defaultLocale })
const getField = makeGetLocalizedField({ locale, defaultLocale })
const getField = makeGetLocalizedField({
locale,
localesFallback,
defaultLocale,
})

const localizedAsset = { ...assetItem }
// Create a node for each asset. They may be referenced by Entries
Expand Down