Skip to content

Instantly share code, notes, and snippets.

@samuells
Last active April 3, 2019 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samuells/a2e84e4f790cef899ad1b8433ffec812 to your computer and use it in GitHub Desktop.
Save samuells/a2e84e4f790cef899ad1b8433ffec812 to your computer and use it in GitHub Desktop.
Little script to swap field translation of Storyblok content
'use strict'
const StoryblokClient = require('storyblok-js-client')
// ******* START
// YES&NO Prompt handler
// thx to https://www.npmjs.com/package/yesno
const options = {
yes: [ 'yes', 'y' ],
no: [ 'no', 'n' ]
}
function defaultInvalidHandler (question, defaultvalue, callback, yesvalues, novalues) {
process.stdout.write('\nInvalid Response.\n')
process.stdout.write('Answer either yes : (' + yesvalues.join(', ')+') \n')
process.stdout.write('Or no: (' + novalues.join(', ') + ') \n\n')
ask(question, defaultvalue, callback, yesvalues, novalues)
}
let invalidHandlerFunction = defaultInvalidHandler
function ask (question, defaultvalue, callback, yesvalues, novalues) {
if (!invalidHandlerFunction) {
invalidHandlerFunction = defaultInvalidHandler
}
yesvalues = yesvalues ? yesvalues : options.yes
novalues = novalues ? novalues : options.no
yesvalues = yesvalues.map(function (v) { return v.toLowerCase() })
novalues = novalues.map(function (v) { return v.toLowerCase() })
process.stdout.write(question + ' ')
process.stdin.setEncoding('utf8')
process.stdin.once('data', function (val) {
var result
var cleaned = val.trim().toLowerCase()
if (cleaned == '' && defaultvalue != null) {
result = defaultvalue
}
else if (yesvalues.indexOf(cleaned) >= 0) {
result = true
}
else if (novalues.indexOf(cleaned) >= 0) {
result = false
}
else {
invalidHandlerFunction(question, defaultvalue, callback, yesvalues, novalues)
return
}
process.stdin.unref()
callback(result)
}).resume()
}
// ******* END of YES&NO Handler
// Settings of script
let oauthToken = ""
let spaceId = "" // id of space where to swap content
let fromLang = "" // language from which will be copy content into default
let toLang = "" // language where will be copy content from default
let i18nComponentsFields = {} // translatable fields per page
let Storyblok
function addTransKeyFromComponent(component) {
// creates i18nComponentsFields
const compName = component.name
const compSchema = component.schema
const compKeys = Object.keys(compSchema)
let i18nKeys = []
compKeys.map( key => {
if (compSchema[key].translatable) {
i18nKeys.push(key)
}
})
i18nComponentsFields[compName] = i18nKeys
console.log(`✅ got all i18n fields of ${compName}`)
}
function swapContentOnStories(page=1) {
Storyblok.get(`spaces/${spaceId}/stories`, {
page
})
.then(response => {
response.data.stories.map(story => getStoryContent(story.id))
if (response.total - response.perPage * page > 0) {
swapContentOnStories(page + 1) // get all stories from Storyblok - response is paged!!
}
}).catch(error => {
console.log(error)
})
}
function getStoryContent(storyId) {
Storyblok.get(`spaces/${spaceId}/stories/${storyId}`, {})
.then(response => {
swapContentOfStory(response.data.story.content)
console.log(`✅ swapped content on ${response.data.story.name}`)
updateStory(storyId, response.data.story)
}).catch(error => {
console.log(error)
})
}
function swapContentOfStory(content) {
const i18nContentKeys = i18nComponentsFields[content.component]
const contentKeys = Object.keys(content)
contentKeys.map(key => {
if(i18nContentKeys && i18nContentKeys.includes(key)) {
content[`${key}__i18n__${toLang}`] = content[key]
// if no translation leave the default
content[key] = content[`${key}__i18n__${fromLang}`] ? content[`${key}__i18n__${fromLang}`] : content[key]
} else if (Array.isArray(content[key])) {
content[key].map(component => swapContentOfStory(component))
} else {
// Do nothing - not i18n field
}
})
}
function updateStory(storyId, updatedStory) {
Storyblok.put(`spaces/${spaceId}/stories/${storyId}`, {
"story": updatedStory,
"force_update": 1
}).then(response => {
console.log(`⬆️ successfully updated - [${response.data.story.name}] `)
}).catch(error => {
console.log(error)
})
}
// Run script
process.stdout.write('\x1B[2J\x1B[0f\u001b[0;0H'); // clear console/terminal
if (process.argv.length < 7) {
console.log('\x1b[31m%s\x1b[0m', `Error: Expected 4 argument:
- "oauthToken" - Managment API Token of user (not space) from Storyblok
- "spaceId" - if of space, where will the swap happen
- "fromLang" - which language will be set as default
- "toLang" - as which language will be set original default content`)
process.exit(1)
} else if(process.argv.indexOf('--token') > -1) {
const oauthTokenIndex = process.argv.indexOf('--token')
if (oauthTokenIndex > -1) {
oauthToken = process.argv[oauthTokenIndex + 1]
spaceId = process.argv[oauthTokenIndex + 2]
fromLang = process.argv[oauthTokenIndex + 3]
toLang = process.argv[oauthTokenIndex + 4]
}
if (fromLang === toLang) {
console.log('\x1b[31m%s\x1b[0m', `Error: "fromLang" and "toLang" are equal!`)
process.exit(1)
}
ask(`Are you sure you want to:
- move default language content into '${toLang}' translation
- '${fromLang}' translation set as default?`, true, function (ok) {
if (ok) {
console.log("🚚 🚚 🚚 🚚 ... moving content ... ");
// Initialize the client with the oauth token
Storyblok = new StoryblokClient({
oauthToken // user Auth Token from Storyblok
})
// Get schemas of all components
Storyblok.get(`spaces/${spaceId}/components`, {})
.then(response => {
response.data.components.map(component => addTransKeyFromComponent(component))
// After get of all translatable fields start content swapping
swapContentOnStories(1)
}).catch(error => {
console.log(error)
})
} else {
console.log("\x1b[34m%s\x1b[0m", "Okey, no swapping today!");
process.exit(1)
}
});
}
@samuells
Copy link
Author

samuells commented Apr 3, 2019

This script assume Arrays are not translatable.

eg. how to run it:

node ./swapContentTranslations.js --token {oauthToken} {spaceID} {fromLang} {toLang}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment