GitHub - Flinesoft/BartyCrouch: Localization/I18n: Incrementally update/translat...
source link: https://github.com/Flinesoft/BartyCrouch
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
README.md
Installation • Configuration • Usage • Build Script • Migration Guides • Issues • Contributing • License
BartyCrouch
BartyCrouch incrementally updates your Strings files from your Code and from Interface Builder files. "Incrementally" means that BartyCrouch will by default keep both your already translated values and even your altered comments. Additionally you can also use BartyCrouch for machine translating from one language to 60+ other languages. Using BartyCrouch is as easy as running a few simple commands from the command line what can even be automated using a build script within your project.
Requirements
- Xcode 10.1+ & Swift 4.2+
- Xcode Command Line Tools (see here for installation instructions)
Getting Started
Installation
Via [Homebrew](https://brew.sh/)To install Bartycrouch the first time, simply run the command:
brew install bartycrouch
To update to the newest version of BartyCrouch when you have an old version already installed run:
brew upgrade bartycrouch
To install or update to the latest version of BartyCrouch simply run this command:
mint install Flinesoft/BartyCrouch
Configuration
To configure BartyCrouch for your project, first create a configuration file within your projects root directory. BartyCrouch can do this for you:
bartycrouch init
Now you should have a file named .bartycrouch.toml
with the following contents:
[update] tasks = ["interfaces", "code", "transform", "normalize"] [update.interfaces] path = "." defaultToBase = false ignoreEmptyStrings = false unstripped = false [update.code] codePath = "." localizablePath = "." defaultToKeys = false additive = true unstripped = false [update.transform] codePath = "." localizablePath = "." transformer = "foundation" supportedLanguageEnumPath = "." typeName = "BartyCrouch" translateMethodName = "translate" [update.normalize] path = "." sourceLocale = "en" harmonizeWithSource = true sortByKeys = true [lint] path = "." duplicateKeys = true emptyValues = true
This is the default configuration of BartyCrouch and should work for most projects as is. In order to use BartyCrouch to its extent, it is recommended though to consider making the following changes:
- Provide more specific paths for any key containing
path
if possible. (e.g."App/Sources"
forcodePath
) - Remove the
code
task if your project is Swift-only and you use the newtransform
update task. - If you are using SwiftGen with the
structured-swift4
template, you will probably want to user thetransform
task and change itstransformer
option toswiftgenStructured
. - If you decided to use the
transform
task, create a new file in your project (e.g. underSupportingFiles
) namedBartyCrouch.swift
and copy the following code:
// // This file is required in order for the `transform` task of the translation helper tool BartyCrouch to work. // See here for more details: https://github.com/Flinesoft/BartyCrouch // import Foundation enum BartyCrouch { enum SupportedLanguage: String { // TODO: remove unsupported languages from the following cases list & add any missing languages case arabic = "ar" case chineseSimplified = "zh-Hans" case chineseTraditional = "zh-Hant" case english = "en" case french = "fr" case german = "de" case hindi = "hi" case italian = "it" case japanese = "ja" case korean = "ko" case malay = "ms" case portuguese = "pt-BR" case russian = "ru" case spanish = "es" case turkish = "tr" } static func translate(key: String, translations: [SupportedLanguage: String], comment: String? = nil) -> String { let typeName = String(describing: BartyCrouch.self) let methodName = #function print( "Warning: [BartyCrouch]", "Untransformed \(typeName).\(methodName) method call found with key '\(key)' and base translations '\(translations)'.", "Please ensure that BartyCrouch is installed and configured correctly." ) // fall back in case something goes wrong with BartyCrouch transformation return "BC: TRANSFORMATION FAILED!" } }
- If you don't develop in English as the first localized language, you should update the
sourceLocale
of thenormalize
task. - If you want to use the machine translation feature of BartyCrouch, add
translate
to the tasks list at the top and copy the following section into the configuration file withsecret
replaced by your Microsoft Translator Text API Subscription Key:
[update.translate] path = "." secret = "<#Subscription Key#>" sourceLocale = "en"
Usage
Before using BartyCrouch please make sure you have committed your code. Also, we highly recommend using the build script method described below.
bartycrouch
accepts one of the following sub commands:
update
: Updates your.strings
file contents according to your configuration.lint
: Checks your.strings
file contents for empty values & duplicate keys.
Also the following command line options can be provided:
-v
,--verbose
: Prints more detailed information about the executed command.-x
,--xcode-output
: Prints warnings & errors in Xcode compatible format.-w
,--fail-on-warnings
: Returns a failed status code if any warning is encountered.
update
subcommand
The update subcommand can be run with one or multiple of the following tasks:
interfaces
: Updates.strings
files of Storyboards & XIBs.code
: UpdatesLocalizable.strings
file fromNSLocalizedString
entries in code.transform
: A mode where BartyCrouch replaces a specific method call to provide translations in multiple languages in a single line. Only supports Swift files.translate
: Updates missing translations in other languages than the source language.normalize
: Sorts & cleans up.strings
files.
In order to configure which tasks are executed, edit this section in the config file:
[update] tasks = ["interfaces", "code", "transform", "normalize"]
path
: The directory to search for Storyboards & XIB files.defaultToBase
: Add Base translation as value to new keys.ignoreEmptyStrings
: Doesn't add views with empty values.unstripped
: Keeps whitespaces at beginning & end of Strings files.
codePath
: The directory to search for Swift code files.localizablePath
: The enclosing path containing the localizedLocalizable.strings
files.defaultsToKeys
: Add new keys both as key and value.additive
: Prevents cleaning up keys not found in code.customFunction
: Use alternative name toNSLocalizedString
.customLocalizableName
: Use alternative name forLocalizable.strings
.unstripped
: Keeps whitespaces at beginning & end of Strings files.
codePath
: The directory to search for Swift code files.localizablePath
: The enclosing path containing the localizedLocalizable.strings
files.transformer
: Specifies the replacement code. Usefoundation
forNSLocalizedString
orswiftgenStructured
forL10n
entries.supportedLanguageEnumPath
: The enclosing path containing theSupportedLanguage
enum.typeName
: The name of the type enclosing theSupportedLanguage
enum and translate method.translateMethodName
: The name of the translate method to be replaced.customLocalizableName
: Use alternative name forLocalizable.strings
.
path
: The directory to search for Strings files.secret
: Your Microsoft Translator Text API Subscription Key.sourceLocale
: The source language to translate from.
path
: The directory to search for Strings files.sourceLocale
: The source language to harmonize keys of other languages with.harmonizeWithSource
: Synchronizes keys with source language.sortByKeys
: Alphabetically sorts translations by their keys.
lint
subcommand
The lint subcommand was designed to analyze a project for typical translation issues. The current checks include:
duplicateKeys
: Finds duplicate keys within the same file.emptyValues
: Finds empty values for any language.
Note that the lint
command can be used both on CI and within Xcode via the build script method:
- In Xcode the
-x
or--xcode-output
command line argument should be used to get warnings which point you directly to the found issue. - When running on the CI you should specify the
-w
or--fail-on-warnings
argument to make sure BartyCrouch fails if any warnings are encountered.
Localization Workflow via transform
When the transform
update task is configured (see recommended step 4 in the Configuration section above) and you are using the build script method, you can use the following simplified process for writing localized code during development:
- Instead of
NSLocalizedString
calls you can useBartyCrouch.translate
and specify a key, translations (if any) and optionally a comment. For example:
self.title = BartyCrouch.translate(key: "onboarding.first-page.header-title", translations: [.english: "Welcome!"])
- Once you build your app, BartyCrouch will automatically add the new translation key to all your
Localizable.strings
files and add the provided translations as values for the provided languages. - Additionally, during the same build BartyCrouch will automatically replace the above call to
BartyCrouch.translate
with the proper translation call, depending on yourtransformer
option setting.
The resulting code depends on your transformer
option setting:
When set to foundation
, the above code will transform to:
self.title = NSLocalizedString("onboarding.first-page.header-title", comment: "")
When set to swiftgenStructured
it will transform to:
self.title = L10n.Onboarding.FirstPage.headerTitle
Advantages of transform
over the code
task:
- You can provide translations for keys without switching to the Strings files.
- In case you use SwiftGen, you don't need to replace calls to
NSLocalizedString
withL10n
calls manually after running BartyCrouch. - Can be combined with the machine translation feature to provide a source language translation in code and let BartyCrouch translate it to all supported languages in a single line & without ever leaving the code.
Disadvantages of transform
over the code
task:
- Only works for Swift Code. No support for Objective-C. (You can use both methods simultaneously though.)
- Xcode will mark the freshly transformed code as errors (but build will succeed anyways) until next build.
- Not as fast as
code
since SwiftSyntax currently isn't particularly fast. (But this should improve over time!)
NOTE: As of version 4.0.x of BartyCrouch formatted localized Strings are not supported by this automatic feature.
Build Script
In order to truly profit from BartyCrouch's ability to update & lint your .strings
files you can make it a natural part of your development workflow within Xcode. In order to do this select your target, choose the Build Phases
tab and click the + button on the top left corner of that pane. Select New Run Script Phase
and copy the following into the text box below the Shell: /bin/sh
of your new run script phase:
if which bartycrouch > /dev/null; then bartycrouch update -x bartycrouch lint -x else echo "warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch" fi
Next, make sure the BartyCrouch script runs before the steps Compiling Sources
(and SwiftGen
if used) by moving it per drag & drop, for example right after Target Dependencies
.
Now BartyCrouch will be run on each build and you won't need to call it manually ever (again). Additionally, all your co-workers who don't have BartyCrouch installed will see a warning with a hint on how to install it.
Note: Please make sure you commit your code using source control regularly when using the build script method.
Exclude specific Views / NSLocalizedStrings from Localization
Sometimes you may want to ignore some specific views containing localizable texts e.g. because their values are going to be set programmatically.
For these cases you can simply include #bartycrouch-ignore!
or the shorthand #bc-ignore!
into your value within your base localized Storyboard/XIB file. Alternatively you can add #bc-ignore!
into the field "Comment For Localizer" box in the utilities pane.
This will tell BartyCrouch to ignore this specific view when updating your .strings
files.
Here's an example of how a base localized view in a XIB file with partly ignored strings might look like:
Here's an example with the alternative comment variant:
You can also use #bc-ignore!
in your NSLocalizedString
macros comment part to ignore them so they are not added to your Localizable.strings
. This might be helpful when you are using a .stringsdict
file to handle pluralization (see docs).
For example you can do something like this:
func updateTimeLabel(minutes: Int) { String.localizedStringWithFormat(NSLocalizedString("%d minute(s) ago", comment: "pluralized and localized minutes #bc-ignore!"), minutes) }
The %d minute(s) ago
key will be taken from Localizable.stringsdict file, not from Localizable.strings, that's why it should be ignored by BartyCrouch.
Migration Guides
See the file MIGRATION_GUIDES.md.
Contributing
See the file CONTRIBUTING.md.
License
This library is released under the MIT License. See LICENSE for details.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK