{"id":98,"date":"2019-01-26T23:15:29","date_gmt":"2019-01-26T23:15:29","guid":{"rendered":"http:\/\/tamer-az.com\/?p=98"},"modified":"2019-01-26T23:15:29","modified_gmt":"2019-01-26T23:15:29","slug":"translating-your-theme","status":"publish","type":"post","link":"https:\/\/tamer-az.com\/?p=98","title":{"rendered":"Translating Your Theme"},"content":{"rendered":"\n<p>It&#8217;s very easy to turn a blind eye to\n other languages when developing your WordPress theme, but this is a \nvery bad habit and immediately turns away a whole market of WordPress \nusers and potentially thousands of dollars in lost revenue. Out of the \ntop 10 countries that search Google for &#8220;WordPress themes&#8221;, only one is \nnative English speaking (the USA) and that comes 9th. As of writing \nthis, there are only 269 themes in WordPress&#8217; theme database that are \ntagged as translation-ready out of more than 1,500 themes. That&#8217;s only \n18% of the themes. I&#8217;m going to show you how to make yours one of them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How It Works<\/h2>\n\n\n\n<p>When you usually make a theme, you will simply hardcode any theme text such as the 404 error message in the <em>404.php<\/em>\n file, or labels such as &#8220;comments:&#8221; or &#8220;author:&#8221;. If the user&#8217;s \nWordPress is German for example, these snippets of text will still \ndisplay in English. The solution to this is to return or echo these \nstatements using one of four WordPress functions which are designed to \nreference a language file for the correct text. Once you have your text \nwrapped in these functions, you can create a file containing all the \ntranslations that is referenced every time the theme is loaded. There \nare three translation files that we use:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>.pot <em>(Portable Object Template)<\/em> \u2013 This is the template file\n that contains a reference to each text string in your theme that needs \ntranslating. This file does not contain any translation. It is a \nplaintext file.<\/li><li>.po <em>(Portable Object)<\/em> \u2013 Made from the .pot file, the .po \ncontains all your string references as well as their translations to one\n specific language. This is also a plaintext file that can be edited.<\/li><li>.mo <em>(Machine Object)<\/em> \u2013 A binary version of the .po file. By using machine code, the file can be used much faster than its plaintext alternative.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\nStep 1 The Four Functions<\/h2>\n\n\n\n<p>Each of the four functions requires at least one argument, which is the text that is to be translated. The functions are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>\n<code>__()<\/code> \u2013 <em>(two underscores)<\/em> The basic function that you will use the majority of the time. It returns the text in the correct language.<\/li><li>\n<code>_e()<\/code> \u2013 The same as <code>__()<\/code> except it echoes the text instead of returning it.<\/li><li>\n<code>_n()<\/code> \u2013 Used when the text has the potential to be plural, \nso for example if you were to display how many comments have been made, \nyou might want to output either &#8220;X comments&#8221; or &#8220;X comment&#8221; depending on\n how many comments you have.<\/li><li>\n<code>_x()<\/code> \u2013 Useful for when the translation of the word depends on the context. &#8220;Post&#8221; could mean &#8220;a post <em>(noun)<\/em>&#8221; or &#8220;to post <em>(verb)<\/em>&#8221; depending on context. It is important for the translator to know which you mean when translating to be accurate. <code>_x()<\/code> is mainly used where single words are used.\n<\/li><\/ul>\n\n\n\n<figure><iframe loading=\"lazy\" src=\"https:\/\/tpc.googlesyndication.com\/safeframe\/1-0-31\/html\/container.html\" width=\"300\" height=\"250\"><\/iframe><\/figure>\n\n\n\n<p>Advertisement<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">__() &amp; _e()<\/h3>\n\n\n\n<p>These are the simplest translation functions that WordPress has to offer. Let&#8217;s take a look at an example of each:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>12345<\/td><td><code>&lt;?php<\/code><code>if<\/code><code>( is_single() ) { <\/code><code>\/\/If this is a \"post\"<\/code><code>echo<\/code> <code>__( <\/code><code>'This is a post.'<\/code> <code>);<\/code><code>}<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>12345<\/td><td><code>&lt;?php<\/code><code>if<\/code><code>( is_single() ) { <\/code><code>\/\/If this is a \"post\"<\/code><code>_e( <\/code><code>'This is a post.'<\/code> <code>);<\/code><code>}<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Both of these functions are doing exactly the same thing here. The \nstatement &#8220;this is a post&#8221; is being checked against the .mo file if \nthere is one, and returning the result. <code>__()<\/code> and <code>_e()<\/code>\n only require one argument to be passed to them, which is the text we \nwant to be translated. A second optional argument is available and we&#8217;ll\n come to that later. The only difference between the two is that <code>__()<\/code> needs the <code>echo<\/code> statement here. Let&#8217;s look at an example where <code>__()<\/code> works better than <code>_e()<\/code>:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>123<\/td><td><code>&lt;?php<\/code><code>the_content( __( <\/code><code>'Click here to read more'<\/code> <code>) );<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Instead of passing a string to the <code>the_content()<\/code> function, we have used <code>__()<\/code> so that the text can be translated. If we had used <code>_e()<\/code> here instead, you would have the translation of &#8220;Click here to read more&#8221; echoed to the document instead of being passed to <code>the_content()<\/code> which would cause all sorts of unhelpful problems.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">_n()<\/h3>\n\n\n\n<p>What if you have a situation where the text you output could \npotentially be a plural or a singular like the &#8220;X comments&#8221; example \nabove? Instead of giving two different text strings for the translator, \nyou can say that you have a single piece of text that needs a singular \nand plural translation. The following two examples both output the same \nresult to the user:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1234567<\/td><td><code>&lt;?php<\/code><code>if<\/code><code>(get_comments_number() == 1) {<\/code><code>_e( <\/code><code>'There is a comment'<\/code> <code>);<\/code><code>} <\/code><code>else<\/code> <code>{<\/code><code>_e( <\/code><code>'There are comments'<\/code> <code>);<\/code><code>}<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>123<\/td><td><code>&lt;?php<\/code><code>echo<\/code> <code>_n( <\/code><code>'There is a comment'<\/code> <code>, <\/code><code>'There are comments'<\/code> <code>, get_comments_number() );<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p><code>_n()<\/code> <em>requires<\/em> three arguments. The first is the\n singular version of the text, the second is the plural, and the third \nis the number that it&#8217;s referencing. In this case, <code>get_comments_number()<\/code> is finding how many comments are on a post and then <code>_n()<\/code> is choosing the appropriate text to use.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">_x() &amp; _ex()<\/h3>\n\n\n\n<p>Let&#8217;s say you&#8217;re translating a .pot file, and you come across an \nentry &#8220;scroll&#8221;. Are you going to interpret that as &#8220;a piece of rolled \npaper&#8221; or &#8220;pan up or down the website&#8221;? You could really do with some \ncontext to describe what you need to translate it to. These functions \ngive you that ability, by having a second required attribute which asks \nfor a short description to describe the phrase or word. Check the \nexample below:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1234<\/td><td><code>&lt;?php<\/code><code>echo<\/code> <code>_x( <\/code><code>'post link'<\/code> <code>, <\/code><code>'A link to the post'<\/code> <code>);<\/code><code>_ex( <\/code><code>'post link'<\/code> <code>, <\/code><code>'Submit a link'<\/code> <code>);<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>The example shows you the difference between <code>_x()<\/code> and <code>_ex()<\/code>. It is the same <code>e<\/code>, as with <code>_e<\/code>,\n to make the function echo the output instead of returning it. For both,\n our first parameter is our text that needs translating, and the second \nis a comment or note about the translation text to make it clear what is\n meant.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Advanced Techniques<\/h3>\n\n\n\n<p>Let&#8217;s say that you have a situation where the text you want to \ngenerate is composed of a text string with the result of a function or \nthe value of a variable put somewhere inside it. You might be tempted to\n right something like this:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1234<\/td><td><code>&lt;?php<\/code><code>$color<\/code> <code>= the_color();<\/code><code>_e( <\/code><code>\"You have chosen the $color theme\"<\/code> <code>);<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>When it comes to making your .pot file, POEdit will ignore this \nbecause it doesn&#8217;t want to use a variable in the middle of a sentence. \nThe reason being is that it will submit the string <code>You have chosen the $color theme<\/code>\n to the .pot file, but when it comes to searching for the translation \nwhen the script is executed, it will search for the string <code>You have chosen the blue theme<\/code> which it won&#8217;t find. So what if we do this instead:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1234<\/td><td><code>&lt;?php<\/code><code>$color<\/code> <code>= the_color();<\/code><code>echo<\/code> <code>__( <\/code><code>'You have chosen the '<\/code> <code>) . <\/code><code>$color<\/code> <code>. __( <\/code><code>' theme.'<\/code> <code>);<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>The script will now be able to retrieve the translations, but now \nit&#8217;s become too difficult to translate because the sentence has been \nbroken up. This sentence might not even be translatable in some \nlanguages that have largely different syntax, such as in German where \ntheir word for &#8220;chosen&#8221; would appear at the end of the sentence. You \nwould need to go through the trouble of explaining that these two \nseparate text strings are part of one, and that &#8220;theme&#8221; might not \ntranslate to &#8220;theme&#8221; at all.<\/p>\n\n\n\n<p>The solution is to use a single text string that has single-quotation-friendly syntax. This is where the <code>printf()<\/code> or <code>sprintf()<\/code> functions become useful. Let&#8217;s take a look at what our code needs to look like:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1234<\/td><td><code>&lt;?php<\/code><code>echo<\/code> <code>sprintf( __( <\/code><code>'You have chosen the %s theme.'<\/code> <code>) , the_color() );<\/code><code>printf( __( <\/code><code>'You have chosen the %s theme.'<\/code> <code>) , the_color() );<\/code><code>?&gt;<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Not only does this solve all our problem we had before, but it&#8217;s a lot tidier and only uses one line of code. The <code>printf()<\/code> or <code>sprintf()<\/code> functions&#8217; first arguments are the string to output which contains at least one placeholder, in this case <code>%s<\/code> <em>(which means &#8220;string&#8221;)<\/em>,\n and any other arguments are variables that are to be placed inside the \ninitial string. There are many different placeholders you can use inside\n your string and you can find a full list under <a href=\"http:\/\/www.php.net\/manual\/en\/function.sprintf.php\"><code>sprintf<\/code> in the PHP manual<\/a>. Note that the different between <code>printf()<\/code> and <code>sprintf()<\/code> is similar to <code>_e()<\/code> and <code>__()<\/code> respectively.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\nStep 2 Introducing POEdit<\/h2>\n\n\n\n<p>Now that you have successfully tagged all your text output on your \ntheme, you now need to collect this information into a .pot file. POEdit\n is a fantastic program that gives you the ability to create your .pot \nfile, and also provides an easy to use GUI that can be used to make your\n .po and, more importantly, your .mo files too.<\/p>\n\n\n\n<p>First, you will need to download POEdit, which you can find here for Windows, Mac and Linux:<br>\n<a href=\"http:\/\/www.poedit.net\/download.php\">http:\/\/www.poedit.net\/download.php<\/a><\/p>\n\n\n\n<p>Once POEdit is installed, you can create your .pot file. To do this, \ngo to File &gt; New Catalog. You will be presented with a dialog box \nwhere you need to enter some basic information. The essentials in the \n&#8220;Project Info&#8221; tab are the project name and your language\/country. You \nalso must enter the following in the &#8220;Plural Forms&#8221; box:<\/p>\n\n\n\n<p><strong>Plural Forms:<\/strong> <code>nplurals=2; plural=n != 1;<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/cdn.tutsplus.com\/wp\/uploads\/legacy\/234_Translating_Your_Theme\/poedit1.jpg\" alt=\"POEdit project info\"\/><\/figure>\n\n\n\n<p>On the &#8220;paths&#8221; tab, enter the path where the files can be found \nrelative to the save destination of this .pot file. For example, if you \nare putting the .pot file in the theme&#8217;s root folder, enter <code>.<\/code> <em>(period)<\/em>. If you want to place the .pot file in a &#8220;language&#8221; folder inside the theme root, enter <code>..<\/code> <em>(two periods)<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/cdn.tutsplus.com\/wp\/uploads\/legacy\/234_Translating_Your_Theme\/poedit2.jpg\" alt=\"POEdit path\"\/><\/figure>\n\n\n\n<p>Next, you need to tell POEdit which keywords to look for when scanning our files. Enter the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>__<\/li><li>_e<\/li><li>_n:1,2<\/li><li>_x:1,2c<\/li><li>_ex:1,2c<\/li><\/ul>\n\n\n\n<p>The <code>:1,2<\/code> extension tell POEdit that these keywords have \ntwo parts to them. By default, the second argument is the plural unless \nyou include the <code>c<\/code> which mean the second argument is a comment.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/cdn.tutsplus.com\/wp\/uploads\/legacy\/234_Translating_Your_Theme\/poedit3.jpg\" alt=\"POEdit keywords\"\/><\/figure>\n\n\n\n<p>You&#8217;re good to go! Click &#8220;OK&#8221; and choose a place to save your .pot \nfile. Remember that it has to relate to the path you defined earlier. \nPOEdit will now scan through your files and find all the occurrences of \nyour translation functions and save them without translations into your \n.pot file. If you only want to provide the bare minimum support for \ninternational translation you can ship your .pot file with your theme \nand stop here, however if you are able to translate your theme into \nanother language yourself, you can ship your theme with a premade \ntranslation as described in step 3.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\nStep 3 Translating and Making Your .po File<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/cdn.tutsplus.com\/wp\/uploads\/legacy\/234_Translating_Your_Theme\/poedit4.jpg\" alt=\"POEdit translating singular\"\/><\/figure>\n\n\n\n<ol class=\"wp-block-list\"><li>A list of all the text strings to be translated<\/li><li>The current string being translated<\/li><li>Your translation of the string<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/cdn.tutsplus.com\/wp\/uploads\/legacy\/234_Translating_Your_Theme\/poedit5.jpg\" alt=\"POEdit translating plural\"\/><\/figure>\n\n\n\n<ol class=\"wp-block-list\"><li>Singular and plural of current string<\/li><li>Tabs to switch between singular and plural of your translation<\/li><li>Your translation<\/li><\/ol>\n\n\n\n<p>Once you have translated all the strings in the .pot file, you can \nsave this as your .po file. Any string that you haven&#8217;t provided a \ntranslation for will show in the original language when someone views \nyour theme.<\/p>\n\n\n\n<p>The filename of your .po is crucial. Gettext uses the ISO 639 \nstandard for language abbreviations and ISO 3166 for locales. If your \ntranslation is written in American English for example, your file name \nwill look like <code>en-US.po<\/code>. Capitalization is also important here. For a full list of language and country codes, check out these two links:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"http:\/\/www.gnu.org\/software\/gettext\/manual\/gettext.html#Language-Codes\">Gettext language codes<\/a><\/li><li><a href=\"http:\/\/www.gnu.org\/software\/gettext\/manual\/gettext.html#Country-Codes\">Gettext country codes<\/a><\/li><\/ul>\n\n\n\n<p>Once you save, POEdit by default automatically creates a .mo file \nalongside your .po file. It is recommended you include all three of your\n translation files with your theme so that people can create their own \ntranslations and edit your existing translations easily.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\nStep 4 Setting Up WordPress<\/h2>\n\n\n\n<p>Let&#8217;s recap what you have done so far. You have told WordPress all \nthe text that you want to be translatable, and then you used POEdit to \ncollect each string and place them into a .pot file which can be \ntranslated into a .po and .mo file. These files are then included in the\n theme files. The final step is to zip your theme, install it and let \nWordPress know which language .mo file you want it to use. This is a \nvery straight forward procedure where you access your <code>wp-config.php<\/code> file found in your WordPress&#8217; root folder.<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>123456789<\/td><td><code>\/**<\/code><code>* WordPress Localized Language, defaults to English.<\/code><code>*<\/code><code>* Change this to localize WordPress. A corresponding MO file for the chosen<\/code><code>* language must be installed to wp-content\/languages. For example, install<\/code><code>* de_DE.mo to wp-content\/languages and set WPLANG to 'de_DE' to enable German<\/code><code>* language support.<\/code><code>*\/<\/code><code>define(<\/code><code>'WPLANG'<\/code><code>, <\/code><code>''<\/code><code>);<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Your file should already contain <code>define('WPLANG', '');<\/code> but if it does not, you can add it in. You simply need to add your language and locale code into the <code>define<\/code>. If you were to translate your theme into German, you would have this:<\/p>\n\n\n\n<table class=\"wp-block-table\"><tbody><tr><td>1<\/td><td><code>define(<\/code><code>'WPLANG'<\/code><code>, <\/code><code>'de_DE'<\/code><code>);<\/code><\/td><\/tr><\/tbody><\/table>\n\n\n\n<p>Your internationalization is complete! Remember to include your .pot \nfile with your theme, and if you were able to translate your theme to \nanother language, to include the .po and .mo files too.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s very easy to turn a blind eye to other languages when developing your WordPress theme, but this is a very bad habit and immediately turns away a whole market of WordPress users and potentially thousands of dollars in lost revenue. Out of the top 10 countries that search Google for &#8220;WordPress themes&#8221;, only one is native English speaking (the<\/p>\n<div class=\"clearfix\"><\/div>\n<div class=\"pull-left padding-top-25\"><a href=\"https:\/\/tamer-az.com\/?p=98\" class=\"btn btn-theme\">Continue reading<span class=\"screen-reader-text\"> &#8220;Translating Your Theme&#8221;<\/span> <i class=\"fa fa-fw fa-long-arrow-right\"><\/i> <\/a>  <\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-98","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/tamer-az.com\/index.php?rest_route=\/wp\/v2\/posts\/98","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tamer-az.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tamer-az.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tamer-az.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tamer-az.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=98"}],"version-history":[{"count":1,"href":"https:\/\/tamer-az.com\/index.php?rest_route=\/wp\/v2\/posts\/98\/revisions"}],"predecessor-version":[{"id":99,"href":"https:\/\/tamer-az.com\/index.php?rest_route=\/wp\/v2\/posts\/98\/revisions\/99"}],"wp:attachment":[{"href":"https:\/\/tamer-az.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=98"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tamer-az.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=98"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tamer-az.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=98"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}