Set up In-Context Editor
Introduction
To install the PhraseApp In-Context Editor the following steps are required:
- Expose the key names of your template
- Add our JavaScript snippet to render the editor interface
We provide ready-to-use adapters for common web frameworks. If we do not yet offer an adapter for your technology, you can easily implement it yourself by following the instructions for custom integrations.
Installation
Screencast
This short screencast will show you how to setup the In-Context Editor for your Rails-App in an easy way.
Add the gem
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
Initialize the gem
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
You can create and manage access tokens in your profile settings or via the Authorizations API.
--project-id
You can find the ID of your project in your project settings in Translation Center.
This will create an initializer file with some configuration options.
Activate the In-Context Editor
Enable In-Context Editor in your phraseapp_in_context_editor.rb
initializer file:
config.enabled = true
Add the JavaScript
Add the JavaScript snippet to your application layout within the <head>
section by using the phraseapp_in_context_editor_js
helper:
<head>
...
<%= phraseapp_in_context_editor_js %>
...
</head>
Done
Open your application in the browser to see the In-Context Editor applied to your app. You can sign in with any user of your PhraseApp account.
Turbolinks
In-Context Editor currently does not work with Turbolinks because Turbolinks will remove all In-Context Editor UI from the page on every page fetch.
To solve this, we recommend disabling Turbolinks when using In-Context Editor by adding the data-no-turbolink
attribute to your body
tag, e.g.
<body <%= PhraseApp::InContextEditor.enabled? ? "data-no-turbolink" : "" %>>
This guide covers integration with angular-phrase
an addon for the excellent angular-translate module by Pascal Precht.
Install angular-phrase
Install angular-phrase
via Bower (or download it manually):
$ bower install angular-phrase
Add the module to your AngularJS application
Add the angular-phrase
module to your existing AngularJS application after loading the angular-translate
module:
var myApp = angular.module("myApp", ['pascalprecht.translate', 'phrase']);
Configure
Configure the module:
myApp.value("phraseProjectId", "YOUR-PROJECT-ID");
myApp.value("phraseEnabled", true);
myApp.value("phraseDecoratorPrefix", "{{__");
myApp.value("phraseDecoratorSuffix", "__}}");
You can find the ID of your project in your project settings in Translation Center.
Please see In-Context Editor configuration guide for more information on available configuration options.
Add the JavaScript snippet
Add the phrase-javascript
directive within your application, usually best within the <head>
:
<phrase-javascript></phrase-javascript>
Done
Open your application in the browser to see the In-Context Editor applied to your app. You can sign in with any user of your PhraseApp account.
More
We provide an adapter to use the In-Context Editor with ngx-translate. If you're using a different localization library along with Angular 2+, please check out our guide for custom integrations.
Installation
Installation instructionsMore
We provide adapters to use the In-Context Editor with react-i18next and react-intl. If you're using a different localization library along with React, please check out our guide for custom integrations.
Installation
Follow the installation instructions for your i18n library of choice:
- react-intl-phraseapp (for use with react-intl)
- react-i18next-phraseapp (for use with react-i18next)
More
Create a new environment
We recommend creating a new environment in which In-Context Editor should run. Let's call the new environment translation
:
Start by creating a new configuration file:
# app/config/config_translation.yml
imports:
- { resource: config.yml }
parameters:
translator.class: Acme\YourBundle\Translation\PhraseTranslator
The environment should be accessible in the browser, so lets create a front controller for it:
# 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();
Extending the Base Translator
You need to 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 = "{{__phrase_";
$suffix = "__}}";
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;
}
}
}
Add the JavaScript snippet
To load the In-Context Editor, you need to add the JavaScript snippet to your layout:
# Acme/YourBundle/Resources/views/layout.html.twig
{% if app.environment == 'translation' %}
<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>
{% endif %}
Done.
Start translating your app by accessing your front controller in the browser!
More
Create a new environment
We recommend creating a new environment in which In-Context Editor should run. Let's call the new environment translation
:
Start by creating a new configuration file:
# app/config/config_translation.yml
imports:
- { resource: config.yml }
The environment should be accessible in the browser, so lets create a front controller for it:
# 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);
Extending the Base Translator
You need to 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 = "{{__phrase_";
$suffix = "__}}";
if (null === $domain) {
$domain = 'messages';
}
// Return ID of translation key with pre- and suffix for PhraseApp
return $prefix.$id.$suffix;
}
}
Creating Compiler Pass
Now, to make sure the class is always overridden when your bundle is used, you should use 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');
}
}
When using separate compiler passes, you need to 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());
};
}
}
Add the JavaScript snippet
To load the In-Context Editor, you need to add the JavaScript snippet to your layout (don't forget to set your project id):
# src/YourBundle/Resources/views/layout.html.twig
{% if app.environment == 'translation' %}
<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>
{% endif %}
Done.
Start translating your app by accessing your front controller in the browser!
More
Add the package
Install the django-phrase
package with pip
:
$ pip install django-phrase
And add phrase
to the list of installed apps:
INSTALLED_APPS = (
'phrase',
)
Extend the template
You can now use the phrase_i18n
template tag in your templates:
{% load phrase_i18n %}
Note: You have to load phrase_i18n
after you load ì18n
in order to let django-phrase
override the translation methods.
Add the JavaScript snippet
Add the JavaScript snippet to your base layout file. This should go inside the <head> section of your template file:
{% phrase_javascript %}
Configuration
You can configure the In-Context Editor in your settings by using these options:
PHRASE_ENABLED = True
PHRASE_PROJECT_ID = 'YOUR_PROJECT_ID'
PHRASE_PREFIX = '{{__'
PHRASE_SUFFIX = '__}}'
Done
Open your application in the browser to see the In-Context Editor applied to your application. You can sign in with any user of your PhraseApp account.
More
Copy the source code
Make sure the package com.phraseapp.incontexteditor
is available in your app. You can check it out on GitHub.
Configure your Project ID
Set the correct project ID and adjust the remaining configuration in PhraseAppConfiguration.class
.
Apply PhraseApp as your MessageSource
In order to render all translations through PhraseApp, you must add the bean to your application:
@Bean
@Conditional(PhraseAppEnabledCondition.class)
public MessageSource messageSource() {
return new PhraseAppMessageSource();
}
Add the Javascript
Provide the required Javascript helper in your templates by exposing the helper as a bean:
@Bean
public PhraseAppJavascriptHeader phraseAppJavascriptHeader() {
return new PhraseAppJavascriptHeader();
}
and then adding the script tag to your templates, within the page head:
<head>
<script th:utext="${@phraseAppJavascriptHeader.getHeader()}"></script>
</head>
Restart the application and sign in with your PhraseApp user credentials.
More
If there is no ready-to-use adapter for your technology yet, you can easily implement it yourself following the instructions for custom integrations.