By Samuel Chan

More Supported Languages for TextMaster Orders

When you order translations from TextMaster, you’ll now find support for more languages, including Brazilian Portuguese, Chinese (Hong Kong), Danish, Japanese, and Korean, among others.

textmaster-transifex

We’ve also added the Enterprise level as a translation quality option above Premium. The Enterprise tier is best suited for translating more complex content such as whitepapers, ebooks, advanced web content, and even legal documents.

Here’s the full list of 46 languages and 87 locales you can now order translations for: ar, ar-sa, bg, bg-bg, bs, bs-ba, ca, ca-es, cs, cs-cz, da, da-dk, de, de-de, el, el-gr, en, en-gb, en-us, es, es-es, es-sa, et, et-ee, fi, fi-fi, fr, fr-fr, he, he-il, hi, hi-in, hr, hr-hr, hu, hu-hu, id, id-id, is, is-is, it, it-it, ja, ja-jp, ko, ko-kr, lt, lt-lt, lv, lv-lv, mn, mn-mn, nl, nl-be, nl-nl, no, no-no, pl, pl-pl, pt, pt-br, pt-pt, ro, ro-ro, ru, ru-ru, sk, sk-sk, sl, sl-si, sq, sq-al, sr, sr-rs, sv, sv-se, th, th-th, tr, tr-tr, uk, uk-ua, vi, vi-vn, zh, zh-cn, zh-hk.

Happy translating!

Automating Transifex Updates with Jenkins

Jenkins, an Open Source continuous integration server, supports Transifex projects using a few simple shell commands. In this post, we’ll show you how to configure Jenkins to automatically synchronize with a Transifex project.

Jenkins Basics

Jenkins automates the process of running repeating tasks such as executing scripts or building software packages from source. Jenkins also monitors the status of running jobs, provides alerts, and integrates with external build services such as Maven and Ant.

Each job is assigned a workspace, which is a directory where copies of the job’s source files are stored. For instance, in Ubuntu, these directories fall under /var/lib/jenkins/workspace/. If your project is managed by source control, Jenkins will automatically pull the latest revision from your source repository. Otherwise, you’ll need to copy your source files to the job’s workspace after creating the new job in Jenkins.

Integrating Transifex

One of the benefits of Jenkins is that it can execute shell scripts during the build cycle. This makes it easy to integrate Transifex by simply calling the Transifex Client. Using tx push and tx pull, you can have Jenkins automatically update your source and translation files as the project is built.

Configuring Your Project

Before Jenkins can use the Transifex Client, it has to be able to read your project’s configuration. By default, the Transifex Client stores its configuration settings on a per-user basis. On a Linux environment, this is typically /home/<user>/.transifexrc. However, Jenkins executes commands as the Jenkins user. For instance, in Ubuntu, this means that any user-specific configuration files for Jenkins should be stored in /var/lib/jenkins/.

To configure your project for Jenkins, copy your transifexrc file to /var/lib/jenkins/.transifexrc. If you manage multiple jobs with Jenkins, you can store .transifexrc in the job’s workspace. Keep in mind that .transifexrc contains sensitive account information and shouldn’t be viewable by anyone but the Jenkins user.

You’ll also need to make sure that your project is configured to use the Transifex Client. Running tx init in your project folder will generate a .tx directory containing a configuration file. This configuration file tells the Transifex Client how to connect to your localization repository. Unlike the .transifexrc file, we recommend checking the .tx directory and config file into your source control repository. That way, when Jenkins checks out the project, it has everything it needs to connect to Transifex.

Configuring the Jenkins Job

Once you’ve granted Jenkins permission to access your Transifex project, you can configure your Jenkins job. As the job executes, Jenkins will call the Transifex client and update the project’s localization files.

Jenkins project

Navigate to the job’s configuration page. Under the “Build” section, click “Add build step”, and select “Execute shell”. A text box appears, allowing you to enter commands. Enter the following commands and click Save:

tx push -s
tx pull -a

Jenkins configuration

The next time a build occurs, Jenkins uses the Transifex Client to not only push your source files to Transifex, but also to pull the most recent translations into the build.

Modifying Downloaded Translation Files
If you need to further modify your language files before including them in the build, you can run additional commands by either adding new statements or by adding a new build step. You can perform any command-line task supported by the operating system running Jenkins, such as converting between file types or moving files to a separate directory. For instance, if you haven’t set up your project using a file expression, you’ll have to manually move your translation files into the target directory.

Handling Problems

Integrating Transifex with Jenkins is fairly straightforward, but problems can arise during the process. Two issues in particular are extremely common: file permissions, and build failures due to the Transifex Client.

File Permissions

As we mentioned earlier, the Jenkins user must have access to project files. If permissions aren’t properly assigned, this could result in opening Jenkins or your Transifex project to outside access. When copying files to a Jenkins workspace, make sure those files can only be modified by the Jenkins user. If you’re copying a .transifexrc file to the Jenkins workspace, make sure the file can only be read by the Jenkins user.

If you manage your project using version control, Jenkins will automatically fetch and store files as the Jenkins user. However, this does mean providing Jenkins with access to your source repository. Some version control systems such as Git allow you to use file permissions to prevent users from modifying checked out files. Alternatively, hosting providers such as GitHub provide advanced controls for limiting users’ ability to push to repositories.

Build Failures

Common causes of build failures are a missing .transifexrc file, or Jenkins not having the right permissions to read your project’s files. Make sure your .transifexrc file is not only stored in Jenkin’s configuration directory, but is also readable by the Jenkins user.

You should also make sure that your project configuration and source files can be read by Jenkins. If you copied your source files manually, you’ll need to grant permission to the Jenkins user to read and modify files in the project directory.

If the build continues to fail, try running the Transifex Client as the Jenkins user and viewing the immediate output. After logging into the Jenkins server, use the sudo command to temporarily switch to the Jenkins user:

$ sudo -iu jenkins cd /path/to/workspace && tx push -s

Any output from the Transifex Client will appear directly in the console. You can also view output from the Transifex Client by opening Jenkins, navigating to your project’s build history, and clicking on Console Output for the last build.

Additional Resources

Using the Transifex Client through Jenkins is the easiest way to ensure your builds are using the latest translations. You can also install the Transifex Plugin for Jenkins, which simply adds a hyperlink to the Transifex project page on the Jenkins job page.

Bridging GitHub and Transifex with Txgh

We previously showcased Txgh, a tool for automatically bridging GitHub with Transifex. Txgh is an Open Source Sinatra server that uses webhooks to trigger updates between GitHub and Transifex. It allows both developers and translators to share localization updates in an automated and seamless way. Changes to either a GitHub repository or a Transifex project are pushed to the Txgh server, which forwards them to Transifex or GitHub respectively.

Txgh has seen a lot of updates since its earlier release. Txgh can now run as a Heroku dyno for quick and easy deployment. The new release also supports branches, rather than limiting changes to master. Transifex will manage future updates to the project, but the project will remain open sourced. In this post, we’ll walk you through setting up the latest version of Txgh.

Getting Started with Txgh

Txgh requires an existing Heroku account. If you don’t already have one, you can sign up for a free account here. Txgh requires Ruby and Bundler, which you can install using this guide. Note that the Txgh project uses Ruby version 2.0.0, which we recommend installing using a version manager.

Download Txgh

To download Txgh, simply clone the latest version from GitHub:

$ git clone https://github.com/matthewjackowski/txgh.git
Cloning into 'txgh'...
remote: Counting objects: 162, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 162 (delta 0), reused 0 (delta 0), pack-reused 159
Receiving objects: 100% (162/162), 34.75 KiB | 0 bytes/s, done.
Resolving deltas: 100% (68/68), done.
Checking connectivity... done.

Configure Txgh

Txgh needs access to a GitHub account, a Transifex account, and information about the Transifex project being managed. Earlier versions of Txgh used a YAML file to store user credentials. With the latest version of Txgh, this information is stored as environment variables in Heroku. We’ll add these environment variables after deploying the server to Heroku.

In the meantime, we can provide Txgh with our Transifex project’s configuration. Copy the config file stored in your project’s .tx directory to Txgh’s config directory and rename it to tx.config. You should see three files in the directory: key_manager.rb, key_manager_ruby.rb, and tx.config. For more information on setting up your project configuration, click here.

Deploying to Heroku

Heroku provides a command-line tool for interacting with applications. When you create a new application, Heroku creates a remote Git repository (with a branch named heroku), which you can then push your code to. Change your current directory to the Txgh project’s root directory and enter the following command:

$ heroku create
Creating nameless-eyrie-4025... done, stack is cedar-14
https://nameless-eyrie-4025.herokuapp.com/ | https://git.heroku.com/nameless-eyrie-4025.git
Git remote heroku added

By default, Heroku provides a randomly generated name, but you can supply one as a parameter. Once the new application has been created, you can deploy your app by using git:

$ git push heroku master
Counting objects: 156, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (71/71), done.
Writing objects: 100% (156/156), 33.84 KiB | 0 bytes/s, done.
Total 156 (delta 65), reused 155 (delta 65)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rack
remote: -----> Using Ruby version: ruby-2.0.0
remote: -----> Installing dependencies using bundler 1.9.7
...
remote: -----> Compressing... done, 18.3MB
remote: -----> Launching... done, v4
remote:        https://nameless-eyrie-4025.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy.... done.
To https://git.heroku.com/nameless-eyrie-4025.git
 * [new branch]      master -> master

You can verify the success of the deployment by opening the Heroku dashboard in your web browser and navigating to the newly created dyno:

Heroku dyno

Updating the Configuration

Before you can start pushing updates between GitHub and Transifex, you’ll need to provide the Heroku app with information on how to access each service. Txgh uses a set of environment variables to manage connections between each service. The name and description of these variables is shown in the table below:

VariableDescriptionExample
transifex_project_config_tx_configLocation of your Transifex project's configuration file relative to Txgh's root folder../config/tx.config
transifex_project_config_api_usernameYour Transifex username.txuser
transifex_project_config_api_passwordPassword to your Transifex account.1324578
transifex_project_config_push_translations_toName of the GitHub repository that Txgh will push updates to.ghuser/my_repository
transifex_project_config_push_translations_to_branchGitHub branch to update.heads/master
github_repo_config_api_usernameYour GitHub username.ghuser
github_repo_config_api_tokenA personal API token created in GitHub.489394e58d99095d9c6aafb49f0e2b1e
github_repo_config_push_source_toName of the Transifex project that Txgh will push updates to.my_project

There are two ways to apply these to your Heroku app:

  1. Add the environment variables through Heroku’s web interface.
  2. Create a local file containing your environment variables and apply it using rake.

Add Environment Variables Through the Heroku Dashboard
Open the Heroku dashboard in your web browser. Click on the Settings tab and scroll down to the Config Variables section. Click Reveal Config Vars, then click Edit. You’ll have access to the application’s existing variables, but more importantly you can add new variables as shown in the screenshot below. Add the variables listed above and click Save.

Config vars

Note that the RACK_ENV variable defaults to production, but in order for it to work with Txgh we need to set it to test.

Add Environment Variables Using txgh_config.rb
The txgh_config.rb file stores our environment variables inside of the Txgh folder. To create the file, copy and paste the following into a new text file. Replace the placeholder values with your actual values and save the file in the config directory as txgh_config.rb.

# 'test' only ENV['RACK_ENV']
config_env :test do
    set 'transifex_project_config_tx_config', './config/tx.config'
    set 'transifex_project_config_api_username', 
    set 'transifex_project_config_api_password', 
    set 'transifex_project_config_push_translations_to', 
    set 'transifex_project_config_push_translations_to_branch', 'heads/master'
    set 'github_repo_config_api_username', 
    set 'github_repo_config_api_token', 
    set 'github_repo_config_push_source_to', 
end

To apply the changes to your Heroku dyno, use the rake command:

$ rake config_env:heroku
Running echo $RACK_ENV on nameless-eyrie-4025... up, run.2376
Configure Heroku according to config_env[test]

=== nameless-eyrie-4025 Config Vars
LANG:                                          en_US.UTF-8
RACK_ENV:                                      test
github_repo_config_api_token:                  489394e58d99095d9c6aafb49f0e2b1e
github_repo_config_api_username:               ghuser
github_repo_config_push_source_to:             nodejs-test
transifex_project_config_api_password:         12345678
transifex_project_config_api_username:         txuser
transifex_project_config_push_translations_to: ghuser/nodejs-test
transifex_project_config_tx_config:            ./config/tx.config

This command updates the configuration of your Heroku app with the values specified in txgh_config.rb. If you have any issues running the rake command, run bundle install in the Txgh project’s root directory. This compiles and installs the Ruby gems required by Txgh. Once the install completes, run the rake command again.

Since this file contains sensitive information, you should avoid committing it to your Heroku repository or to your GitHub repository.

Once the rake command has completed successfully, open the Heroku dashboard, navigate to the application’s settings and click Reveal Config Vars.

Final Configuration Steps
The last step is to change the value of the RACK_ENV variable. By default, Heroku sets the value of RACK_ENV to production. However, we recommend testing Txgh by setting this value to test. If you haven’t already, open your application’s environment variables in a web browser and change the value of RACK_ENV from production to test. When you’re ready to deploy, you can change this value back to production.

config-vars-fixed

Meanwhile, check the values of your other variables. If any values seem incorrect, you can edit them in your browser or edit and re-apply the txgh_config.rb file using rake. Once everything looks good, you can add your webhooks to Transifex and GitHub.

Connecting Transifex and GitHub to Txgh

Txgh synchronizes your Transifex and GitHub projects using webhooks, allowing Txgh to respond immediately to changes in either service. The webhook URLs follow the format https://.herokuapp.com/hooks/, where is the name of your deployed Heroku app and is either “transifex” or “github.” For instance, we’ll use the following URL with Transifex:

https://nameless-eyrie-4025.herokuapp.com/hooks/transifex

and the following URL with GitHub:

https://nameless-eyrie-4025.herokuapp.com/hooks/github

Connecting Your Transifex Project
Open your project in Transifex. Under More Project Options, click Manage.

Transifex manage

In the Features section at the bottom of the screen is a text box titled Web Hook URL. Enter in the URL you created from your Heroku app, then click Save Project. Secret keys are currently unsupported, so leave the field blank for now.

Transifex webhook

Connecting Your GitHub Repository
Connecting a GitHub repository is similar. Open your repository in a web browser and click Settings.

GitHub repository

Under Webhooks & services, click to add a webhook. You may be asked to confirm your password. Enter the Heroku app URL for the Payload URL and change the Content type to application/x-www-form-urlencoded. Just like with Transifex, keep the Secret token field blank.

GitHub add webhook

Click Add webhook to create your new webhook. GitHub will ping the URL to test its validity. You can check whether the ping was successful by reloading the page.

Next, we’ll test out the integration by moving translations between GitHub and Transifex.

Testing It Out

To test the integration, we’ll push a new commit to GitHub, then we’ll use the new commit to update translations in Transifex.

First, add a new string to the language source file in your Transifex project. Save your changes, then push the code to your GitHub repository. The push will automatically trigger the webhook. You can verify that webhook was successful by opening GitHub in a browser, navigating to the Webhooks & services, clicking on the webhook URL, and reviewing Recent Deliveries.

Recent deliveries

If successful, you should see the new source strings in your Transifex project:

Transifex new strings

Update the translations in Transifex. Back in your GitHub repository, review the latest commits. You should see a commit from Transifex with the latest updates to the target language:

GitHub results

Going Forward

This project represents an early look into automated integration with GitHub. Going forward, we plan on making it easier to setup automated integration with code repositories and other third-party services. If you have any questions, feel free to contact a Transifex team member for a personalized demo or leave a comment below.

Using Transifex with Google Drive

Combining Transifex with Google Drive gives you the ability to edit and share your project files with your entire team. In addition to managing your project with the Transifex client, you can use our auto-update function to update resource files without the need for a third-party service.

Using the Auto-Update Function

Transifex offers an auto-update function that periodically scans a remote file and updates your resources based on changes to that file. The only requirement is that the remote file has to be publicly accessible. To do this, we’ll use a feature in Google Drive designed for hosting static web pages. We’ll then create a URL that Transifex can use to access our resource files.

Start by opening your project in Google Drive. Navigate to your project folder, right-click your resource file, and click “Share”. The Share Settings popup window appears: by default, the file is limited to specific users. We need to make the file publicly available so that Transifex can access it. Note that this has the side effect of making your resource file available to anyone on the public Internet.

Click “Get shareable link” at the top-right corner of the window to show the link sharing dropdown. Click “More” under the dropdown, select “Public on the web”, then click “Save.” Your share settings should look similar to the following screenshot:

Google Drive share popup

Using Google Drive’s Host Feature

After clicking Save, Google Drive gives you a link to the file. Accessing the file through this link will open a file preview, which prevents Transifex from correctly parsing the file’s contents. Instead, we’ll use Google Drive’s host feature to access the file’s contents exactly as they are.

A regular Google Drive link looks similar to the one below. The file ID is a unique string of alphanumeric characters that identifies the file:
https://drive.google.com/file/d/[file ID]/view?usp=sharing

Copy the file ID into the following URL:
https://googledrive.com/host/[file ID]

Test the link by opening the URL in a browser. If you can see the contents of the file, then the link works.

Supplying the URL to Transifex

In Transifex, navigate to your project’s resource list and click “Auto update resources.”

Transifex resources

A new dialog box appears. Enter your newly-created URL and click “Update URL.” If Transifex can successfully access the URL, then the URL turns green.

Auto-update source files

Back in Google Drive, update your source file and save the changes. There’s a small delay Transifex polls the URL for changes once a day, so the updates won’t appear immediately. You can disable the auto-update function by removing the resource’s URL.

Handling Changes

When the auto-update function detects changes, it performs one of three actions:

  1. New strings are added to the project as expected.
  2. Modified strings are added to the project as new strings. The old string and its translations are kept in the project’s Translation Memory.
  3. Missing strings are removed from the resource. The string and its translations are kept in the project’s Translation Memory.

Using the Transifex Client

If you choose not to use the auto-update function, you can manually sync your resource files using the Transifex Client. While it’s less automated, the benefit is that you have control over when the Transifex project is updated. You can use Google Drive to share your project with other users, including the project’s configuration files. This way, another user can run the Transifex Client in the project folder without having to first configure the project. Just be careful not to store your .transifexrc file with the project, as it contains your account credentials.

Google Drive share

For more information, read our FAQ on updating source files.

Using Transifex with Dropbox

Dropbox is shaking up the way many businesses share files. The ability to instantly update files across multiple users and devices makes it easy for companies to stay in sync. With Transifex, you can easily update localization files stored in your Dropbox account.

Using the Auto-Update Function

Transifex provides an auto-update function that modifies your project’s source file based on a contents of a URL. Transifex periodically checks the URL and adds or removes strings based on the contents of the file. This file can be hosted anywhere – Dropbox, GitHub, or even a simple web server – as long as it’s publicly accessible.

To use the auto-update function, you’ll need to create a public URL for your Dropbox file. Using either the Dropbox desktop app or website, right-click your source file and click “Share.” Dropbox will automatically generate a public link to the file, which you’ll provide to Transifex.

In Transifex, navigate to your project’s resource list and click “Auto update resources.”

Transifex resources

A new dialog box appears. Enter the URL generated by Dropbox and click “Update URL.” If Transifex can successfully reach the URL, the URL turns green.

Auto-update source files

Over in Dropbox, update your source file and save the changes. Transifex polls the URL for changes once a day, so the updates won’t appear immediately. You can disable the auto-update function by removing the resource’s URL.

Handling Changes

When the auto-update function detects changes, it performs one of three actions:

  1. New strings are added to the project as expected.
  2. Modified strings are added to the project as new strings. The old string and its translations are kept in the project’s Translation Memory.
  3. Missing strings are removed from the resource. The string and its translations are kept in the project’s Translation Memory.

Handling Syntax Errors

In some cases, Transifex will experience a syntax error when trying to parse text files. This is due to Dropbox’s preview feature, as shown in this screenshot:

Dropbox preview

To ensure Transifex receives a plain text copy of the file, append “?raw=1” to the end of the URL (if the URL already contains a parameter, such as “?dl=0”, use “&raw=1” instead). For example:

https://www.dropbox.com/s/myproject/en.json?dl=0

becomes:

https://www.dropbox.com/s/myproject/en.json?dl=0&raw=1.

Dropbox raw

Using the Transifex Client

If you need a faster approach, you can use the Transifex Client. While it’s less automated than providing a URL, the benefit is that you have control over when the Transifex project is updated. By storing your project configuration with your project files, you can easily share your project with others as shown in the screenshot below. Just be careful not to store your .transifexrc file with the project, as it contains your account credentials.

Dropbox share

For more information, read our FAQ on updating source files.

How to Use Git to Track Changes in Translation Files

There’s been a lot of buzz about managing translations through version control. As localization becomes more integrated into your projects, it’s important that members of your development and localization teams stay synchronized. In this post, we’ll discuss best practices when using Git to manage your own projects.

What is Git?

Git is a version control system (VCS) designed by Linus Torvalds, the creator of Linux. Git tracks changes to source code for multiple users, allowing teams to easily share the same codebase.

Version control is an extensive topic, but we’ll focus on three key components: repositories, commits, and branches.

Repositories are directories that hold your code files. Repositories also double as workspaces. You can create a new repository on your local machine, or you can copy (clone) a repository from a remote machine and work on it locally.

Commits are changes to source code that are applied to a repository. Commits make it easy to group similar changes for organizing, managing, and auditing tasks.

Branches are deviations in the codebase. They let you create new working copies of code without disrupting the original copy. You can easily switch between branches, and any changes made to a branch can be merged into another branch. Git repositories provide a default master branch that forms the trunk for other branches.

There are many other components to Git including forks, push and pull requests, staging, and tagging. For a more comprehensive overview of Git, see Pro Git, an open source book covering a wide range of Git’s features.

Hosting Git Repositories Online

You can host a Git repository on any computer, but there are websites that provide online repository hosting. GitHub, BitBucket, GitLab, Gitorious, and Kiln all provide hosting for public and private repositories.

Git Best Practices

When working with multiple developers, it’s vital to set a version control strategy that everyone understands and agrees with. This section discusses Git best practices that ensure consistency and provide a reliable trail of changes.

Stay in Sync

A code repository is only effective if it’s kept up-to-date with frequent commits. Commits should consist of small, related changes rather than large, varied changes. For instance, if you fix a typo, you can apply the change in a single commit. However, if you fix a typo and a bug, you should make two commits: one for the typo and one for the bugfix. Small, related commits make it easy to not only track changes, but to roll back changes if necessary. It also helps other developers understand exactly what changed while you were working on the file.

Branch Out

Branching does more than just organize code changes: it lets developers modify the codebase without impacting another user’s workspace. A branch is essentially a snapshot of the base branch at a particular commit. New commits build off of that initial commit, allowing the branch to extend independently of other branches including the one it’s based on.

Imagine your organization is preparing a new software release. While the code is being finalized, one of your developers starts working on a new feature for the next release. Not wanting to lose work, he commits his changes before leaving for the night. Without a good branching policy in place, his commit ends up introducing incompatible features into master and the automated build fails.

If a new branch was created specifically for that feature, the developer could commit his changes to a different codebase than the one used for release. The next section shows commonly used branching techniques. There are several well-tested methods, but one of the more popular is the Gitflow Workflow.

The Gitflow Workflow
Originally proposed by Vincent Driessen, the Gitflow Workflow establishes two main branches: master and develop.Master is limited to production-ready code, while develop contains ongoing development changes. Other branches – features, bugfixes, and releases – are based off of these two core branches.

Gitflow workflow

Example of a repository using the Gitflow Workflow (Atlassian)

When development is started on a new feature, develop branches off into a new branch. Once that feature is complete, it gets merged back into the develop branch. As the product nears release, develop branches into release, which is limited to preparing the code for the upcoming release. In the meantime, changes can still be committed to the other branches. When the release is ready, it’s merged back into develop as well as master.

Besides develop, the only other branch that derives directly from master is hotfix. When a hotfix is released, hotfix is merged back into master and develop in order to incorporate the changes into future releases. This results in a flow where changes are logically separated, but still combined into the main branches upon completion.

Combine Often

Merging changes is critical to ensuring consistency across branches. Once a feature is finalized, its changes need to join the changes submitted by other developers in other branches. This can be accomplished using two methods: merging and rebasing.

Merging vs. Rebasing
Merging and rebasing both solve the problem of synchronizing two branches, but they go about it in very different ways. For instance, imagine you’re working with a repository that has two branches: master and feature. You’ve been assigned to work on new code and commit your changes to feature. In the meantime, other developers are committing changes to master. Once you’ve finished coding, you need to update master with the changes made to feature.

Merging resolves this by creating a new commit in feature containing all of the intermediate commits from master. While this fully preserves both branches, it also generates a lot of extraneous commits, as it needs to incorporate each change from master all the way back to the branch point.

Git merge

Merging the master branch into a feature branch (Atlassian)

Rebasing takes the opposite approach by committing changes from feature into master. Rebasing rewinds to the commit in master that feature is based off of, then reapplies each commit from feature to master. While this reduces the number of commits, it has the effect of essentially rewriting the project’s history.

Git rebase

Rebasing the same feature branch onto master (Atlassian)

Git’s rebase command lets you determine exactly how the branches are integrated. For instance, interactive rebasing will walk you through each feature commit and let you alter the commit before it’s applied to master. For more details, see Merging vs. Rebasing in the Atlassian Git Tutorial.

Synchronizing Git With Transifex

There are several ways to manage code with Git while still managing localizations with Transifex.

Using the Transifex Client with Git

You can simply use the Transifex Client to push source changes to Transifex. The benefit to this approach is that it ensures you have access the latest translations and can push resource updates to the Transifex project.

The drawback is that you’ll need to enforce a policy for pushing resource updates. Features that are still in development can change completely, and having your localizers work on text that might not appear in the final product is a waste of time and money. You will also need to be aware of including localization updates when committing their changes.

Using txgh

Txgh is an Open Source Sinatra server created by Strava. It uses Webhooks to automatically trigger updates in GitHub and Transifex. If a developer commits a change to a source translation file in GitHub, txgh automatically updates the file in Transifex. Additionally, if a translator makes a change in Transifex that updates a file to 100%, txgh creates and pushes a new commit to GitHub. Txgh removes the added step of having to run the Transifex Client each time a translation is added.

There’s No One-Size-Fits-All Solution

Different organizations will prefer different workflows based on their needs and culture. Gitflow is far from the only Git workflow in popular use, and it may not be ideal for your development cycle. You can find a comparison of Git workflows in Atlassian’s Git Tutorial. You can find additional resources for using Git through GitHub’s help site. If you want to learn more about Git, Code School provides an interactive online course.

Translate your Zendesk Knowledge Base with Transifex Sync

Knowledge bases help your customers get answers to questions instantly. It’s key to customer success. To make translating your Zendesk knowledge base easier, we’ve built the Transifex Sync Zendesk app.

Transifex Sync Zendesk translation app

Transifex Sync automatically detects all the articles, sections, and categories in your Zendesk Help Center. With a click, you can upload the content to Transifex and translate it like you would any other content in Transifex. When the translations are done, just download them into Zendesk using Transifex Sync and you’re ready to provide answers to users worldwide. Easy!

Learn more about Transifex Sync, or check it out in the Zendesk Marketplace.

Translate your Help Scout Docs with Transifex

Help Scout is a popular help desk software with a built-in a knowledge base solution called Docs. If you use Docs, you can now translate it with Transifex Live. Not only can you provide great email support, but you can offer answers to your users 24/7 in their native language too.

Multilingual Help Scout Docs

Translating your Help Scout Docs with Transifex Live is simple. Just add the Transifex Live JavaScript snippet in your site’s settings, save the articles, translate, and publish. Best of all, when you use Transifex Live, you only need to set up one knowledge base to offer it in multiple languages.

Check out our sample Help Scout knowledge base that was translated with Transifex Live, or get started by following the instructions in the documentation.

P.S. If you haven’t heard, we’ve also built a Transifex Live-based WordPress plugin for translating your WordPress site.

Translating Your Node.js App with Transifex

Node.js is a server-side environment for delivering scalable JavaScript apps and services. It’s quickly gaining popularity, having been used by Netflix, PayPal, LinkedIn, and others. In this post, we’ll show you how can use Transifex to easily localize your Node.js apps.

Setting Up Node.js for Localization

While there are several modules for localizing in Node.js, we recommend the i18n-node module. i18n-node stores localization data in standard JSON, making it easy to pass text to and from Transifex.

i18n-node

i18n-node is a simple translation module for integrating localization into a Node.js app. Each locale stores its translations in a separate JSON file, which you’ll use to send localization data to and from Transifex. You can add i18n-node to your project using npm:

$ npm install i18n

Load i18n along with the rest of your modules:

// load modules
var http = require('http'),
      i18n = require('i18n'),
      ...

To configure i18n, specify the locales you want to include in your project and the directory where the localization files will be stored. You can also specify a default locale, a unique extension for newly created localization files, and more. A full list of options is available on the i18n-node GitHub page.

In this example, we’ll store English, Spanish, and German language files in the locales directory under the current directory:

i18n.configure({
	locales:['en', 'es', 'de'],
	directory: __dirname + '/locales',
	defaultLocale: 'en',
	extension: '.json'
});

i18n-node supports both shorthand locale codes and IETF language tags. For example, to specify British English, change “en” to “en_GB”.

You can reference a localized string by using the global i18n keyword. For example, if you have a variable that stores the string “Hello”, you can replace it with a localized string using i18n.__(keyword):

// Hard coded string
// var greeting = 'Hello';

// Localized string
var greeting = i18n.__('Hello');

The exception is when responding to http requests, in which case you can attach the reference to the request object. For example, let’s create a simple web server that displays “Hello” to the user:

app = http.createServer(function(request, response) {
	i18n.init(request, response);
	response.end(response.__('Hello');
});

app.listen(3000, '127.0.0.1');

i18n automatically generates the default locale using the keyword provided. When the app starts, i18n creates three new files:

  • en.json, which contains the default keys
  • es.json, which will contain the Spanish translations
  • de.json, which will contain the German translations

Further down, we’ll show you how to connect your app to Transifex using the Transifex client.

RequireJS

RequireJS provides its own i18n implementation that can also be imported into Transifex. If your Node.js app uses RequireJS, add the i18n.js plugin to your project.

Similar to i18n-node, RequireJS uses JSON to store translations. However, rather than using a standard JSON Key-Value file format similar to i18n-node, RequireJS actually defines the key-value set as an object.

RequireJS searches for localization files in the “nls” folder under the project directory. Additional languages are stored in separate directories and are enabled by adding the language to the main file.

For more details on localizing with RequireJS, see the RequireJS documentation on i18n.

Sending the Source File to Transifex

The Transifex Client makes it easy to move translations between your app and Transifex. If you don’t already have the Transifex Client installed, follow the instructions here.

Start by creating a new Transifex project using the JSON Key-Value (.json) file format. The en.json file will act as our source file. Once you’ve created the project, use the Transifex Client to create a local repository in your app directory:

$ cd myapp
$ tx init

tx init creates a .tx directory in the current folder with a basic config file. We’ll set up the configuration by specifying the directory where localized files are stored, setting en.json as the initial localization resource, setting English as the source language, and specifying standard JSON as the file type.

Transifex_project_slug specifies the URL slug for your project, while default_resource_slug specifies the URL slug for the default resource. You can find both of these in your project page.

[main]
host = http://wpdev.transifex.com

[Transifex_project_slug.default_resource_slug]
file_filter = locales/.json
source_file = locales/en.json
source_lang = en
type = KEYVALUEJSON

Finally, push any local changes to Transifex using tx push -s. The -s flag tells the Transifex Client to update the project with the source file.

$ tx push -s
Pushing translations for resource nodejs-test.enjson:
Pushing source file (locales/en.json)
Done.

The project page should reflect the updated source file:

Transifex project page

Localizing in Transifex

Now that your source file has been pushed to your project, you can use Transifex to start localizing. We’ll show you how to add new languages, update translations, then push the changes back to your Node.js application.

Adding Existing Languages

If your app already contains translations, you can push those translations to Transifex using the Transifex Client. Use tx push with the -t flag instead of the -s flag to push any existing translations to your project.

$ tx push -t
Pushing 'de' translations (file: locales/de.json)
Pushing 'es' translations (file: locales/es.json)
Done.

For smaller projects, it may be easier to create a new translation and enter any existing translations as comments. For more information on how you can do this, see the Transifex Editor tutorial.

Adding New Languages

Begin by clicking “Edit Languages” in the Project Languages table:

Project languages

In the popup window, enter the languages that you want to add to your project. In this case, we’ll add Spanish (es) and German (de). As you type, the search box will filter based on the name of the language. You can also specify locales such as Latin American Spanish (es_419) or Austrian German (de_AT). When you’re ready, click Apply.

Add languages

Adding Translations

Your new languages will appear in your project dashboard. Since no work has been done on them, they’ll both appear at 0% completion. You’ll also see that no translators have been assigned to the new languages. You can learn more about adding translators through the People page.

Adding translations

Let’s start by filling in our German translation. Clicking on the German language will bring you to the resource page. The en.json source file is shown along with its category and completion. From here, you can also assign and manage the project’s team members.

Transifex resources

Click on the en.json resource, then click Translate in the popup window:

Translation popup

This will bring you to the Transifex Editor, where you can modify and review your translations. The left-hand panel shows the strings provided by your resource file. In this case, we only have the one string, “Hello”. The right-hand panel provides tools for entering and reviewing translations. Additionally, you can view suggested translations, read through a history of translations, add comments or instructions, and more. You can learn more about the Transifex Editor through the Editor tutorial.

When you’re ready to translate, select “Hello” so that it appears in the right-hand panel under “Untranslated String”. Type “Hallo” in the translation box underneath the string and press the Tab key or the Save button. The translation will be marked as unreviewed until it can be verified by a reviewer or manager. In the meantime, do the same for the Spanish translation by switching to the Spanish resource and entering “Hola” in the translation box.

Transifex translation editor

The project dashboard will now show the languages as pending review. Next, we’ll sync the new translations back to Node.js.

Syncing Changes Back to Node.js

Using the Transifex Client, you can pull changes back to your Node.js app with tx pull:

$ tx pull -a
New translations found for the following languages: de, es
Pulling new translations for resource nodejs-test.enjson (source: locales/en.json)
 -> de: locales/de.json
 -> es: locales/es.json
Done.

You can verify the results by checking your es.json and de.json files. If the process was successful, you should see a new key-value pair for each language.

$ cat locales/es.json locales/de.json
{
	"Hello": "Hola"
}{
	"Hello": "Hallo"
}

With that, your Node.js app is ready to go! If you’re using i18n-node, you can test your configuration using i18n’s the setLocale() function:

i18n.configure({...});
i18n.setLocale('es');
app = http.createServer(...);

Retrieving Project Information through Node.js

There are other ways to interact with your Transifex project through Node.js. node-transifex is a community module that provides an easy interface to the Transifex API. After adding your project name and user credentials to node-transifex, you can use the module’s built-in methods to pull data about your Transifex project. For instance, as a project owner, you can use the languageSetMethod() function to return a list of the project’s languages along with the coordinators, translators, and reviewers for each language.

node-transifex also allows statistics gathering, such as the percentage of items that have been translated and the percentage of items that have been reviewed. You can gather statistics for the entire project, or for a specific language.

Install node-transifex using npm:

$ npm install transifex

Then, initialize the module with your project name and credentials:

var Transifex = require("transifex");

var transifex = new Transifex({
    project_slug: "myProject",
    credential: "username:password"
});

For a list of available functions, see the node-transifex project page.

What is Translation Memory?

As you translate more and more content, whether it’s strings in an app or text on a website, you’ll encounter content that’s similar to or even the same as what’s been translated before. For example, an app may contain both the phrase “Download file” as well as “Download all files.”

In our new infographic, we explain what Translation Memory is, and how it can help you handle these similar content.

Infographic: What is Translation Memory