-
Notifications
You must be signed in to change notification settings - Fork 3
feat: Internationlization #120
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
Changes from all commits
95b456c
e4c7b9a
cbddc69
38b30f1
a42af38
fd4c654
e128481
da26c1b
6ab424e
c47453d
edfd17f
6b78bf8
971e831
bf9614a
9f22787
e3d5a25
5a48230
3ee0c86
aa9bbf3
25dd3a0
913bd9f
158279d
d682d15
3f29a15
935c64f
948dc37
ce3e042
df1ea42
30097d5
9c0bdc3
26bcf2a
be3786b
f2682b8
930917b
310616c
0bb5fe6
7e22832
1b3e577
a003792
56ece8c
9e9f53b
6a0df4a
e812448
48fd3e7
c4e7789
a74c229
c391fea
e83c5f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import fetch from 'node-fetch'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { info, error, debug } from '../src/utils/logger.js'; | ||
|
||
const TRANSLATIONS_DIR = path.join( process.cwd(), 'src/translations' ); | ||
const SUPPORTED_LOCALES = [ | ||
'ar', // Arabic | ||
'bg', // Bulgarian | ||
'bo', // Tibetan | ||
'ca', // Catalan | ||
'cs', // Czech | ||
'cy', // Welsh | ||
'da', // Danish | ||
'de', // German | ||
'en-au', // English (Australia) | ||
'en-ca', // English (Canada) | ||
'en-gb', // English (UK) | ||
'en-nz', // English (New Zealand) | ||
'en-za', // English (South Africa) | ||
'el', // Greek | ||
'es', // Spanish | ||
'es-ar', // Spanish (Argentina) | ||
'es-cl', // Spanish (Chile) | ||
'es-cr', // Spanish (Costa Rica) | ||
'fa', // Persian | ||
'fr', // French | ||
'gl', // Galician | ||
'he', // Hebrew | ||
'hr', // Croatian | ||
'hu', // Hungarian | ||
'id', // Indonesian | ||
'is', // Icelandic | ||
'it', // Italian | ||
'ja', // Japanese | ||
'ka', // Georgian | ||
'ko', // Korean | ||
'nb', // Norwegian (Bokmål) | ||
'nl', // Dutch | ||
'nl-be', // Dutch (Belgium) | ||
'pl', // Polish | ||
'pt', // Portuguese | ||
'pt-br', // Portuguese (Brazil) | ||
'ro', // Romainian | ||
'ru', // Russian | ||
'sk', // Slovak | ||
'sq', // Albanian | ||
'sr', // Serbian | ||
'sv', // Swedish | ||
'th', // Thai | ||
'tr', // Turkish | ||
'uk', // Ukrainian | ||
'ur', // Urdu | ||
'vi', // Vietnamese | ||
'zh-cn', // Chinese (China) | ||
'zh-tw', // Chinese (Taiwan) | ||
]; | ||
|
||
/** | ||
* Prepare translations for all supported locales. | ||
* | ||
* @param {boolean} force Whether to force download even if cache exists. | ||
* | ||
* @return {Promise<void>} A promise that resolves when translations are prepared. | ||
*/ | ||
async function prepareTranslations( force = false ) { | ||
if ( force ) { | ||
info( 'Ignoring cache, downloading translations...' ); | ||
} else { | ||
info( 'Verifying translations...' ); | ||
} | ||
|
||
for ( const locale of SUPPORTED_LOCALES ) { | ||
try { | ||
await downloadTranslations( locale, force ); | ||
} catch ( err ) { | ||
error( `✗ Failed to download translations for ${ locale }:`, err ); | ||
} | ||
} | ||
|
||
info( '✓ Translations ready!' ); | ||
} | ||
|
||
/** | ||
* Downloads translations for a specific locale from translate.wordpress.org. | ||
* | ||
* @param {string} locale The locale to download translations for. | ||
* @param {boolean} force Whether to force download even if cache exists. | ||
* | ||
* @return {Promise<void>} A promise that resolves when translations are downloaded. | ||
*/ | ||
async function downloadTranslations( locale, force = false ) { | ||
if ( ! force && hasValidTranslations( locale ) ) { | ||
debug( `Skipping download of cached translations for ${ locale }` ); | ||
return; | ||
} | ||
debug( `Downloading translations for ${ locale }...` ); | ||
|
||
const url = `https://translate.wordpress.org/projects/wp-plugins/gutenberg/dev/${ locale }/default/export-translations/?format=json`; | ||
const response = await fetch( url ); | ||
|
||
if ( ! response.ok ) { | ||
throw new Error( `Failed to download translations for ${ locale }` ); | ||
} | ||
|
||
const translations = await response.json(); | ||
const outputPath = path.join( TRANSLATIONS_DIR, `${ locale }.json` ); | ||
|
||
// Ensure the translations directory exists | ||
if ( ! fs.existsSync( TRANSLATIONS_DIR ) ) { | ||
fs.mkdirSync( TRANSLATIONS_DIR, { recursive: true } ); | ||
} | ||
|
||
// Write translations to file | ||
fs.writeFileSync( outputPath, JSON.stringify( translations, null, 2 ) ); | ||
debug( `✓ Downloaded translations for ${ locale }` ); | ||
} | ||
|
||
/** | ||
* Checks if translations exist and are valid for a specific locale. | ||
* | ||
* @param {string} locale The locale to check. | ||
* | ||
* @return {boolean} Whether valid translations exist. | ||
*/ | ||
function hasValidTranslations( locale ) { | ||
const filePath = path.join( TRANSLATIONS_DIR, `${ locale }.json` ); | ||
if ( ! fs.existsSync( filePath ) ) { | ||
return false; | ||
} | ||
|
||
try { | ||
const content = fs.readFileSync( filePath, 'utf8' ); | ||
const translations = JSON.parse( content ); | ||
return translations && typeof translations === 'object'; | ||
} catch ( err ) { | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* Main entry point for the script. | ||
* Parses command line arguments and downloads translations. | ||
*/ | ||
const forceDownload = | ||
process.argv.includes( '--force' ) || process.argv.includes( '-f' ); | ||
|
||
prepareTranslations( forceDownload ).catch( ( err ) => { | ||
error( 'Failed to prepare translations:', err ); | ||
process.exit( 1 ); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,11 @@ | |
value = "http://localhost:5173/" | ||
isEnabled = "NO"> | ||
</EnvironmentVariable> | ||
<EnvironmentVariable | ||
key = "GUTENBERG_EDITOR_REMOTE_URL" | ||
value = "http://localhost:5174/remote.html" | ||
isEnabled = "NO"> | ||
</EnvironmentVariable> | ||
Comment on lines
+59
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Disabled by default. Added to simplify testing the remote editor. |
||
</EnvironmentVariables> | ||
</LaunchAction> | ||
<ProfileAction | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,7 @@ private struct _EditorView: UIViewControllerRepresentable { | |
if #available(iOS 16.4, *) { | ||
viewController.webView.isInspectable = true | ||
} | ||
viewController.startEditorSetup() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding this required start call to the demo app was overlooked during #114. |
||
return viewController | ||
} | ||
|
||
|
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the same translations supported by Gutenberg Mobile.