Using the Phrase API in Your App

Phrase is a cloud-based Translation Management System (TMS) tailored to the needs for localization and internationalization of modern enterprises. Built for developers, Phrase is a combination of a whole lot of tools and resources (e.g. REST API, CLI tool and UI Dashboard) that suit all tastes and flavours of localization development. Together with extensive online documentation, any respectable practitioner could automate localization tasks and reduce overheads. In this tutorial, we're going to explore the Phrase API and use the available tooling in a variety of ways to address our localization needs.

Phrase offers a comprehensive and well-documented REST API (take a look at the DNA of the Phrase API if you’d like to get a better understanding of the rationale behind it). These are its key service endpoints:

  • Projects: You can list, view, create or delete projects. Projects are the main modules separating logical entities. Each project has it’s own localization resources, team members, jobs, etc.
  • Locales: You can list, view, create or delete different locales within each project. Locales consist of information about language tags usage, plural rules, directions rules, etc.
  • Keys: You can list, view, create or delete different keys per project. Keys are the individual unique IDs used to match translation strings to the associated translation. There is also an option to add meta information such as tags or type.
  • Translations. You can list, view, create or delete different translations per project. The translations contain a reference to one or more keys. Then, there is a list of available translations per locale parameter.
  • Uploads: You can upload files and track their status.
  • Tags: You can manage tag meta information for each key for better control and searching.
  • Blacklisting keys: You can blacklist or filter out particular keys within a project.
  • Versions: You can view all revisions of each translation.

Other than the core resources, there are additional endpoints that cover special operations such as Jobs, Branches, Comments, Integrations, User Management and Glossaries. As you can see for yourself, Phrase is not just an online database but rather a complete platform.

As a customer, you can consume the Phrase API in a variety of ways. For ease of use, you can always start with the UI Dashboard that you see right after logging on the main page.

However, in this tutorial, we’d like to take a look at how we can use the REST API using the provided Phrase CLI Tool and the language-specific libraries. Let’s start with the CLI Tool.

Phrase CLI Tool

The CLI Tool is suitable for automation tasks and quick experimentation. We can perform most of the exposed API operations from the convenience of our favourite shell client.

To run it, you’d first need to download the client from the CLI Tool page. Once downloaded, don’t forget to make it executable if you are working on Linux or Mac.

mv phraseapp_macosx_amd64 phraseapp
chmod +x phraseapp

➜ ./phraseapp
account show                                          <ID>    Get details on a single account.
accounts list    List all accounts the current user has access to.
authorization create    Create a new authorization.
...

Before we interact with the API, we need to configure our client. Run the following command in your local shell:

➜ ./phraseapp init
PhraseApp.com API Client Setup

Please enter your API access token (you can generate one in your profile at phraseapp.com): 
<token>

The <token> parameter is needed, and you can create one from your Account > Access Tokens. Once generated, enter the input and you will be asked to select a project from the list or you can create a new one…

Loading projects...
 1: Test (Id: 8fa47c48c3ba80aebe255e99651de3e4)
 2: WP POT File Test (Id: 5ed97cfde5a2ac8bf4fbc6edd82eb4a9)
 3: Handmade's Tale (Id: 40fe26fda781e98df0134cf91e02aea4)
 4: Create new project
 
 > 1

Next, you’ll be asked to specify the default language file formats that you want to use for that project as well as their location. At the moment, Phrase supports 39 formats (still more to come):

1: yml - Ruby/Rails YAML, file extension: yml
 2: gettext - Gettext, file extension: po
 3: gettext_template - Gettext Template, file extension: pot
 4: gettext_mo - Gettext Mo, file extension: mo
 5: xml - Android Strings, file extension: xml
 6: strings - iOS Localizable Strings, file extension: strings
 7: stringsdict - iOS Localizable Stringsdict, file extension: stringsdict
 8: xlf - XLIFF, file extension: xlf
 9: qph - Qt Phrase Book, file extension: qph
10: ts - Qt Translation Source, file extension: ts
11: json - Chrome JSON i18n, file extension: json
12: react_simple_json - React-Intl Simple JSON, file extension: json
13: react_nested_json - React-Intl Nested JSON, file extension: json
14: simple_json - Simple JSON, file extension: json
15: go_i18n - Go i18n JSON, file extension: json
16: nested_json - Nested JSON, file extension: json
17: node_json - i18n-node-2 JSON, file extension: js
18: resx - .NET ResX, file extension: resx
19: resx_windowsphone - Windows Phone ResX, file extension: resx
20: windows8_resource - Windows 8 Resource, file extension: resw
21: ini - INI, file extension: ini
22: properties - Java Properties .properties, file extension: properties
23: play_properties - Play Framework Properties, file extension: locale
24: properties_xml - Java Properties XML, file extension: xml
25: plist - Objective-C/Cocoa Property List, file extension: plist
26: symfony_xliff - Symfony XLIFF, file extension: xlf
27: yml_symfony - Symfony YAML, file extension: yml
28: yml_symfony2 - Symfony2 YAML, file extension: yml
29: tmx - TMX Translation Memory eXchange, file extension: tmx
30: xlsx - Excel XLSX, file extension: xlsx
31: csv - CSV, file extension: csv
32: php_array - PHP Array, file extension: php
33: zendesk_csv - Zendesk CSV, file extension: csv
34: laravel - Laravel/F3/Kohana Array, file extension: php
35: angular_translate - Angular Translate, file extension: json
36: mozilla_properties - Mozilla Properties, file extension: properties
37: ember_js - EmberJs, file extension: js
38: i18next - i18next, file extension: json
39: episerver - Episerver XML, file extension: xml


Select the format to use for language files you download from PhraseApp (1-39): 15
Using format Go i18n JSON

Enter the path to the language file you want to upload to PhraseApp.
For documentation, see https://help.phraseapp.com/phraseapp-for-developers/phraseapp-client/configuration#push
Source file path: [default ./<locale_name>.all.json]

Enter the path to which to download language files from PhraseApp.
For documentation, see https://help.phraseapp.com/phraseapp-for-developers/phraseapp-client/configuration#pull
Target file path: [default ./<locale_name>.all.json]

We select the go i18n JSON format, usually used in the go-i18n library. We also discussed it this tutorial on how to go multilingual with Hugo.

Once we’re done with the configuration, we can pull the latest locales in our local environment as easy as:

➜ ./phraseapp pull
Downloaded en to en.all.json
Downloaded de to de.all.json

Theo/Projects/phraseapp-api
➜ ls
de.all.json en.all.json phraseapp

Theo/Projects/phraseapp-api
➜ cat de.all.json
[
  {
    "id": "general.back",
    "translation": "zurück"
  },
  {
    "id": "general.cancel",
    "translation": "abbrechen"
  },
  {
    "id": "general.confirm",
    "translation": "Bist du sicher?"
  },
  {
    "id": "general.destroy",
    "translation": "Löschen"
  },
  {
    "id": "general.edit",
    "translation": "Bearbeiten"
  },
  {
    "id": "general.new",
    "translation": "Neu"
  },
  {
    "id": "hello",
    "translation": "Hallo Welt"
  },
  {
    "id": "layouts.application.about",
    "translation": "Über"
  },
  {
    "id": "layouts.application.account",
    "translation": "Konto"
  },
  {
    "id": "layouts.application.app_store",
    "translation": "App Store"
  },
  {
    "id": "layouts.application.imprint",
    "translation": "Impressum"
  },
  {
    "id": "layouts.application.logout",
    "translation": "Abmelden"
  },
  {
    "id": "layouts.application.my_mails",
    "translation": "Meine Mails"
  }
]%

Theo/Projects/phraseapp-api
➜ cat en.all.json
[
  {
    "id": "general.back",
    "translation": "Back"
  },
  {
    "id": "general.cancel",
    "translation": "Cancel"
  },
  {
    "id": "general.confirm",
    "translation": "Are you sure?"
  },
  {
    "id": "general.destroy",
    "translation": "Delete"
  },
  {
    "id": "general.edit",
    "translation": "Edit"
  },
  {
    "id": "general.new",
    "translation": "New"
  },
  {
    "id": "hello",
    "translation": "Hello world"
  },
  {
    "id": "layouts.application.about",
    "translation": "About"
  },
  {
    "id": "layouts.application.account",
    "translation": "Account"
  },
  {
    "id": "layouts.application.app_store",
    "translation": "App Store"
  },
  {
    "id": "layouts.application.imprint",
    "translation": "Imprint"
  },
  {
    "id": "layouts.application.logout",
    "translation": "Logout"
  },
  {
    "id": "layouts.application.my_mails",
    "translation": "My Mails"
  },
  {
    "id": "layouts.application.press",
    "translation": "Press"
  },
  {
    "id": "layouts.application.preview",
    "translation": "Preview"
  },
  {
    "id": "layouts.application.profile",
    "translation": "Profile"
  },
  {
    "id": "layouts.application.sign_in",
    "translation": "Login"
  },
  {
    "id": "layouts.application.sign_up",
    "translation": "Register"
  }
]%

If we wanted a different format, we could change it from the configuration file .phraseapp.yml topull the locales again.

Now that we’ve configured the client, we can perform some concrete operations. For example, if we want to list all our projects:

➜ ./phraseapp projects list | jq
[
  {
    "account": {
      "company": "",
      "created_at": "2018-06-26T08:35:41Z",
      "id": "597581c0",
      "name": "Dynport GmbH",
      "updated_at": "2019-02-05T15:01:36Z"
    },
    "created_at": "2018-06-26T08:36:17Z",
    "id": "8fa47c48c3ba80aebe255e99651de3e4",
    "main_format": "",
    "name": "Test",
    "project_image_url": "",
    "updated_at": "2018-06-26T15:50:06Z"
  },
  ...

Notice: We used the jq tool to print the JSON response a bit prettier.

When we’ve updated our local translations, we can push them to the online platform so that the translations become available for other team members.

For example, add the following key to the en.all.json file:

{
    "id": "general.test",
    "translation": "Test"
},

Then, push them to the remote…

➜ ./phraseapp push
Uploading de.all.json... done!
Check upload ID: ba66d11bea716dd09ff4e56e750525f6, filename: de.all.json for information about processing results.
Uploading en.all.json... done!
Check upload ID: 6c34dd66483661b49be8eae837e1dd7f, filename: en.all.json for information about processing results.

The new key will be available in the Dashboard:

Using Libraries

If we want to access the API programatically, we can do so by using a library written in the programming language of our choice. Phrase provides several library implementations for us to use. Let’s see how we can use the Go library in practice.

First, make sure you have Go installed and configured correctly.

Then create a main.go file with the following content:

package main

import (
	"github.com/phrase/phraseapp-go/phraseapp"
	"os"
	"fmt"
	"log"
)

func main()  {
	credentials := phraseapp.Credentials{
		Host:  "https://api.phraseapp.com",
		Token: os.Getenv("PHRASE_APP_TOKEN"),
	}

	client := phraseapp.Client{
		Credentials: credentials,
	}

	projects, err := client.ProjectsList(1, 10)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("PROJECT LIST")
	fmt.Println("____________")
	for _, project := range projects {
		fmt.Println(project.Name)
	}
}

Here, we just use the Phrase client to retrieve the project list and print their names. If you configured the access token correctly, you would see the list of your projects.

$> export PHRASE_APP_TOKEN=<token> && go run main.go

PROJECT LIST
____________
Test
WP POT File Test
Handmade's Tale

The Phrase API gives you the ultimate control over the request-and-response information – useful in many scenarios, such as automation, CI and CD pipelines, translations sync and many more.

Conclusion

In this article, we took a look at how to take advantage of the official Phrase API using the Command Line Client and a library written in Go. If you want to explore more about Phrase and it’s related technologies, don’t hesitate to sign up for a 14-day trial period. Thanks for your time and stay put for more great tutorials!

5 (100%) 8 votes
Comments
close

Automate Your Localization Workflow for Continuous Deployment

Automate Localization for Continuous Deployment

  • Integrate Phrase into your agile environment easily
  • Import and export your localization files in any format
  • Automate your localization workflow to speed up every release