Skip to content
This repository has been archived by the owner on Mar 6, 2023. It is now read-only.

Localization support #18

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

Localization support #18

wants to merge 11 commits into from

Conversation

afenton90
Copy link

Adds support for localization in both the studio and web app.
Default supported languages are: English, Spanish, Norwegian

@afenton90 afenton90 requested a review from kmelve May 21, 2020 14:26
@afenton90 afenton90 added the enhancement New feature or request label May 21, 2020
Copy link
Member

@kmelve kmelve left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we’re there yet with the frontend? I wonder if we should add some sort of locale selector as well. Doesn't need to be fancy, a <select><option> in the main nav would suffice.

I also added dedicated localized example content to this branch.

Comment on lines 1 to 73
import {generateLocaleType, getLocaleTypeName, supportedLanguages} from './localize'

const localizedTypes = ['string', 'text', 'slug', 'portableText', 'simplePortableText']

const localizeField = (field, traceModified) => {
if (!localizedTypes.includes(field.type)) return field

const localizedField = {
...field,
type: getLocaleTypeName(field.type)
}

if (traceModified) {
traceModified.push(localizedField)
}

return localizedField
}

const inModified = name => field => field.name === name

export const localizeSupportedTypes = typeDef => {
const fieldsModified = []
const localizedDef = {...typeDef}

// Localize fields
if (localizedDef.fields) {
localizedDef.fields = localizedDef.fields.map(field => {
if (field.type === 'array') {
return {
...field,
of: field.of.map(localizeField)
}
}

return localizeField(field, fieldsModified)
})
}

// Localize any previews to first language
if (localizedDef.preview && localizedDef.preview.select && fieldsModified.length > 0) {
localizedDef.preview = {
...localizedDef.preview,
select: Object.keys(localizedDef.preview.select).reduce((select, key) => {
// Find any fields that have been modified and change name
let baseKey
const selectorToChange = localizedDef.preview.select[key]
if (selectorToChange.includes('.')) {
baseKey = selectorToChange.substring(0, selectorToChange.indexOf('.'))
} else {
baseKey = selectorToChange
}

if (!fieldsModified.find(inModified(baseKey))) {
select[key] = localizedDef.preview.select[key]
} else {
let prefix = selectorToChange
let suffix = ''
if (selectorToChange.includes('.')) {
prefix = selectorToChange.substring(0, selectorToChange.indexOf('.'))
suffix = selectorToChange.substring(selectorToChange.indexOf('.'))
}
select[key] = `${prefix}.${supportedLanguages[0].id}${suffix}`
}
return select
}, {})
}
}

return localizedDef
}

export default localizedTypes.map(generateLocaleType)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty clever, but I have a hard time deciding if it’s a bit too clever?

  1. If we are going with it, we should add comments to make it easier to parse what’s happening (it’s not that hard to guess from the code, but we need to keep in mind that we have many who are beginners).

  2. Although it’s nifty that you just add this to localize fields without having to actually change types in the other schema-fields, it also makes it a bit ”magic”. I didn't get what was happening at first. It’s also often the case that you don't want to localize all string fields. So we need to make it more obvious in the schema field, how you can add non-localized fields as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments to hopefully make it clearer what this function is doing

template/studio/localization/localize.js Show resolved Hide resolved
template/studio/schemas/documents/route.js Outdated Show resolved Hide resolved
siteConfig,
textSection,
]
.map(localizeSupportedTypes)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make it easy™ to opt a field type out if the localization?

Comment on lines 23 to 40

// Generate a page for each language
Object.keys(slug).forEach(lang => {
if (lang === '_type') return

const path = slug[lang].current === '/' ? `/${lang}` : `/${lang}/${slug[lang].current}`
obj[path] = {
query: {
slug: slug[lang].current,
lang: lang
},
includeInSitemap,
disallowRobot,
_createdAt,
_updatedAt,
page: '/LandingPage'
}
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get this to work, e.g. http://localhost:3000/en/about

@kmelve
Copy link
Member

kmelve commented May 26, 2020

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants