{"id":305,"date":"2020-08-20T12:25:34","date_gmt":"2020-08-20T10:25:34","guid":{"rendered":"http:\/\/www.myblog.nguenkam.com\/?p=305"},"modified":"2020-08-20T12:34:44","modified_gmt":"2020-08-20T10:34:44","slug":"internationalization-variante-with-ngx-i18nsupport","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2020\/08\/20\/internationalization-variante-with-ngx-i18nsupport\/","title":{"rendered":"Internationalization ( variante with ngx-i18nsupport)"},"content":{"rendered":"\n<p>Angular has a specific way of dealing with internationalization (i18n). It is described in the official documentation Angular Cookbook&nbsp;<a href=\"https:\/\/angular.io\/docs\/ts\/latest\/cookbook\/i18n.html\">Internationalization (i18n)<\/a>.<\/p>\n\n\n\n<p>Said in one sentence,<\/p>\n\n\n\n<ul><li>markup your strings to translate in your templates with an attribute&nbsp;<code>i18n<\/code><\/li><li>run the Amgular extraction tool (<code>ng-xi18n<\/code>) to extract the strings in an XML Format called&nbsp;<a href=\"http:\/\/docs.oasis-open.org\/xliff\/v1.2\/os\/xliff-core.html\">[XLIFF-1.2]<\/a><\/li><li>copy and then translate the extracted file for every language you plan to support<\/li><li>run the ng compiler to generate a special version of your app for the different languages<\/li><\/ul>\n\n\n\n<p>There is an excellent Blog Article <a href=\"https:\/\/www.myblog.nguenkam.com\/index.php\/2020\/08\/20\/internationalization-i18n-with-angular\/\" data-type=\"post\" data-id=\"282\">here<\/a>&nbsp;, which describes it in detail.<\/p>\n\n\n\n<p><span class=\"has-inline-color has-vivid-red-color\">But there are some maior gaps in the workflow<\/span>. That\u00b4s where this tool comes into play.<\/p>\n\n\n\n<p>First, you have to create a complete translation, otherwise, the ng compiler will not generate a version. It is not possible to run with&nbsp;<strong>partial translation<\/strong>.<\/p>\n\n\n\n<p>Second, whenever you change something in your app, you have to regenerate the xliff, but there is no documented way how to\u00a0<strong>merge<\/strong>\u00a0this with the already\u00a0<strong>existing<\/strong>\u00a0translated files. There are new translation unit, that you have to merge in, and there are translation units, that do not exist any more.<\/p>\n\n\n\n<h4>Tutorial for using xliffmerge with angular cli<\/h4>\n\n\n\n<p>This tutorial shows in a few step, how to use&nbsp;<code>xliffmerge<\/code>&nbsp;in an Angular App, which is generated with&nbsp;<code>angular-cli<\/code>.<\/p>\n\n\n\n<p>It shows the basic workflow for preparing an application for translation, translating it, running it, changing it, translating it again, running it again&#8230;<\/p>\n\n\n\n<h4>Start a new project<\/h4>\n\n\n\n<p>If you haven&#8217;t done it at all, install\u00a0<code>angular-cli<\/code>\u00a0globally:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install -g @angular\/cli@latest<\/code><\/pre>\n\n\n\n<p>Then you can create a new project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ng new sampleapp\r\n\r\ncd sampleapp<\/code><\/pre>\n\n\n\n<h4>Prepare the app for translations<\/h4>\n\n\n\n<p>For this tutorial we assume that your preferred language is not English, but something else, e.g. German. So you want to write your application in German and translate it to English later. <\/p>\n\n\n\n<p>So as a first step we change our application to German and additionally mark all text, that needs translation, with an\u00a0<code>i18n<\/code>-Attribute. For details have a look at the\u00a0<a href=\"https:\/\/angular.io\/docs\/ts\/latest\/cookbook\/i18n.html\">Angular Cookbook about Internationalization<\/a>.<\/p>\n\n\n\n<p>Our\u00a0<code>src\/app\/app.component.html<\/code>\u00a0(generated by the cli) now looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;div style=\"text-align:center\">\r\n  &lt;h1 i18n>\r\n    Willkommen zu {{ title }}!\r\n  &lt;\/h1>\r\n  &lt;img ..>\r\n&lt;\/div>\r\n&lt;h2 i18n>Hier einige Links, die den Anfang erleichtern: &lt;\/h2><\/code><\/pre>\n\n\n\n<h4>Add the xliffmerge tooling to your project<\/h4>\n\n\n\n<p>There is an\u00a0<code>ng add Schematic<\/code>\u00a0to add the toling to your new project. Just type<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ng add @ngx-i18nsupport\/tooling --i18nLocale=de --languages de,en<\/code><\/pre>\n\n\n\n<p>The parameter\u00a0<code>--i18nLocale=de<\/code>\u00a0tells that you are using German as your default language (&#8220;en&#8221; is the default if you do not specify it). And the parameter\u00a0<code>--languages de,en<\/code>\u00a0sets all the languages that you are planning to use in the moment (of course you can add more languages later on).<\/p>\n\n\n\n<p>You will see some output like this<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> added script extract-i18n to \/\/package.json\r\n    added npm script to extract i18n message, run \"npm run extract-i18n\" for extraction\r\n    added script start-en to \/\/package.json\r\n    added npm script to start app for language en, run \"npm run start-en\"\r\n    added build configuration en to project sampleapp\r\n    added build configuration for language \"en\" to project \"sampleapp\"\r\n    added serve configuration en to project sampleapp\r\n    added serve configuration for language \"en\" to project \"sampleapp\"\r\n    added architect builder xliffmerge to project sampleapp\r\n    added builder xliffmerge to project \"sampleapp\"\r\nUPDATE package.json (1647 bytes)\r\nUPDATE angular.json (4613 bytes)<\/code><\/pre>\n\n\n\n<p>As you can see there are changes on your workspace file\u00a0<code>angular.json<\/code>\u00a0and on your\u00a0<code>package.json<\/code>. There are some new scripts installed in your\u00a0<code>package.json<\/code>\u00a0to start your application using different languages and there is a new script to extract translatable parts from your application.<\/p>\n\n\n\n<h4>Generate a messages.xlf file<\/h4>\n\n\n\n<p>After the initial changes described in the previous chapter your application now contains some i18n marked stuff. So now you can extract this stuff for translation.<\/p>\n\n\n\n<p>angular-cli has a build in task\u00a0<code>xi18n<\/code>\u00a0for this. So you could just type<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ng xi18n sampleapp --output-path i18n --i18n-locale de<\/code><\/pre>\n\n\n\n<p>The\u00a0<code>ng add @ngx-i18nsupport\/tooling<\/code>\u00a0added a script to your\u00a0<code>package.json<\/code>\u00a0that does this for you. You will find the following in your\u00a0<code>package.json<\/code>\u00a0scripts section:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\r\n  &#91;...]\r\n  \"scripts\": {\r\n    &#91;...]\r\n    \"extract-i18n\": \"ng xi18n sampleapp --i18n-format xlf --output-path i18n --i18n-locale de &amp;&amp; ng run sampleapp:xliffmerge\"\r\n  }\r\n  &#91;...]\r\n}<\/code><\/pre>\n\n\n\n<p class=\"has-black-color has-text-color\"> PS:<em> but if you have installed the<\/em> &#8220;@ngx-i18nsupport\/tooling&#8221; <em> trought &#8220;npm install&#8221; command, then you will have to write te script by yourself. <\/em><\/p>\n\n\n\n<p>Then you can type<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run extract-i18n<\/code><\/pre>\n\n\n\n<p>Some words about the parameters used in the command.<\/p>\n\n\n\n<p><code>--output-path<\/code>&nbsp;specifies the path (relativ to&nbsp;<code>src<\/code>) where the generated file will be saved. We prefer to have it under&nbsp;<code>src\/i18n<\/code>.<\/p>\n\n\n\n<p><code>--i18n-locale<\/code>&nbsp;specifies the language that is used in the templates (the default language, German in this tutorial).<\/p>\n\n\n\n<p>After running the command you will find a newly generated file\u00a0<code>src\/i18n\/messages.xlf<\/code>. If you open it with a text editor, you will see that it is an XML file containing some somewhat strange markup wich is defined by XLF<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\r\n      &lt;trans-unit id=\"91fcc40bc784cacec7c70d5f1eee77ebc1d8d308\" datatype=\"html\">\r\n        &lt;source>\r\n    Willkommen zu &lt;x id=\"INTERPOLATION\" equiv-text=\"{{ title }}\"\/>!\r\n  &lt;\/source>\r\n        &lt;context-group purpose=\"location\">\r\n          &lt;context context-type=\"sourcefile\">app\/app.component.ts&lt;\/context>\r\n          &lt;context context-type=\"linenumber\">3&lt;\/context>\r\n        &lt;\/context-group>\r\n      &lt;\/trans-unit>\r\n      &lt;trans-unit id=\"1bd7be430ac3f26a91a30d76868397fa8fea9882\" datatype=\"html\">\r\n        &lt;source>Hier einige Links, die den Anfang erleichtern: &lt;\/source>\r\n        &lt;context-group purpose=\"location\">\r\n          &lt;context context-type=\"sourcefile\">app\/app.component.ts&lt;\/context>\r\n          &lt;context context-type=\"linenumber\">8&lt;\/context>\r\n        &lt;\/context-group>\r\n      &lt;\/trans-unit>\r\n...<\/code><\/pre>\n\n\n\n<p>Following the angular i18n tutorial the next steps would be to<\/p>\n\n\n\n<ul><li>create a copy of this file for every language you want to support.<\/li><li>translate it.<\/li><\/ul>\n\n\n\n<p>This is where\u00a0<code>xliffmerge<\/code>\u00a0comes into play. If you have a look at the generated script, you see that after the normal call of\u00a0<code>ng xi18n<\/code>\u00a0there is a following call\u00a0<code>ng run sampleapp:xliffmerge<\/code>.<\/p>\n\n\n\n<p><code>ng run<\/code>\u00a0is an angular-cli command to run a specific builder (called architect target in cli terminology). This builder is added to the workspace definition file\u00a0<code>angular.json<\/code>. In the section\u00a0<code>architect<\/code>\u00a0in this file you will find something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> \"xliffmerge\": {\r\n          \"builder\": \"@ngx-i18nsupport\/tooling:xliffmerge\",\r\n          \"options\": {\r\n            \"xliffmergeOptions\": {\r\n              \"i18nFormat\": \"xlf\",\r\n              \"srcDir\": \"src\/i18n\",\r\n              \"genDir\": \"src\/i18n\",\r\n              \"defaultLanguage\": \"de\",\r\n              \"languages\": &#91;\r\n                \"de\",\r\n                \"en\"\r\n              ]\r\n            }\r\n          }\r\n        }<\/code><\/pre>\n\n\n\n<p>This is the builder definition. In the options section you find some configuration options and the languages used. What options are available is discussed in detail in the\u00a0<a href=\"https:\/\/github.com\/martinroob\/ngx-i18nsupport\/tree\/master\/projects\/xliffmerge#usage\">usage section<\/a>.<\/p>\n\n\n\n<h4>Generating language specific files<\/h4>\n\n\n\n<p>After running\u00a0<code>npm run extract-i18n<\/code>\u00a0you will see some warnings:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WARNING: please translate file \"src\/i18n\/messages.en.xlf\" to target-language=\"en<\/code><\/pre>\n\n\n\n<p>In addition to the\u00a0<code>ng xi18n<\/code>\u00a0command the xliffmerge architect target has generated a file for your target language &#8220;en&#8221;. The warning tells you that you have to translate the English file.<\/p>\n\n\n\n<p>You will now find 3 files under src\/i18n<\/p>\n\n\n\n<ol><li><code>messages.xlf<\/code>: The master file containing all the messages found in your app.<\/li><li><code>messages.de.xlf<\/code>: The German version.<\/li><li><code>messages.en.xlf<\/code>: The (up to now untranslated) English version.<\/li><\/ol>\n\n\n\n<p>If you open the files with a text editor, you will see<\/p>\n\n\n\n<ul><li><code>messages.xlf<\/code>&nbsp;is the file Angular created for you. There are no&nbsp;<code>&lt;target&gt;<\/code>&nbsp;elements (no translation), the attribute&nbsp;<code>source-language=\"de\"<\/code>&nbsp;tells the source language.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n&lt;xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">\r\n  &lt;file source-language=\"de\" datatype=\"plaintext\" original=\"ng2.template\">\r\n    &lt;body>\r\n...\r\n      &lt;trans-unit id=\"1bd7be430ac3f26a91a30d76868397fa8fea9882\" datatype=\"html\">\r\n        &lt;source>Hier einige Links, die den Anfang erleichtern: &lt;\/source>\r\n...<\/code><\/pre>\n\n\n\n<ul><li><code>messages.de.xlf<\/code>\u00a0contains a copy, but there are\u00a0<code>&lt;target><\/code>\u00a0elements that contain the same values as the source elements. There is an additional attribute\u00a0<code>state=\"final\"<\/code>.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n&lt;xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">\r\n  &lt;file source-language=\"de\" datatype=\"plaintext\" original=\"ng2.template\" target-language=\"de\">\r\n    &lt;body>\r\n      &lt;trans-unit id=\"91fcc40bc784cacec7c70d5f1eee77ebc1d8d308\" datatype=\"html\">\r\n        &lt;source>\r\n    Willkommen zu &lt;x id=\"INTERPOLATION\" equiv-text=\"{{ title }}\"\/>!\r\n  &lt;\/source>\r\n        &lt;context-group purpose=\"location\">\r\n          &lt;context context-type=\"sourcefile\">app\/app.component.ts&lt;\/context>\r\n          &lt;context context-type=\"linenumber\">3&lt;\/context>\r\n        &lt;\/context-group>\r\n      &lt;target state=\"final\">\r\n    Willkommen zu &lt;x id=\"INTERPOLATION\" equiv-text=\"{{ title }}\"\/>!\r\n  &lt;\/target>&lt;\/trans-unit>\r\n      &lt;trans-unit id=\"1bd7be430ac3f26a91a30d76868397fa8fea9882\" datatype=\"html\">\r\n        &lt;source>Hier einige Links, die den Anfang erleichtern: &lt;\/source>\r\n        &lt;context-group purpose=\"location\">\r\n          &lt;context context-type=\"sourcefile\">app\/app.component.ts&lt;\/context>\r\n          &lt;context context-type=\"linenumber\">8&lt;\/context>\r\n        &lt;\/context-group>\r\n      &lt;target state=\"final\">Hier einige Links, die den Anfang erleichtern: &lt;\/target>&lt;\/trans-unit>\r\n    &lt;\/body>\r\n  &lt;\/file>\r\n&lt;\/xliff><\/code><\/pre>\n\n\n\n<ul><li><code>messages.en.xlf<\/code>\u00a0is nearly the same, but the\u00a0<code>target-language<\/code>\u00a0is set to\u00a0<code>en<\/code>\u00a0and all\u00a0<code>&lt;target><\/code>\u00a0elements have an attribute\u00a0<code>state=\"new\"<\/code>. This marks the fact that you have to translate it by your own.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n&lt;xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">\r\n  &lt;file source-language=\"de\" datatype=\"plaintext\" original=\"ng2.template\" target-language=\"en\">\r\n    &lt;body>\r\n      &lt;trans-unit id=\"91fcc40bc784cacec7c70d5f1eee77ebc1d8d308\" datatype=\"html\">\r\n        &lt;source>\r\n    Willkommen zu &lt;x id=\"INTERPOLATION\" equiv-text=\"{{ title }}\"\/>!\r\n  &lt;\/source>\r\n        &lt;context-group purpose=\"location\">\r\n          &lt;context context-type=\"sourcefile\">app\/app.component.ts&lt;\/context>\r\n          &lt;context context-type=\"linenumber\">3&lt;\/context>\r\n        &lt;\/context-group>\r\n      &lt;target state=\"new\">\r\n    Willkommen zu &lt;x id=\"INTERPOLATION\" equiv-text=\"{{ title }}\"\/>!\r\n  &lt;\/target>&lt;\/trans-unit>\r\n      &lt;trans-unit id=\"1bd7be430ac3f26a91a30d76868397fa8fea9882\" datatype=\"html\">\r\n        &lt;source>Hier einige Links, die den Anfang erleichtern: &lt;\/source>\r\n        &lt;context-group purpose=\"location\">\r\n          &lt;context context-type=\"sourcefile\">app\/app.component.ts&lt;\/context>\r\n          &lt;context context-type=\"linenumber\">8&lt;\/context>\r\n        &lt;\/context-group>\r\n      &lt;target state=\"new\">Hier einige Links, die den Anfang erleichtern: &lt;\/target>&lt;\/trans-unit>\r\n    &lt;\/body>\r\n  &lt;\/file>\r\n&lt;\/xliff><\/code><\/pre>\n\n\n\n<h4>Translate your messages files<\/h4>\n\n\n\n<p>Next you have to translate\u00a0<code>messages.en.xlf<\/code>\u00a0by yourself. Use a translation tool, if you want. E.g. have a look at\u00a0<a href=\"https:\/\/github.com\/martinroob\/tiny-translator\">Tiny Translator<\/a>. At the end you just replace the target elements with the translated version and you change the state attribute to\u00a0<code>state=\"translated\"<\/code>\u00a0or even better to\u00a0<code>state=\"final\"<\/code>\u00a0to mark it as fully reviewed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n&lt;xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">\r\n  &lt;file source-language=\"de\" datatype=\"plaintext\" original=\"ng2.template\" target-language=\"en\">\r\n    &lt;body>\r\n      &lt;trans-unit id=\"91fcc40bc784cacec7c70d5f1eee77ebc1d8d308\" datatype=\"html\">\r\n        &lt;source>\r\n    Willkommen zu &lt;x id=\"INTERPOLATION\" equiv-text=\"{{ title }}\"\/>!\r\n  &lt;\/source>\r\n        &lt;context-group purpose=\"location\">\r\n          &lt;context context-type=\"sourcefile\">app\/app.component.ts&lt;\/context>\r\n          &lt;context context-type=\"linenumber\">3&lt;\/context>\r\n        &lt;\/context-group>\r\n      &lt;target state=\"final\">\r\n    Welcome to &lt;x id=\"INTERPOLATION\" equiv-text=\"{{ title }}\"\/>!\r\n  &lt;\/target>&lt;\/trans-unit>\r\n      &lt;trans-unit id=\"1bd7be430ac3f26a91a30d76868397fa8fea9882\" datatype=\"html\">\r\n        &lt;source>Hier einige Links, die den Anfang erleichtern: &lt;\/source>\r\n        &lt;context-group purpose=\"location\">\r\n          &lt;context context-type=\"sourcefile\">app\/app.component.ts&lt;\/context>\r\n          &lt;context context-type=\"linenumber\">8&lt;\/context>\r\n        &lt;\/context-group>\r\n      &lt;target state=\"final\">Here are some links to start with: &lt;\/target>&lt;\/trans-unit>\r\n    &lt;\/body>\r\n  &lt;\/file>\r\n&lt;\/xliff><\/code><\/pre>\n\n\n\n<p>Do not forget to put the translated files under configuration management, they should all be considered as source files<\/p>\n\n\n\n<h4>Run your English version of the app<\/h4>\n\n\n\n<p>There already is a start script added to your\u00a0<code>package.json<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\r\n  &#91;...]\r\n  \"scripts\": {\r\n    &#91;...]\r\n    \"extract-i18n\": ...,\r\n    \"start-en\": \"ng serve --configuration=en\"\r\n  }\r\n  &#91;...]\r\n}<\/code><\/pre>\n\n\n\n<p>and there also is a configuration change in your\u00a0<code>angular.json<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>..\"build\": {\r\n    \"configurations\": {\r\n..\r\n            \"en\": {\r\n              \"aot\": true,\r\n              \"outputPath\": \"dist\/sampleapp-en\",\r\n              \"i18nFile\": \"src\/i18n\/messages.en.xlf\",\r\n              \"i18nFormat\": \"xlf\",\r\n              \"i18nLocale\": \"en\"\r\n            }\r\n..\"serve\": {\r\n..\r\n          \"configurations\": {\r\n..\r\n            \"en\": {\r\n              \"browserTarget\": \"sampleapp:build:en\"\r\n            }<\/code><\/pre>\n\n\n\n<p>Run<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run start-en<\/code><\/pre>\n\n\n\n<p>You now will see the English version of your app:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"975\" height=\"389\" src=\"https:\/\/www.myblog.nguenkam.com\/wp-content\/uploads\/2020\/08\/en-translate.png\" alt=\"\" class=\"wp-image-308\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2020\/08\/en-translate.png 975w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2020\/08\/en-translate-300x120.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2020\/08\/en-translate-768x306.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p>Congratulations! You did it \ud83d\ude42 <\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>PS:<em> the following script-command could be sub-divise in 2 scripts<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"scripts\": { ...\n     \"extract-i18n\": \"ng xi18n sampleapp --i18n-format xlf -- output-path i18n --i18n-locale de &amp;&amp; ng run sampleapp:xliffmerge\"\n...}\r<\/code><\/pre>\n\n\n\n<p>is the same als:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"scripts\"{...\n\n    \"extract-i18n\": \"ng xi18n sampleapp --i18n-format xlf --output-path i18n --i18n-locale de\"\n    \"merge-i18n\":\"ng run sampleapp:xliffmerge\"\n\n...}<\/code><\/pre>\n\n\n\n<h4>reference<\/h4>\n\n\n\n<p><a href=\"https:\/\/www.npmjs.com\/\">https:\/\/www.npmjs.com\/<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/\">https:\/\/github.com\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Angular has a specific way of dealing with internationalization (i18n). It is described in the official documentation Angular Cookbook&nbsp;Internationalization (i18n). Said in one sentence, markup your strings to translate in your templates with an attribute&nbsp;i18n run the Amgular extraction tool (ng-xi18n) to extract the strings in an XML Format called&nbsp;[XLIFF-1.2] copy and then translate the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":309,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,37,44,48],"tags":[40,47,45,46,49],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/305"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=305"}],"version-history":[{"count":6,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/305\/revisions"}],"predecessor-version":[{"id":313,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/305\/revisions\/313"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/309"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=305"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=305"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=305"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}