Integrations

In-Context Editor (Strings)

Available for

  • Advanced plan

  • Enterprise plan

Get in touch with Sales for licensing questions.

The In-Context Editor is designed to help translators get things done more efficiently. After installing the In-Context Editor, it can be customized to work with many technologies.

Installing the Strings In-Context Editor

Requirements

To use the In-Context Editor, the application requires:

  • Web-based websites, web applications, mobile sites, etc.

  • Translators have access to the the web server running the editor. This could be a local environment if required.

  • A key-value localization file structure.

    Web sites with translatable strings extracted and a view layer that uses a key-value structure to render translations.

  • Key names exposed to the view or template layer.

  • JavaScript snippet that renders the editor.

  • Ideally, a dedicated environment for translations. This can be a clone of a staging environment and although more work to initially set up, provides a better workflow and more stability.

    If a dedicated environment is not possible, an existing staging environment can be used with the option of enabling the In-Context Editor as needed.

JavaScript Snippet

Include the JavaScript snippet in the application layout and replace YOUR_PROJECT_ID with the ID for the project.

The snipped includes the code required to:

Project ID in is found in project settings.

Sample:

<script>

  window.PHRASEAPP_CONFIG = {

    projectId: 'YOUR_PROJECT_ID'

  };

  (function() {

    var phraseapp = document.createElement('script'); phraseapp.type = 'text/javascript'; phraseapp.async = true;

    phraseapp.src = ['https://', 'phraseapp.com/assets/in-context-editor/2.0/app.js?', new Date().getTime()].join('');

    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(phraseapp, s);

  })();

</script>

Using the In-context editor

Exposing Key Names

Typically, a view layer renders translations by passing the name of a translatable string (i.e., the key) to some sort of translation method or view helper.

Sample PHP code:

$translations = array(

  "page.headline" => "Some Headline",

  "page.link.label" => "I am a link",

  "page.link.hint" => "Click me"

)

function translate($keyName) {

  return $translations[$keyName];

}

The template would then render the output of the translate() method instead of the actual translated string:

<h1><?php echo translate("page.headline"); ?></h1>
Formatting

It must be indicated in the template which keys to render translations for.

Use this formatting to expose key names instead of translations:

{{__phrase_NameOfYourKey__}}

Example:

If the key page.headline is in the template, render the string {{__phrase_page.headline__}}.

Modify the translate() helper method so as to expose key names in the required format:

function translate($keyName) {

  if ($phraseModeEnabled) {

    return "";

  } else {

    return $translations[$keyName];

  }

}

Depending on framework, translation helpers in the code can be overridden or a wrapped version can be created to use in templates.

Escaping Key Names and Special Characters

Ensure key names are converted to a recognizable format.

Characters in the following list need to be escaped when exposed to the In-Context Editor:

Character

Escape sequence

Example

<

[[[[[[html_open]]]]]]

{{__phrase__<key__}} becomes {{__phrase__key[[[[[[html_open]]]]]]__}}

>

[[[[[[html_close]]]]]]

{{__phrase__key>__}} becomes {{__phrase__[[[[[[html_close]]]]]]key__}}

Context View

Context View is an add-on for the In-Context Editor. It provides links back to your app, so translators are always aware of context. It is automatically available within the In-Context Editor if subscribed to the correct plan.

Context View collects information about which keys are rendered on which URLs in a web application and stores this information. Links to the website are generated from displayed keys. Translators can click a link next to a key to go directly to its location on the site and use the In-Context Editor to edit the translation on the page.

Setup Context view

To setup Context view, follow these steps:

  1. Prepare a staging environment that uses the In-context editor.

  2. Add the URL for the staging environment to the In-context editor URL field in the In-context editor tab in the Project settings window.

  3. If the application or website uses anchor or location hash-based routing, select Enable support for routing via anchor.

  4. Click Save.

    The URL is added to the project settings.

  5. Browse the website with the installed In-context editor.

Ajax Mode

The In-Context Editor supports Ajax and DOM manipulation (i.e., via JavaScript) using mutation observers.

Ajax mode can cause problems in some cases, and may result in severe performance issues when using the In-Context Editor. To disable Ajax mode, add the following configuration value before the JavaScript snippet:

window.PHRASEAPP_CONFIG = {

  ajaxObserver: false

}

Automatic Case Conversion

By default, the In-Context Editor’s document parser converts all keys to lowercase. If experiencing issues with this behavior and want to use case-sensitive keys within the In-Context Editor, disable the automatic lowercase feature:

window.PHRASEAPP_CONFIG = {

  autoLowercase: false

}

Branching

If using Branching and want to initialize the In-Context Editor on a different branch in a project, add the following configuration value before the JavaScript snippet:

window.PHRASEAPP_CONFIG = {

  branch: [insert_branch_name]

}

Customize Key Decorators

When using the In-Context Editor, key names are typically wrapped with decorators (curly braces, by default) to generate unique identification keys within the context of a document:

{{__phrase_YOUR.KEY__}} 

If this causes conflicts with other libraries (e.g., client-side template engines, including AngularJS and Ember.js) that use a similar syntax, change the In-Context Editor’s decorator prefix and suffix in the setup. To tell the In-Context Editor which decorators the parser should look for, add the following configuration values before the JavaScript snippet:

window.PHRASEAPP_CONFIG = {

  prefix: '[[__',

  suffix: "__]]"

}

This tells the editor to look for tags beginning with [[__ and ending with __]]:

[[__phrase_YOUR.KEY__]]

If using the phraseapp-in-context-editor-ruby gem to provide In-Context Editor functionality, ensure decorators are configured:

PhraseApp::InContextEditor.configure do |config|

  config.prefix = "[[__"

  config.suffix = "__]]"

end

If not using the gem, ensure the key name exposure pattern is adjusted in the custom code.

Debug Mode

To enable debug mode, add the following configuration value before the JavaScript snippet:

window.PHRASEAPP_CONFIG = {

  debugMode: true

}

Enabling and disabling the In-Context Editor

This setting is only available when using the phraseapp-in-context-editor-ruby gem.

The In-Context Editor is disabled by default.

The In-Context Editor can be explicitly enabled or disabled. This affects the inclusion of the JavaScript snippet (when using the view helper) and the rendering of the decorated key names in views:

PhraseApp::InContextEditor.enabled = true|false

Example of binding the flag to an environment variable:

PhraseApp::InContextEditor.enabled = (ENV["IN_CONTEXT_EDITING"] == "1")

Forcing a Locale

To set a specific locale explicitly when starting the In-Context Editor,use the forceLocale setting. This is useful for preselecting the locale currently displayed in your web application in the In-Context Editor as well:

window.PHRASEAPP_CONFIG = {

  forceLocale: "pt-BR"

}

Full Reparsing

Enable fullReparse ifusing the In-Context Editor with a JavaScript framework that uses Virtual DOM such as React. This allows proper reparsing when DOM changes are detected:

window.PHRASEAPP_CONFIG = {

  fullReparse: true

}

Ignored Keys

This setting is only available when using the phraseapp-in-context-editor-ruby gem.

Keys can be excluded from being rendered with the In-Context Editor. When working with Rails, keys may be ignored for data such as error messages or date and time format keys. To exclude keys from being handled automatically by the phraseapp-in-context-editor-ruby gem, add an array of the keys to phraseapp_in_context_editor.rb initialization file. Wildcards can also be used:

PhraseApp::InContextEditor.configure do |config|

  config.ignored_keys = ["date.*", "forbidden.key",   "errors.messages*"]

end

Keys matching any of these patterns will not be made accessible to the In-Context Editor and are rendered normally.

Sanitize Output to Webpage

The In-Context Editor can be configured to escape or alter translations before they are inserted into the webpage by providing a function to the sanitize property.

The function accepts the translation string as the first argument and should return a string:

import escape from “lodash/escape”;

window.PHRASEAPP_CONFIG = {  

    sanitize: escape

}

Single Sign-on

If using single sign-on and want to initialize the In-Context Editor with SSO enabled, add the following configuration value before the JavaScript snippet:

window.PHRASEAPP_CONFIG = {

  sso: {

    enabled: true,
    
    provider: 'saml',

    identifier: [insert_company_identifier]

  }

}

To require users to sign on using SSO, set the enforced parameter:

window.PHRASEAPP_CONFIG = {

  sso: {

    enforced: true

  }

}

Web Framework Installations

Angular 2 (ngx-translate)

To install the In-Context Editor in this environment, follow these steps:

  1. Install with NPM:

    npm install ngx-translate-phraseapp
  2. Configure:

    let config = {
      projectId: '<YOUR_PROJECT_ID>',
      phraseEnabled: true,
      prefix: "{{__",
      suffix: "__}}",
      fullReparse: true
    };

    Project ID of a project is found in project settings.

  3. By default, the editor’s document parser converts all keys to lowercase. If experiencing issues with this behavior and want to use case-sensitive keys within the editor, disable the automatic lowercase feature:

    let config = {
      // ...
      autoLowercase: false
    }
  4. Add these snippets to the Angular app:

    app.component.ts

    import { initializePhraseAppEditor, PhraseAppCompiler} from 'ngx-translate-phraseapp'
    
    let config = {
      projectId: '<YOUR_PROJECT_ID>',
      phraseEnabled: true,
      prefix: "{{__",
      suffix: "__}}",
      fullReparse: true
    };
    
    initializePhraseAppEditor(config);

    app.module.ts

    import { TranslateModule, TranslateLoader, TranslateCompiler } from '@ngx-translate/core';
    import { HttpClientModule, HttpClient } from '@angular/common/http';
    import { PhraseAppCompiler } from 'ngx-translate-phraseapp'
    
    export function HttpLoaderFactory(http: HttpClient) {
      return new TranslateHttpLoader(http);
    }
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        HttpClientModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
          },
          compiler: {
            provide: TranslateCompiler,
            useClass: PhraseAppCompiler
          }
        }),
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
Code sample

This demo app showcases an integration of the In-Context Editor with Angular and ngx-translate.

AngularJS (angular-translate)

To install the In-Context Editor in this environment, follow these steps:

  1. Install angular-phrase via Bower (or download manually):

    $ bower install angular-phrase
  2. Add the angular-phrase module to existing AngularJS application after loading the angular-translate module:

    var myApp = angular.module("myApp", ['pascalprecht.translate', 'phrase']);
    
  3. Configure the module:

    myApp.value("phraseProjectId", "YOUR-PROJECT-ID");
    
    myApp.value("phraseEnabled", true);
    
    myApp.value("phraseDecoratorPrefix", "");

    Project ID of a project is found in project settings. This creates an initialization file with some configuration options.

  4. Add the phrase-javascript directive to the application inside the <head> tag:

    <phrase-javascript></phrase-javascript>
  5. Open the application in any web browser to see the In-Context Editor applied to the app. Sign in with any Phrase organization user.

angular-phrase on GitHub

Code sample

This demo application for angular-phrase shows how to localize AngularJS with angular-translate.

Django

To install the In-Context Editor in this environment, follow these steps:

  1. Install the django-phrase package with pip:

    $ pip install django-phrase
  2. Add Phrase to the list of installed apps:

    INSTALLED_APPS = (
    
        'phrase',
    
    )
  3. Use the phrase_i18n template tag in templates:

    {% load phrase_i18n %}

    To allow django-phrase to override translation methods, load phrase_i18n after i18n.

  4. Add the JavaScript snippet to the layout:

    {% phrase_javascript %}
  5. Configure the In-Context Editor for the project with these options:

    PHRASE_ENABLED = TruePHRASE_PROJECT_ID = 'YOUR_PROJECT_ID'PHRASE_PREFIX = '{{__'PHRASE_SUFFIX = '__}}'
  6. Open the application in any web browser to see the In-Context Editor applied to the app. Sign in with any Phrase organization user.

Django adapter code on GitHub

Code sample

This demo application demonstrates how to integrate the In-Context Editor with a Django application.

React (intl)

Note

This library may not work with IE11 or older browsers. Add Babel to the build pipeline if older browser support is required.

This library inherits common components of the react-intl packages. If Phrase is enabled by calling initializePhraseAppEditor, the behavior of the components will change.

To install the In-Context Editor in this environment, follow these steps:

  1. Install via NPM:

    npm install react-intl-phraseapp

    or build from source:

    npm run dist
    npm install
  2. Configure:

    let config = {
      projectId: '<YOUR_PROJECT_ID>',
      phraseEnabled: true,
      prefix: "[[__",
      suffix: "__]]",
      fullReparse: true
    };

    Project ID of a project is found in project settings.

  3. Add the snippet to the react app:

    import {initializePhraseAppEditor} from 'react-intl-phraseapp'
    
    let config = {
      projectId: '<YOUR_PROJECT_ID>',
      phraseEnabled: true,
      prefix: "[[__",
      suffix: "__]]",
      fullReparse: true
    };
    
    initializePhraseAppEditor(config);
  4. Find all imports of FormattedMessage, and change the source from react-intl to react-intl-phraseapp.

    import {FormattedMessage} from 'react-intl-phraseapp'
  5. Run unit tests using jest:

    npm test
Code sample

This demo shows an integration of the Phrase In-Context Editor with react-intl.

Ruby on Rails (i18n)

To install the In-Context Editor in this environment, follow these steps:

  1. Add the phraseapp-in-context-editor-ruby gem to the environment you want to use the In-Context Editor with:

    group :development do
      gem 'phraseapp-in-context-editor-ruby'
     end

    and install it by executing the bundle command:

    $ bundle install
  2. Install the phraseapp-in-context-editor-ruby gem by executing the Rails generator:

    $ bundle exec rails generate phraseapp_in_context_editor:install --access-token=YOUR_ACCESS_TOKEN --project-id=YOUR_PROJECT_ID
    

    --access-token

    Create and manage access tokens in profile settings or via the Authorizations API.

    --project-id

    Project ID of a project is found in project settings. This creates an initialization file with some configuration options.

  3. Add the JavaScript snippet to your application layout within the <head> tag by using the phraseapp_in_context_editor_js helper:

    <head>
      ...
      <%= phraseapp_in_context_editor_js %>
      ...
    </head>
  4. Open the application in any web browser to see the In-Context Editor applied to the app. Sign in with any Phrase organization user.

  5. Disable Turbolinks (if used)

    Turbolinks removes all In-Context Editor UI elements from the page on every page fetch.

    Add the data-no-turbolink attribute to the <body> tag:

    <body <%= PhraseApp::InContextEditor.enabled? ? "data-no-turbolink" : "" %>>
Code sample

This demo shows an integration of the Phrase In-Context Editor with react-i18next.

Spring

To install the In-Context Editor in this environment, follow these steps:

  1. Ensure the package com.phraseapp.incontexteditor is available in the app.

  2. Set the correct project ID and adjust the other parameters in PhraseAppConfiguration.class.

  3. To render all translations through Phrase, add the bean to the application:

    @Bean
    
    @Conditional(PhraseAppEnabledCondition.class)
    
    public MessageSource messageSource() {
    
        return new PhraseAppMessageSource();
    
    }
  4. Provide the required JavaScript helper in the templates by exposing the helper as a bean:

    @Bean
    
    public PhraseAppJavascriptHeader phraseAppJavascriptHeader() {
    
        return new PhraseAppJavascriptHeader();
    
    }
  5. Add the <script> tag to your templates within each page’s <head> tag:

    <head>
    
        <script th:utext="${@phraseAppJavascriptHeader.getHeader()}"></script>
    
    </head>
  6. Restart the application and sign in with Phrase user credentials.

Example application source code on GitHub

How To Localize Spring Applications Like A Pro

Spring Boot starter package (provided by ePages)

Symfony 2.x

To install the In-Context Editor in this environment, follow these steps:

  1. Create a new environment in which the In-Context Editor will run. In the example, the new environment is named translation.

    Create a new configuration file:

    # app/config/config_translation.yml
    
    imports:
    
        - { resource: config.yml }
    
    parameters:
    
        translator.class: Acme\YourBundle\Translation\PhraseTranslator
  2. Create a controller to make the environment browser accessible:

    # web/app_translation.php
    
    <?php
    
    require_once __DIR__.'/../app/bootstrap.php.cache';
    
    require_once __DIR__.'/../app/AppKernel.php';
    
    use Symfony\Component\HttpFoundation\Request;
    
    $kernel = new AppKernel('translation', false);
    
    $kernel->handle(Request::createFromGlobals())->send();
  3. Override the standard translation method in order to expose the key names to the In-Context Editor:

    # Acme/YourBundle/Translation/PhraseTranslator.php
    
    <?php
    
    namespace Acme\YourBundle\Translation;
    
    use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator;
    
    class PhraseTranslator extends BaseTranslator
    
    {
    
        public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null)
    
        {
    
            $prefix = "";
    
            if (!isset($locale)) {
    
                $locale = $this->getLocale();
    
            }
    
            if (!isset($this->catalogues[$locale])) {
    
                $this->loadCatalogue($locale);
    
            }
    
            if ($domain == 'routes') {
    
                // Return translated values for 'routes' domain
    
                return strtr($this->catalogues[$locale]->get((string) $id, $domain), $parameters);
    
            } else {
    
                // Return PhraseApp translation keys for all other domains
    
                return $prefix.$id.$suffix;
    
            }
    
        }
    
    }
  4. Add the JavaScript snippet to the layout:

    # Acme/YourBundle/Resources/views/layout.html.twig
  5. Open the application in any web browser to see the In-Context Editor applied to the app. Sign in with any Phrase organization user.

Symfony Translation Documentation

Symfony 2.x adapter code on GitHub

Symfony 3.x

To install the In-Context Editor in this environment, follow these steps:

  1. Create a new environment in which the In-Context Editor will run. In the example, the new environment is named translation.

    Create a new configuration file:

    # app/config/config_translation.yml
    
    imports:
    
       - { resource: config.yml }
  2. Create a controller to make the environment browser accessible:

    # web/app_translation.php
    
    <?php
    
    use Symfony\Component\HttpFoundation\Request;
    
    $loader = require __DIR__.'/../app/autoload.php';
    
    $kernel = new AppKernel('translation', true);
    
    $kernel->loadClassCache();
    
    $request = Request::createFromGlobals();
    
    $response = $kernel->handle($request);
    
    $response->send();
    
    $kernel->terminate($request, $response);
  3. Override the standard translation method in order to expose the key names to the In-Context Editor:

    # src/AppBundle/Translation/PhraseTranslator.php
    
    <?php
    
    namespace AppBundle\Translation;
    
    use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator;
    
    class PhraseTranslator extends BaseTranslator
    
    {
    
       public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null)
    
       {
    
           $prefix = "";
    
           if (null === $domain) {
    
               $domain = 'messages';
    
           }
    
           // Return ID of translation key with pre- and suffix for PhraseApp
    
           return $prefix.$id.$suffix;
    
       }
    
    }
  4. Ensure sure the class is always overridden when the bundle is used with a compiler pass:

    # src/AppBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php
    
    <?php
    
    namespace AppBundle\DependencyInjection\Compiler;
    
    use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
    
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    class OverrideServiceCompilerPass implements CompilerPassInterface
    
    {
    
       public function process(ContainerBuilder $container)
    
       {
    
           $definition = $container->getDefinition('translator.default');
    
           $definition->setClass('AppBundle\Translation\PhraseTranslator');
    
       }
    
    }
  5. If using separate compiler passes, register them in the build() method of the bundle class:

    # src/AppBundle/AppBundle.php
    
    <?php
    
    namespace AppBundle;
    
    use Symfony\Component\HttpKernel\Bundle\Bundle;
    
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    use AppBundle\DependencyInjection\Compiler\OverrideServiceCompilerPass;
    
    class AppBundle extends Bundle
    
    {
    
       public function build(ContainerBuilder $container)
    
       {
    
           parent::build($container);
    
           if($container->getParameter("kernel.environment") == 'translation') {
    
               $container->addCompilerPass(new OverrideServiceCompilerPass());
    
           };
    
       }
    
    }
  6. Add the JavaScript snippet to the layout:

    # src/YourBundle/Resources/views/layout.html.twig
  7. Open the application in any web browser to see the In-Context Editor applied to the app. Sign in with any Phrase organization user.

Symfony Translation Documentation

Vue I18n

Note

Vue I18n Phrase In-Context Editor supports all Vue I18n versions 8.17.5 and newer. This library may work with previous versions but this is not supported. as well, they're not officialy supported and won't get any specific updates or bug fixes.

To install the In-Context Editor in this environment, follow these steps:

  1. Install package with preferred package manager:

    # yarn
    yarn add vue-i18n-phrase-in-context-editor
    
    # npm
    npm install vue-i18n-phrase-in-context-editor

    or load with CDN (register manually window['vue-i18n-phrase-in-context-editor'] ):

    <script src="https://unpkg.com/vue-i18n-phrase-in-context-editor/dist/vue-i18n-phrase-in-context-editor.umd.min.js"></script>
    
  2. Bootstrap (sample):

    import Vue from 'vue';
    import VueI18n from 'vue-i18n';
    
    Vue.use(VueI18n);
    
    const i18n = new VueI18n({
      locale: process.env.VUE_APP_I18N_LOCALE || 'en',
      fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
      messages: {
          hello: 'Hello world!'
      }
    });
    
    new Vue({
      i18n,
      render: h => h(App)
    }).$mount('#app');

    To integrate the library:

    1. Import the Vue I18n Phrase In-Context Editor library.

    2. Create new Vue I18n Phrase In-Context Editor instance, passing Vue I18n instance as a first argument and Phrase Config as a second.

Configuration options and sample methods.

Was this article helpful?

Sorry about that! In what way was it not helpful?

The article didn’t address my problem.
I couldn’t understand the article.
The feature doesn’t do what I need.
Other reason.

Note that feedback is provided anonymously so we aren't able to reply to questions.
If you'd like to ask a question, submit a request to our Support team.
Thank you for your feedback.