{"id":250,"date":"2017-04-08T18:59:25","date_gmt":"2017-04-08T18:59:25","guid":{"rendered":"http:\/\/appsbyjohn.com\/learn\/?p=250"},"modified":"2017-04-30T01:09:22","modified_gmt":"2017-04-30T01:09:22","slug":"5-step-guide-on-translating-your-ionic-app-to-reach-a-global-audience","status":"publish","type":"post","link":"https:\/\/appsbyjohn.com\/learn\/5-step-guide-on-translating-your-ionic-app-to-reach-a-global-audience\/","title":{"rendered":"5 Step Guide on Translating your Ionic App to Reach a Global Audience"},"content":{"rendered":"<p><a href=\"#get-guide\">Request a PDF of this post<\/a><\/p>\n<p>An easy way to reach more users with your mobile app is by supporting their native language. Apple strongly encourages <a href=\"https:\/\/developer.apple.com\/internationalization\/\" title=\"Apple guidance on preparing for a global audience\">preparing your app for a global audience<\/a>. This tutorial introduces how to translate your Ionic application to support other languages. My recent <a href=\"https:\/\/itunes.apple.com\/us\/app\/hours-worked\/id536786928?ls=1&#038;mt=8\" title=\"Hours Worked Time Tracker on the App Store\">Hours Worked<\/a> update (version 3.2) included support for 5 other languages. This tutorial walks through updating an app in 5 simple steps:<\/p>\n<p><!--more--><\/p>\n<ol>\n<li>Translate the content of your app<\/li>\n<li>Add the <a href=\"https:\/\/angular-translate.github.io\/\" title=\"Angular Translate module\">Angular Translate<\/a> module to your app<\/li>\n<li>Update your templates<\/li>\n<li>Update your controllers and services<\/li>\n<li>Test your translations<\/li>\n<\/ol>\n<h2>Translate the content of your app<\/h2>\n<p>Before changing any code we need all app content translated. Create a text document of <i>every<\/i> piece of text from your app. Be sure to check everything. Here are some considerations:<\/p>\n<ul>\n<li>Text from each Template<\/li>\n<li>Text from each Controller<\/li>\n<li>Text from each Service<\/li>\n<li>Text returned from a Filter<\/li>\n<li>App Store Description<\/li>\n<li>App Store keywords<\/li>\n<\/ul>\n<p>Unless you are multilingual you need to use a translation service to convert text to your preferred language(s). I have used a website called <a href=\"https:\/\/www.icanlocalize.com\/site\/\" title=\"Pay for text translations\">I Can Localize<\/a> in the past. You can also find affordable translations for sale on <a href=\"https:\/\/www.fiverr.com\/\" title=\"Fiverr website\">Fiverr<\/a>. I recommend finding a translator with experience translating mobile apps.<\/p>\n<p><h2>Add the Angular Translate module to your app<\/h2>\n<p>Assuming you built your app using the Ionic Framework and AngularJS you should use the powerful translation service <a href=\"https:\/\/angular-translate.github.io\/\" title=\"Angular Translate module\">Angular Translate<\/a>. Download the latest release from their repo, unzip the file, and move the <code>angular-translate.min.js<\/code> file to your project <code>js<\/code> folder. Then simply embed the script into your <code>www\/index.html<\/code> file as follows:<\/p>\n<pre><code>&lt;script src=\"js\/angular-translate.min.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n<p>Be sure to inject the module as a dependency into your app. Here is an excerpt from <a href=\"https:\/\/itunes.apple.com\/us\/app\/hours-worked-time-tracker\/id536786928?mt=8\" title=\"Hours Worked Time Tracker on the App Store\">Hours Worked<\/a>:<\/p>\n<pre><code>angular.module('hoursworked', ['pascalprecht.translate'])<\/code><\/pre>\n<p>Then teach the app about your translations using the <code>$translateProvider<\/code>. Here is a sample from Hours Worked:<\/p>\n<pre><code>$translateProvider.translations('en', {\r\n  start_label: \"Start Time\",\r\n  end_label: \"End Time\"\r\n});\r\n\r\n$translateProvider.translations('es', {\r\n  start_label: \"Principio\",\r\n  end_label: \"Fin\"\r\n});\r\n\r\n$translateProvider.translations('pt', {\r\n  start_label: \"Hora de In\u00edcio\",\r\n  end_label: \"Hora de T\u00e9rmino\"\r\n});\r\n\r\n$translateProvider.translations('zh', {\r\n  start_label: \"\u5f00\u59cb\u65f6\u95f4\",\r\n  end_label: \"\u65f6\u95f4\u7ed3\u675f\"\r\n});\r\n\r\n$translateProvider.preferredLanguage(\"en\");\r\n$translateProvider.fallbackLanguage(\"en\");<\/code><\/pre>\n<h2>Update your templates<\/h2>\n<p>Now that your app is aware of the translations you need to remove all plain text from your templates. Take the &#8220;Start Time&#8221; label from Hours Worked as an example. Here is a snippet of the template before translating the app:<\/p>\n<pre><code>&lt;label class=\"item item-input\"&gt;\r\n  &lt;span class=\"input-label\"&gt;Start Time&lt;\/span&gt;\r\n  &lt;input type=\"time\"&gt;    \r\n&lt;\/label&gt;<\/code><\/pre>\n<p>Here is the same snippet upgraded to use the translation filter:<\/p>\n<pre><code>&lt;label class=\"item item-input\"&gt;\r\n  &lt;span class=\"input-label\"&gt;{{\"start_label\" | translate}}&lt;\/span&gt;\r\n  &lt;input type=\"time\"&gt;    \r\n&lt;\/label&gt;<\/code><\/pre>\n<h2>Update your controllers and services<\/h2>\n<p>After updating each template you will need to update any logic that returns text. Below is a sample from the Controller for the Hours Worked calendar using the translate filter. Note that for a filter to work inside of a controller it must be injected as a dependency: <code>.controller('CalendarCtrl', function($filter) {...<\/code>. After updating the list of dependencies you are free to use the translate filter:<\/p>\n<p><b>Former Controller logic<\/b><\/p>\n<pre><code>DayFactory.index().then(function(hours) {\r\n  $scope.hours = hours;\r\n  if ($scope.allLabel ==\"View All Hours\") {\r\n    $scope.limit = hours.length;\r\n    $scope.allLabel = \"View Less\";\r\n  } else {\r\n    $scope.limit = 5;\r\n    $scope.allLabel = \"View All Hours\";\r\n  }\r\n\r\n}, function(errors) { console.log(errors); });<\/code><\/pre>\n<p><b>Same Controller logic translated<\/b><\/p>\n<pre><code>DayFactory.index().then(function(hours) {\r\n  var va1 = $filter('translate')(\"view_all\");\r\n  var va2 = $filter('translate')(\"view_less\");\r\n  $scope.hours = hours;\r\n  if ($scope.allLabel == va1) {\r\n    $scope.limit = hours.length;\r\n    $scope.allLabel = va2;\r\n  } else {\r\n    $scope.limit = 5;\r\n    $scope.allLabel = va1;\r\n  }\r\n\r\n}, function(errors) { console.log(errors); });<\/code><\/pre>\n<h2>Test your translations<\/h2>\n<p>Testing your translation is simple and dare I say somewhat enjoyable. You will be changing the language and region of your iOS device to test. This is where to find the setting:<\/p>\n<ul>\n<li>Settings App<\/li>\n<li>General<\/li>\n<li>Language &#038; Region<\/li>\n<li>iPhone Language<\/li>\n<li>Select a language you have provided a translation for<\/li>\n<\/ul>\n<p>Then you can re-open your app to confirm that content has been converted. Here is a screencast of me testing the Hours Worked translation in Portuguese:<\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/aGaz0JFr1tY\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<h2 id=\"get-guide\">Get this Guide as a PDF<\/h2>\n<p>Subscribe to the Apps by John Newsletter to get your PDF. I will send you a PDF of this guide and email announcements of any future guides!<\/p>\n<script>(function() {\n\twindow.mc4wp = window.mc4wp || {\n\t\tlisteners: [],\n\t\tforms: {\n\t\t\ton: function(evt, cb) {\n\t\t\t\twindow.mc4wp.listeners.push(\n\t\t\t\t\t{\n\t\t\t\t\t\tevent   : evt,\n\t\t\t\t\t\tcallback: cb\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n})();\n<\/script><!-- Mailchimp for WordPress v4.9.17 - https:\/\/wordpress.org\/plugins\/mailchimp-for-wp\/ --><form id=\"mc4wp-form-1\" class=\"mc4wp-form mc4wp-form-261\" method=\"post\" data-id=\"261\" data-name=\"Get Post PDF\" ><div class=\"mc4wp-form-fields\"><p>\r\n\t<label>Email address: <\/label>\r\n\t<input type=\"email\" name=\"EMAIL\" placeholder=\"Your email address\" required \/>\r\n<\/p>\r\n\r\n<p>\r\n    <label>First Name<\/label>\r\n    <input type=\"text\" name=\"FNAME\">\r\n<\/p>\r\n\r\n<p>\r\n    <label>Last Name<\/label>\r\n    <input type=\"text\" name=\"LNAME\">\r\n<\/p>\r\n\r\n\r\n<p>\r\n    <label>Requested Post<\/label>\r\n    <input type=\"text\" name=\"MMERGE3\" value=\"\/learn\/wp-json\/wp\/v2\/posts\/250\">\r\n<\/p>\r\n\r\n<p>\r\n\t<input type=\"submit\" value=\"Subscribe to get PDF\" \/>\r\n<\/p><\/div><label style=\"display: none !important;\">Leave this field empty if you're human: <input type=\"text\" name=\"_mc4wp_honeypot\" value=\"\" tabindex=\"-1\" autocomplete=\"off\" \/><\/label><input type=\"hidden\" name=\"_mc4wp_timestamp\" value=\"1780623507\" \/><input type=\"hidden\" name=\"_mc4wp_form_id\" value=\"261\" \/><input type=\"hidden\" name=\"_mc4wp_form_element_id\" value=\"mc4wp-form-1\" \/><div class=\"mc4wp-response\"><\/div><\/form><!-- \/ Mailchimp for WordPress Plugin -->\n","protected":false},"excerpt":{"rendered":"<p>Request a PDF of this post An easy way to reach more users with your mobile app is by supporting their native language. Apple strongly encourages preparing your app for a global audience. This tutorial introduces how to translate your Ionic application to support other languages. My recent Hours Worked update (version 3.2) included support &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/appsbyjohn.com\/learn\/5-step-guide-on-translating-your-ionic-app-to-reach-a-global-audience\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;5 Step Guide on Translating your Ionic App to Reach a Global Audience&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-250","post","type-post","status-publish","format-standard","hentry","category-hybrid-app-development"],"_links":{"self":[{"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/posts\/250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/comments?post=250"}],"version-history":[{"count":23,"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/posts\/250\/revisions"}],"predecessor-version":[{"id":290,"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/posts\/250\/revisions\/290"}],"wp:attachment":[{"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/media?parent=250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/categories?post=250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/appsbyjohn.com\/learn\/wp-json\/wp\/v2\/tags?post=250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}