{"id":1063,"date":"2014-09-01T21:52:07","date_gmt":"2014-09-01T16:22:07","guid":{"rendered":"http:\/\/www.allerin.com\/blog\/?p=1063"},"modified":"2016-05-12T15:15:28","modified_gmt":"2016-05-12T09:45:28","slug":"challenges-faced-in-internationalizing-a-rails-application","status":"publish","type":"post","link":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/","title":{"rendered":"Challenges faced in Internationalizing a rails Application"},"content":{"rendered":"<p>While working with one of our Ruby on Rails applications, I wanted to Internationalize the application with full support to Unicode data to be displayed and stored in database.<\/p>\n<p>Here are some Highlights:<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Following Gems are good to be used\/referred:<\/strong><\/p>\n<ol>\n<li>rails-i18n (https:\/\/github.com\/svenfuchs\/rails-i18n)<\/li>\n<\/ol>\n<p>Collection of locale data<\/p>\n<ol>\n<li>i18n-js (https:\/\/github.com\/fnando\/i18n-js)<\/li>\n<\/ol>\n<p>For translations in javascript files<\/p>\n<ol>\n<li>rails-i18nterface (https:\/\/github.com\/mose\/rails-i18nterface)<\/li>\n<\/ol>\n<p>For managing locales and their translations from interface<\/p>\n<ol>\n<li>i18n-recursive-lookup (https:\/\/github.com\/annkissam\/i18n-recursive-lookup)<\/li>\n<\/ol>\n<p>Allow translation definitions to reference other definitions<\/p>\n<ol>\n<li>i18n_data (https:\/\/github.com\/grosser\/i18n_data)<\/li>\n<\/ol>\n<p>List of 2-letter-code\/name pairs for all countries\/languages in all languages<\/p>\n<ol>\n<li>i18n-tasks (https:\/\/github.com\/glebm\/i18n-tasks)<\/li>\n<\/ol>\n<p>Tasks for checking usage of translations, add\/remove unused translations<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Some points to be considered while starting internationalizing:<\/strong><\/p>\n<ol>\n<li>Use dictionaries to maintain commonly used translations so as to avoid repetition of translations in locale files.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol start=\"2\">\n<li>Categorize translations as following<\/li>\n<\/ol>\n<pre>\r\nen:\r\n\r\ndictionary:\r\n\r\nviews:\r\n\r\nhelpers:\r\n\r\nactiverecord:\r\n\r\nmodels:\r\n\r\nuser:\r\n\r\none: Dude\r\n\r\nother: Dudes\r\n\r\nattributes:\r\n\r\nuser:\r\n\r\nname: Username\r\n\r\nmodels:\r\n\r\ncontrollers:\r\n\r\n# gems translations\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<ol start=\"3\">\n<li>Follow alphabetic order for keys<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol start=\"4\">\n<li>If we are avoiding repetition of keys in locales then it is good not to have nesting of keys deeper than 3 levels.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol start=\"5\">\n<li>Check for the for I18n supported messages for gems used in application. Special care should be taken while overriding messages from gems.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol start=\"6\">\n<li>If there is no support for internationalized messages from a gem then we may need to provide translated messages using blocks or by overriding the methods in gem.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol start=\"7\">\n<li>Need to consider data that is stored in database and will be displayed as it is. For example. the status of a person stored in database.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol start=\"8\">\n<li>Searching data must be handled for data where the displayed translated data is actually not present in the database as translated. These cases are where we only show database value by translating on views.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol start=\"9\">\n<li>Writing full keys so that if the part is views is extracted into partials then also the I18n will remain intact.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li>While using third party services or APIs there should be compatibility check on the data accepted by the service provider.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li>UI may get distorted because of the changes in length of translated strings. Use of responsive design is good.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>Challenges faced in internationalizing application:<\/strong><\/p>\n<p>&nbsp;<\/p>\n<ol>\n<li><strong> Breadcrumbs were not translated:<\/strong><\/li>\n<\/ol>\n<p>In application we are using &#8216;breadcrumbs_on_rails&#8217; in our application.<\/p>\n<p>When breadcrumbs are set in controller outside action definition as shown below:<\/p>\n<pre>\r\nclass UsersController &lt; ApplicationController\r\n\r\nadd_breadcrumb I18n.t('general.users'), :users_path, :title =&gt; I18n.t('general.users')\r\n\r\ndef index\r\n\r\n# Something\r\n\r\nend\r\n\r\nend\r\n\r\n<\/pre>\n<p>then they did not get translated on changing locales.<\/p>\n<p>If the breadcrumbs are set inside action then they are translated correctly.<\/p>\n<p>If same breadcrumb is required to be set for all the action then to follow DRY we cannot set breadcrumbs in each action separately.<\/p>\n<pre>\r\nclass UsersController &lt; ApplicationController\r\n\r\ndef index\r\n\r\nadd_breadcrumb I18n.t('general.users'), :users_path, :title =&gt; I18n.t('general.users')\r\n\r\n# Something\r\n\r\nend\r\n\r\nend\r\n\r\n<\/pre>\n<p>Reason: This happens because the add_breadcrumb method that is invoked outside action is class_method and is initialized with `en` locale value at the time of initializing app.<\/p>\n<p>Solution:<\/p>\n<ol>\n<li>Use of proc<\/li>\n<\/ol>\n<pre>\r\nclass UsersController &lt; ApplicationController\r\n\r\nadd_breadcrumb proc{I18n.t('general.users')}, :users_path, :title =&gt; proc{I18n.t('general.users')}\r\n\r\ndef index\r\n\r\n# Something\r\n\r\nend\r\n\r\nend\r\n\r\n<\/pre>\n<ol start=\"2\">\n<li>You can add a before_filter<\/li>\n<\/ol>\n<pre>\r\nclass UsersController &lt; ApplicationController\r\n\r\nbefore_filter :set_breadcrumbs\r\n\r\n\u00a0\r\n\r\ndef index\r\n\r\n# Something\r\n\r\nend\r\n\r\n\u00a0\r\n\r\nprivate\r\n\r\ndef set_breadcrumbs\r\n\r\nadd_breadcrumb I18n.t('general.users'), :users_path, :title =&gt; I18n.t('general.users')\r\n\r\nend\r\n\r\n\u00a0\r\n\r\nend\r\n\r\n<\/pre>\n<ol start=\"2\">\n<li><strong> Issue with Paperclip<\/strong><\/li>\n<\/ol>\n<p>Validation Error messages if directly provided to Paperclip are not translated.<\/p>\n<p>For example:<\/p>\n<pre>\r\nclass User &lt; ActiveRecord::Base\r\n\r\nvalidates_attachment_content_type :document,\r\n\r\n:content_type =&gt; %w(image\/jpeg image\/png image\/gif),\r\n\r\n:message =&gt; I18n.t('document_messages.invalid_content_type')\r\n\r\nend\r\n\r\n<\/pre>\n<p>Workaround is to use `proc`<\/p>\n<pre>\r\nclass User &lt; ActiveRecord::Base\r\n\r\nvalidates_attachment_content_type :document,\r\n\r\n:content_type =&gt; %w(image\/jpeg image\/png image\/gif),\r\n\r\n:message =&gt; proc { I18n.t('document_messages.invalid_content_type') }\r\n\r\nend\r\n\r\n<\/pre>\n<ol start=\"3\">\n<li><strong> Issue with ChronicDuration<\/strong><\/li>\n<\/ol>\n<p>In case of ChronicDuration we were using only `output` method<\/p>\n<p>In this method the translation part was coming from following method<\/p>\n<pre>\r\ndef humanize_time_unit(number, unit, pluralize, keep_zero)\r\n\r\nreturn nil if number == 0 &amp;&amp; !keep_zero\r\n\r\nres = \"#{number}#{unit}\"\r\n\r\n# A poor man's pluralizer\r\n\r\nres &lt;&lt; 's' if !(number == 1) &amp;&amp; pluralize\r\n\r\nres\r\n\r\nend\r\n\r\n<\/pre>\n<p>This method was overriden as following<\/p>\n<pre>\r\ndef humanize_time_unit(number, unit, pluralize, keep_zero)\r\n\r\nreturn nil if number == 0 &amp;&amp; !keep_zero\r\n\r\nres = \"#{number}\" + I18n.t(\"chronic_duration.#{(number != 1 &amp;&amp; pluralize) ? unit + 's' : unit }\")\r\n\r\nend\r\n\r\n<\/pre>\n<p>The required translations were added to locales as following<\/p>\n<pre>\r\nen:\r\n\r\nchronic_duration:\r\n\r\nyear: ' year'\r\n\r\nyears: ' years'\r\n\r\nmonth: ' month'\r\n\r\nmonths: ' months'\r\n\r\nweek: ' week'\r\n\r\nweeks: ' weeks'\r\n\r\nday: ' day'\r\n\r\ndays: ' days'\r\n\r\nhour: ' hour'\r\n\r\nhours: ' hours'\r\n\r\nminute: ' minute'\r\n\r\nminutes: ' minutes'\r\n\r\nsecond: ' second'\r\n\r\nseconds: ' seconds'\r\n\r\n<\/pre>\n<ol start=\"4\">\n<li><strong> Issue with Kaminari<\/strong><\/li>\n<\/ol>\n<p>Setting entry_name as per model is removed as we are using &#8216;entry&#8217; word by default<\/p>\n<pre>\r\ndef page_entries_info(collection, options = {})\r\n\r\nentry_name = collection.total_count == 1 ? t('general.entry') : t('general.entries')\r\n\r\nif collection.total_pages &lt; 2\r\n\r\nt('helpers.page_entries_info.one_page.display_entries', :entry_name =&gt; entry_name, :count =&gt; collection.total_count)\r\n\r\nelse\r\n\r\nfirst = collection.offset_value + 1\r\n\r\nlast = collection.last_page? ? collection.total_count : collection.offset_value + collection.limit_value\r\n\r\nt('helpers.page_entries_info.more_pages.display_entries', :entry_name =&gt; entry_name, :first =&gt; first, :last =&gt; last, :total =&gt; collection.total_count)\r\n\r\nend.html_safe\r\n\r\nend\r\n\r\n<\/pre>\n<ol start=\"5\">\n<li><strong> Issue with overriding validation error message<\/strong><\/li>\n<\/ol>\n<p>Providing error message as a message key to validation does not work correctly.<\/p>\n<p>For example:<\/p>\n<pre>\r\nclass User &lt; ActiveRecord::Base\r\n\r\nvalidates :name, presence: true, message: I18n.t('some.translation.keys.to.custom.validation.message')\r\n\r\nend\r\n\r\n<\/pre>\n<p>Validation error message are looked up as following<\/p>\n<pre>\r\nactiverecord.errors.models.[model_name].attributes.[attribute_name]\r\n\r\nactiverecord.errors.models.[model_name]\r\n\r\nactiverecord.errors.messages\r\n\r\nerrors.attributes.[attribute_name]\r\n\r\nerrors.messages\r\n\r\n<\/pre>\n<p>For above given example it is not required to specify message instead specify it in locale.<\/p>\n<p>Error message will be looked up as following:<\/p>\n<pre>\r\nactiverecord.errors.models.user.attributes.name.blank\r\n\r\nactiverecord.errors.models.user.blank\r\n\r\nactiverecord.errors.messages.blank\r\n\r\nerrors.attributes.name.blank\r\n\r\nerrors.messages.blank\r\n\r\n<\/pre>\n<ol start=\"6\">\n<li><strong> Issue with datepicker<\/strong><\/li>\n<\/ol>\n<p>Following keys used in Datepicker were coming from jquery-ui.min.js are translated after using gem i18n-js<\/p>\n<pre>\r\nprevText:I18n.t('helpers.submit.prev'),nextText:I18n.t('helpers.submit.next'),currentText:I18n.t('trading.tabs.today'),\r\n\r\nmonthNames:[I18n.t('month_names.january'),I18n.t('month_names.february'),I18n.t('month_names.march'),I18n.t('month_names.april'),I18n.t('month_names.may'),I18n.t('month_names.june'),I18n.t('month_names.july'),I18n.t('month_names.august'),I18n.t('month_names.september'),I18n.t('month_names.october'),I18n.t('month_names.november'),I18n.t('month_names.december')],\r\n\r\nmonthNamesShort:[I18n.t('month_names_short.january'),I18n.t('month_names_short.february'),I18n.t('month_names_short.march'),I18n.t('month_names_short.april'),I18n.t('month_names_short.may'),I18n.t('month_names_short.june'),I18n.t('month_names_short.july'),I18n.t('month_names_short.august'),I18n.t('month_names_short.september'),I18n.t('month_names_short.october'),I18n.t('month_names_short.november'),I18n.t('month_names_short.december')],\r\n\r\ndayNames:[I18n.t('day_names.sunday'),I18n.t('day_names.monday'),I18n.t('day_names.tuesday'),I18n.t('day_names.wednesday'),I18n.t('day_names.thursday'),I18n.t('day_names.friday'),I18n.t('day_names.saturday')],\r\n\r\ndayNamesShort:[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"],\r\n\r\ndayNamesMin:[I18n.t('day_names_min.sunday'),I18n.t('day_names_min.monday'),I18n.t('day_names_min.tuesday'),I18n.t('day_names_min.wednesday'),I18n.t('day_names_min.thursday'),I18n.t('day_names_min.friday'),I18n.t('day_names_min.saturday')],\r\n\r\n<\/pre>\n<ol start=\"7\">\n<li><strong> Issue with Uniform<\/strong><\/li>\n<\/ol>\n<p>I had to override the texts from default options of jquery.uniform.js<\/p>\n<pre>\r\nfileDefaultText: I18n.t('js.no_file_chosen'),\r\n\r\nfileBtnText: I18n.t('js.choose_file'),\r\n\r\n<\/pre>\n<ol start=\"8\">\n<li><strong> Issue with prevent_destroy_if_any<\/strong><\/li>\n<\/ol>\n<p>Translation message issue of prevent_destroy_if_any was solved as following<\/p>\n<pre>\r\ndef self.prevent_destroy_if_any(*association_names)\r\n\r\nbefore_destroy do |model|\r\n\r\nassociations_present = []\r\n\r\n\u00a0\r\n\r\nassociation_names.each do |association_name|\r\n\r\nassociation = model.send association_name\r\n\r\nif association.class == Array\r\n\r\nassociations_present &lt;&lt; association_name if association.any?\r\n\r\nelse\r\n\r\nassociations_present &lt;&lt; association_name if association\r\n\r\nend\r\n\r\nend\r\n\r\n\u00a0\r\n\r\nif associations_present.any?\r\n\r\nerrors.add :base, \"Cannot delete #{model.class.model_name.human.downcase} while #{associations_present.join ', '} exist\"\r\n\r\nreturn false\r\n\r\nend\r\n\r\n\u00a0\r\n\r\nend\r\n\r\nend\r\n\r\n<\/pre>\n<p>As<\/p>\n<pre>\r\ndef prevent_destroy_if_any(*association_names)\r\n\r\nbefore_destroy do |model|\r\n\r\nassociations_present = []\r\n\r\n\u00a0\r\n\r\nassociation_names.each do |association_name|\r\n\r\nassociation = model.send association_name\r\n\r\nif association.class == Array\r\n\r\nassociations_present &lt;&lt; association.first.class.model_name.human(:count =&gt; 2).downcase if association.any?\r\n\r\nelse\r\n\r\nassociations_present &lt;&lt; association.class.model_name.human.downcase if association\r\n\r\nend\r\n\r\nend\r\n\r\n\u00a0\r\n\r\nif associations_present.any?\r\n\r\nerrors.add(\r\n\r\n:base,\r\n\r\nI18n.t(\r\n\r\n'messages.cannot_delete_parent_object',\r\n\r\n:parent_object =&gt; model.class.model_name.human.downcase,\r\n\r\n:associated_objects =&gt; associations_present.join(', ')\r\n\r\n)\r\n\r\n)\r\n\r\nreturn false\r\n\r\nend\r\n\r\n\u00a0\r\n\r\nend\r\n\r\nend\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p class=\"normal\">Even related to to few other gems problems were faced that were tackled successfully.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While working with one of our Ruby on Rails applications, I wanted to Internationalize the application with full support to Unicode data to be displayed and stored in database. Here&#8230;<\/p>\n","protected":false},"author":9192191,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[3],"tags":[],"class_list":["post-1063","post","type-post","status-publish","format-standard","hentry","category-technology"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.5 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Challenges faced in Internationalizing a rails Application<\/title>\n<meta name=\"description\" content=\"Here we talk about various Challenges faced in Internationalizing a rails Application. Internationalization is a key component of any web application\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Challenges faced in Internationalizing a rails Application\" \/>\n<meta property=\"og:description\" content=\"While working with one of our Ruby on Rails applications, I wanted to Internationalize the application with full support to Unicode data to be displayed\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/\" \/>\n<meta property=\"og:site_name\" content=\"Artificial Intelligence, ROBOTICS, AUTOMATION\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/allerintech\" \/>\n<meta property=\"article:published_time\" content=\"2014-09-01T16:22:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-05-12T09:45:28+00:00\" \/>\n<meta name=\"author\" content=\"Temp User\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Temp User\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/\"},\"author\":{\"name\":\"Temp User\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/person\\\/1800305fd7a4b1da6e13bbb42425cf27\"},\"headline\":\"Challenges faced in Internationalizing a rails Application\",\"datePublished\":\"2014-09-01T16:22:07+00:00\",\"dateModified\":\"2016-05-12T09:45:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/\"},\"wordCount\":705,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#organization\"},\"articleSection\":[\"Technology\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/\",\"name\":\"Challenges faced in Internationalizing a rails Application\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#website\"},\"datePublished\":\"2014-09-01T16:22:07+00:00\",\"dateModified\":\"2016-05-12T09:45:28+00:00\",\"description\":\"Here we talk about various Challenges faced in Internationalizing a rails Application. Internationalization is a key component of any web application\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/challenges-faced-in-internationalizing-a-rails-application\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Challenges faced in Internationalizing a rails Application\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/\",\"name\":\"Artificial Intelligence, ROBOTICS, AUTOMATION\",\"description\":\"Empowering Futures: Innovating with AI and Machine Learning\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#organization\",\"name\":\"Allerin\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/06\\\/logo-fire.png\",\"contentUrl\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/06\\\/logo-fire.png\",\"width\":1000,\"height\":1000,\"caption\":\"Allerin\"},\"image\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/allerintech\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/allerintech\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/person\\\/1800305fd7a4b1da6e13bbb42425cf27\",\"name\":\"Temp User\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/194a42e22f3078426d730e84e0c45af551304b674cd9cf8b99a0e26d09b974e8?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/194a42e22f3078426d730e84e0c45af551304b674cd9cf8b99a0e26d09b974e8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/194a42e22f3078426d730e84e0c45af551304b674cd9cf8b99a0e26d09b974e8?s=96&d=mm&r=g\",\"caption\":\"Temp User\"},\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/author\\\/tempuser\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Challenges faced in Internationalizing a rails Application","description":"Here we talk about various Challenges faced in Internationalizing a rails Application. Internationalization is a key component of any web application","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/","og_locale":"en_US","og_type":"article","og_title":"Challenges faced in Internationalizing a rails Application","og_description":"While working with one of our Ruby on Rails applications, I wanted to Internationalize the application with full support to Unicode data to be displayed","og_url":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/","og_site_name":"Artificial Intelligence, ROBOTICS, AUTOMATION","article_publisher":"https:\/\/www.facebook.com\/allerintech","article_published_time":"2014-09-01T16:22:07+00:00","article_modified_time":"2016-05-12T09:45:28+00:00","author":"Temp User","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Temp User","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/#article","isPartOf":{"@id":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/"},"author":{"name":"Temp User","@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/person\/1800305fd7a4b1da6e13bbb42425cf27"},"headline":"Challenges faced in Internationalizing a rails Application","datePublished":"2014-09-01T16:22:07+00:00","dateModified":"2016-05-12T09:45:28+00:00","mainEntityOfPage":{"@id":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/"},"wordCount":705,"commentCount":0,"publisher":{"@id":"https:\/\/www.allerin.com\/blog\/#organization"},"articleSection":["Technology"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/","url":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/","name":"Challenges faced in Internationalizing a rails Application","isPartOf":{"@id":"https:\/\/www.allerin.com\/blog\/#website"},"datePublished":"2014-09-01T16:22:07+00:00","dateModified":"2016-05-12T09:45:28+00:00","description":"Here we talk about various Challenges faced in Internationalizing a rails Application. Internationalization is a key component of any web application","breadcrumb":{"@id":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.allerin.com\/blog\/challenges-faced-in-internationalizing-a-rails-application\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.allerin.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Challenges faced in Internationalizing a rails Application"}]},{"@type":"WebSite","@id":"https:\/\/www.allerin.com\/blog\/#website","url":"https:\/\/www.allerin.com\/blog\/","name":"Artificial Intelligence, ROBOTICS, AUTOMATION","description":"Empowering Futures: Innovating with AI and Machine Learning","publisher":{"@id":"https:\/\/www.allerin.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.allerin.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.allerin.com\/blog\/#organization","name":"Allerin","url":"https:\/\/www.allerin.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.allerin.com\/blog\/wp-content\/uploads\/2016\/06\/logo-fire.png","contentUrl":"https:\/\/www.allerin.com\/blog\/wp-content\/uploads\/2016\/06\/logo-fire.png","width":1000,"height":1000,"caption":"Allerin"},"image":{"@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/allerintech","https:\/\/www.linkedin.com\/company\/allerintech"]},{"@type":"Person","@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/person\/1800305fd7a4b1da6e13bbb42425cf27","name":"Temp User","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/194a42e22f3078426d730e84e0c45af551304b674cd9cf8b99a0e26d09b974e8?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/194a42e22f3078426d730e84e0c45af551304b674cd9cf8b99a0e26d09b974e8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/194a42e22f3078426d730e84e0c45af551304b674cd9cf8b99a0e26d09b974e8?s=96&d=mm&r=g","caption":"Temp User"},"url":"https:\/\/www.allerin.com\/blog\/author\/tempuser\/"}]}},"_links":{"self":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/1063","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/users\/9192191"}],"replies":[{"embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/comments?post=1063"}],"version-history":[{"count":4,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/1063\/revisions"}],"predecessor-version":[{"id":1390,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/1063\/revisions\/1390"}],"wp:attachment":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/media?parent=1063"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/categories?post=1063"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/tags?post=1063"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}