 Thank you. Also, thanks for having me for the first ever WordCamp Nordic. It's an honor to speak today in front of so many people. I'm really surprised. Thank you for coming. Even if it's that early, at least for me. I'm not really that morning guy, but yeah. Today I would like to talk a little bit about my favorite topic in Wordpress because it's one of my topics because I'm from Germany. And so my native language isn't English, which is actually the main language of Wordpress, the Wordpress project. And yeah, so I would like to talk a little bit about this topic today. Yeah, I'm Dominik Schilling. I'm a Wordpress core developer since six years and also heavily involved in the translation projects, which is not really new, as you will see a little bit later. And because of this, I have a little subtitle for today's talk, which is a history of 7.7 million minutes in 30 minutes. So yeah, let's check if we can do this today. Just a little note because my topic is actually the state of Wordpress internationalization in 2019 because this world is not really that easy to move down. There's a short form which is called IATN. So please excuse if I continue to use the IATN short form for the next few slides. So just to let you know that this is just a short form of internationalization. So that was the last one. So because, oh, let's say why are there so many minutes since the first slide, which I mentioned there, because the first talk, actually the first mention of IATN was in a blog post on post.org slash news, which was at April 2004. And that was really the first mention of IATN and also localization at 10N. And maybe, you know, which version was released in 2004. Any idea? Come on. No. No, but close. Yes. It was 1.2. And this was the first ever released, which got the first localization of Wordpress and Unicode support. So that's why I have chosen the subtitle, which is 7.7 million minutes, which is actually the date, actually the time frame between 2004 and today. And, yeah, I choose the first two slides because every time I'm talking about IATN or translation, it's really surprising that I still have to, or that we still have to educate some developers to let them know that there is another language than English. So since 2004, the base API or the localization support was there, but a lot of has changed to make this process of translating and to make your plug-in theme and even core much easier to translateable and also for translators because there was, at this time, no really good platform to support, I don't know, like many more languages which we today have. So let's start at the beginning. You may download a Wordpress.zip file and once you open it, you see a lot of PHP files and if you open one of them, maybe you see that there's everything in English. So if you have installed your Wordpress the first time, you see everything in English, maybe, but as we all know, there isn't only English. So let's take a look at the word dashboard, which is here or here. And in this slide, you can see all the translations which we are currently having for the word dashboard. So maybe you see also the translation in your language and the question is now, how do we put all these translations of the string dashboard back to Wordpress? Or actually, how do we make Wordpress ready to make this string dashboard translatable? The first part is the so-called GetTex functions. It's a PHP library, but in Wordpress we actually have our own library on top of, actually not on top of GetTex, but it's a similar API who provides a framework to be able to make strings like dashboard translatable. In this case, it's the underscore underscore function, which simply expects the string. And these functions are also wrapped in a framework which is called PoMo. Po and Mo are two file types, which we will see a little bit later on how they are looking and what you can do with them. And now we have the string in the PHP file, but we still can't translate them because you don't want to change any core files. For example, you wouldn't really add your translation into this file. And there was a tool which was called MakePot PHP. It's a 10-year old script, which was also developed at the time of probably 2004, which simply extracts all the translatable strings from core into a file named Pot. This file is no longer in use, but we have a super awesome alternative now, which is part of the official project called WPCI. Some of you may know it's a CLE interface for your WordPress, which you can install on your server, and then you can type into your terminal some play a little bit of hacker to get all your data or create posts and so on. And since version 2.0, we also have the new command IATN MakePot, which is the placement of the previous MakePot PHP file. And it does the same as the script, just better. Because there were some bugs and also some compatibility issues with PHP versions. And it also extracts all the strings from core, also our special syntax for translator comments. So if a string isn't really clear enough, you can add a comment to the string. And this MakePot command also extracts the translator comments. And MakePot, because Pot is actually a file type and which looks like this. It's a simple text file, which has the reference to the string. In this case, it's wp-admin-index-php-line-31. You have the message ID, which is the English original string, and the message string is in this case empty because it's a template. As you can see, it's a portable object template, which you can use to create other files. This one is a simple example for a single string, but we also have, for example, the string in comments, which is actually based on the number of comments. So we have the actually, I have made a typo here. It's not with the S, just comment, and the plural is comments. And also we have, in this case, two matches strings 0 and 1, depending on the plural form of the language. So now we have the POP file, which is the simple text file, which you can translate. For example, maybe you have heard of PoEdit or TransEffects, which is online service, but today I'm talking about CloudPress. CloudPress is a WordPress plugin, which you can use to create your own collaboration and web-based software translation tool. It's really old, just like WordPress. I think the first comment was done in 2009, and it's also an official sister project of WordPress, just like BVPress or BodyPress. At this time, there was also a library called BackPress, which was kind of difficult. It was more or less a library of WordPress, but we took the opportunity to make it a WordPress plugin, just like BVPress and BodyPress in 2016. So you actually can install your own CloudPress, because it's a simple plugin, which you can install on every WordPress site. The development happens on GitHub, so if you are interested to be one of our contributors, you're always looking for more, because we have a lot of ideas, just actually, I don't know, two or three developers. So if you are interested, please join us at GitHub to help make CloudPress a little bit more better. But now, I don't want you to install all your own CloudPress install, because we have one huge install for web-based.org, which you will find on translate.webs.org. It's maintained by the official WordPress meta team, and we use it to give really translators a central platform to submit their translation for core themes, plugins, or also our web apps, and also some meta projects, or even WordCamp sites. And really, everyone with the WordPress.org account can submit their translation. In this case, it's a simple example where you can see what you can translate everything, WordPress themes, plugins, meta, and the app. And in this case, you can also translate, I think, since 4.1 is actually, I think, the first version which you can translate on translate.webs.org. And the profile just gets imported into this platform, so you don't have to do this. It's done on Core-on-Job, which runs every hour, which simply imports a text file with the default CloudPress CD importer. And if you are on Slack, you will find a few Slack applications in the Polyclouds channel, which are looking like this. For example, if there's a new swing, you get the information and you can write, jump into translate.webs.org and, yeah, translate this swing. Let's get back to our dashboard swing. In this case, it's the finished version of the translation project. Here you can see the original dashboard swing. You can also see the reference here. And this one is the translation. In this case, maybe it's important to know that everyone can submit translations, but they are not directly approved because we have some special rules in the Polyclouds team. In this case, we have the translators and also the editors. And the editors validate your submission. And if the translation is good enough, they approve your translation, or if not, they can reject and, yeah, and you can provide a better translation. Now we have the translation. We have the port file. But how do we get them back to WordPress? In this case, we have something called language packs, which is a thing since, I don't know, 4.0, I think. And it exports every translation which you have previously submitted in a zip file. It's updated every 12 to 24 hours. And it contains these files. We have six to eight files. It depends on the language, for example, all the English variants. They don't have the continent entities files because it's more or less the same. They don't really provide a translation for city names. And for performance reasons, we have split all the translations into four projects. The normal one is for all the frontend strings, admin for the admin strings. Then we also have for multi-sites, admin network part, and, of course, continent cities, which only lose for the settings to set your time zone. The PO file is actually a text file again, which is called portal object. So no template anymore. We finally have our message string for the dashboard string. We also have some metadata. In this case, it's a file for Spanish and Spanish translation of dashboard. So this file, you can actually read, but WordPress doesn't read this file. It reads, of course, a file which is like this with a lot of numbers. It's the MO file, which is called machine object. And this one is bytecode and also used by all the get text functions. To get the language facts actually to a WordPress back, we have the WordPress translation API, which is an official API of WordPress.org, which just requests, depending on your language set in WordPress, all the plugins, themes, and core, and it returns you all the language packs. For example, the response looks a little bit like this. You have the package URL to the zip file, also the version of the file, and the date, and of course the language. And if you download a newer WordPress zip file, you probably don't even start with English, because since 4.0, we have this awesome language user, which allows you doing the installation to select your language already. So instead of first installing your WordPress into English, you can directly select your language, and you are ready to go to use WordPress in your language. So language packs are really the best thing, I think, in the last 4 years, which happened to WordPress, because they are so easy, so automated that you don't really have to worry about languages anymore. The languages are stored in the W Content Languages directory, they are automatically updated, they are installed on the fly, for example, if you switch a language, or even if you're installing a new plugin, theme, and so on, they're installed right in the background, you don't have to worry about it, and by doing other updates, for example, if you update a plugin, I don't know, Hello Dolly, and there's an update for another plugin, you also get the languages, the translations of other plugins, so in this case you also have to worry about this. And this is also one of the reasons why you should really never ever disable auto updates. Now we have the files back on our WordPress install, there's now a thing called Translation API, which is for core, this function load default text domain, which depending on your admin screen loads, either the front end strings, or the admin strings, or the admin network strings. And if you go even further, we are back to our GetTex function, this underscore underscore function now search for the string in the previous loaded translations to load default text domain, and we finally get back to the translation of dashboard in our UI. Oh, I did this much something, I think. What could it be? Yeah, well, we have 2019, and in the end of 2018 there was something new to WordPress, and of course it was the blog editor, and JavaScript. And yeah, JavaScript is not PHP, you can't really use all the PHP functionality which we had for the last decade, so we had to define something new. And luckily the Gutenberg team came up with an API, which is similar to the GetTex API, which is part of the WPIATN namespace. It's also a JavaScript package, which you can download, so you can even use it without WordPress. And for example, if you open the, there's a component called .tip, which has this string, and as you can see, it's the same as the underscore underscore dashboard string in PHP. Just in this case, it's a short form, or actually it's WPIATN dot underscore underscore, or if you import, depending on your JavaScript skills, and what do you want to have, you can import it like this, or you reference it like this. And the good thing, we only had to change the API to make strings translateable, so we have a new API WP.IATN, but for extracting the strings, we still can rely on WP CLI, because it even parses JavaScript files, and that was also one of the reasons why we had to change the script pattern. And let's get back to language packs. I actually lied, because there are 11 more files. In this case, we have JSON files. There are 11 files, because there are actually 11 components which you can translate, and each component has its own translation file, and in case you're wondering what this hash is, it's just the MD5 string of the path of the script. And it's, of course, a text file in the jet1.x format, which looks like this. It's simply JSON with our translations and strings. And actually, we had one more thing to change. We also have the WP set script function, which lets WordPress now to load the JSON file for your script. You just have to pass the script handle, so if you do WP underscore register script, for example, you also have to add the dependency WP.IATN, and finally also WP set script translation to register the handle and also the text domain actually, not the script, right? So this was mostly about core, so the question might be if language packs are also a thing for products and themes, and the answer is, of course, yes. There are just a few requirements to make this work properly. The first one is that you have a proper text domain registration, but there's a special case if you are supporting only 4.6 and up. Of course, in this case, you only have to do this part. You don't have to call load plugin or load team text domain. You don't have to define text domain domain and so on. Just say that your plugin at least requires 4.6 or even better do it 5.1. And of course, the plugin must be hosted in the official web directory, and that's all what you have to do to make translations work via translate.webis.org and also to get the automated language packs. If you want to know a little bit more about this, you can check out the handbook. There are also another section which is called meta language packs which you can follow to get a little bit input about your plugin. For example, if it's not compatible, you get a message and can fix your plugin or theme. And if you want to know more about language packs, you can even see what languages are available for your plugin or theme. So what about private projects? Because as you have heard before, the requirement is that you are hosting your plugin and theme in the official plugin directory or theme directory. But since I'm working for a Swiss-based company, we are also dealing a lot with translations to improve our internal workflow, which means we do see a repetitive task or even stop sending any Excel files between the customer and us. We have introduced something called Tradutorial. It's basically like this. We have four public plugins and themes which are in the directory, the web.org translation API. For our client projects, we have the Tradutorial setup, which allows our customer to directly translate the swings. And both APIs just give back a language pack fully automated to each website which is using the plugin or theme. So it basically allows you to set up your own translate.web.org. And the good thing, everything, even our tools is open source. So you only need WordPress, you only need WordPress, you need WPCLi and Tradutorial and also Tradutorial registry to allow WordPress to download the zip file. As mentioned before, everything runs automatically. It has a direct integration with GitHub via webhooks. We are also working on GitLab and Bitbucket. It uses WPCLi to import the swings, generates the zip files and has a direct integration into the WordPress translation API with all the benefits which I have mentioned before. So in case you want to have your own install looks, for example, this is our platform which we also have a little bit customized and you see it's the same API as from webhooks.org and if you're interested, you can see the project on GitHub. I want to quickly talk about some more features. First one is user locals, which is a thing since 4.7. It basically allows you to set for each user your own locale. So that means that your site no longer has only one language or one local, every user can have their own language and local. For this, we also have the locale switching, which allows you, for example, if you are sending a notification to many users, you can switch to the language of the user and send the notification in their language. So it's similar to if you know a multi-site switch to block, you can also switch to locale. And also an interesting project is called preferred languages, which is not yet part of core. It's a feature project to allow the user to select a stack of languages, for example, for our clients, we also have, we always have this kind of stack, for example, we first use the Swiss German language. If there is a, if a plugin has no translation in Swiss German, we are falling back to the formal version of German. And if this one even doesn't exist, we fall back to German. So if you're interested, it's also an open source plugin, which is quite ready even for the new JavaScript translation API. So if you want to have fallbacks for your languages, I highly recommend this plugin. So let's quickly go to some stats, as I usually do in my slides, even if I have time over. So at the moment, I have, we have 168 locals. Our team has 2,500 editors and 74,000 translators, which sounds like 140 projects, which means core, meta, plugin, cm, and so on. This is a little bit about 2,000 cent where we only have 223,000 swings. In this case, in between 2,040 and 15, we allowed plugins and themes to use our platform. And so at the moment, we have nearly 47 million translations, which is a huge database, which we want to use much more, for example, for, I don't know, translation memory and so on. We have a lot of language packs with a lot of downloads. And this also helped us to have actually reached 24.7 percent, which are not using the English American local as default. The future, we want to improve, of course, for example, is an improved editor UI, also translation memory, or copy from other languages, or even rejecting this feedback, or actually giving feedback to a swing. And for this, we are trying to have a new editor UI. In this case, you are the first one to see this, which kind of looks like this, and here you can even see we have some sort of translation memory. This is also planned for the next few weeks. Language packs, you want to make them faster, you want to make them less complex. And for core, of course, performs improvements every time a topic. But you also may have heard of Gutenberg files 4, which is, or which should introduce an official way to support multilingual sites. So that's something which has met, mentioned in his last state of word. So that was it. Sorry for a little bit more, but yeah. Thank you. Thank you, Dominik. Yeah, I'm sure a lot of us have used the localized version of WordPress, but it's easy to forget how much thought and where it goes behind it. So thank you. Thank you for presenting that to us. So right now, we have a still bit of time left for questions. So if you have a question, please raise your hand and we'll get a microphone for you. Okay, over there. The mig runner is really slow. Hi, my name is Daniel. I'm a long time PTE for finish, for the finish translation. I was very interested in the new features you just very briefly showed us. So I was wondering if you could perhaps just go back a few slides and give us like a maybe just a very short introduction of what how that translation memory will work and how giving feedback will work. It's kind of a little bit secret project. So I just want to tease it a little bit. But of course, I actually don't have a screen of the actual UI. But for example, in WordPress, you also have a new feature. It's called notes or comments. And our current UI doesn't really allow to add more items. So the first step is to redesign the editor which we have. And in this case, that's the current version of the translation memory, which is actually using or it's done with the help of web.com, which have their own translation memory, which we will be able to use also for .org. And it just checked the source string, looked for any related translations. And in this case, but in this case, you have 100%, which is a direct match. Or there's even similar string or a similar original string. In this case, it's 87%. And if you think it's a good enough translation for the string, you just can click copy this and it will insert into the or it will be used as a translation. Is a memory, is it like per project or per local or local or It's, I'm not really sure. I think it's per local. So it's, we use every project and yeah. So someone's translated something in Finnish in core and then someone's translating like WooCommerce. Yeah. So we use the same. Yes. Okay. Thank you. Yeah. There's a question. I'm just wondering about the cost of loading translations in WordPress and after somewhere you can cache that or something like that. If you're running, for example, a large site with lots of plugins and stuff, what the sort of overhead is of loading a locale, which is not the default and if there's some way to make it faster. So the question is about the performance of loading the Yes. Okay. Yeah. There is quite an overhead which is mostly caused by not using the native get X API because we have our own pepper and our own function. So there is indeed small, I would say performance decrease, but we're also working on making this faster, for example, by lazy loading the translation. That's also a ticket with the page. We probably have to take another look at. So we are really trying to make this as performant as possible, but there are also plugins who try to cache the translation, for example, in the object cache or in the database even, which I wouldn't really recommend. But yeah, I hope that answers your question. Is it enough of an issue to warrant something like, is it something that you feel should be an issue for core to address, for example? I mean, it is an issue. Yes, of course. I mean, we have the tickets. We are working on making it better. So, yeah. But it's not that really that you would say it's that bad to have another look at in English. Yeah, we have a few questions here, I guess. Yep. Over there. Is there coordination between translation and themes team in order, for example, to give support to language like Hebrew, who are written right to left? I'm not sure. I get the question. For themes, it's important that things like text lengths and so on. Is there any coordination or test practice? So I can trust that every theme that WordPress provides, like 2019 or 2018, works with right to left languages? I can say that officially default themes, of course, they support right to left languages. I'm not really sure if there's any requirement to have. I'm not really sure. I'm not really into the theme reviewed theme. So maybe no, no. Okay. So if somebody know if there's a requirement to have right to left support for your themes, anyone? No? So I would suggest to really ask the team directly on Slack or so. Or I can look it up and tell you later. Okay. Okay. I think we have time for one more question. I think there was at least one over there. Hello. I wonder how I can have a dashboard in one language and front end in another one by default, not to set up another language to the person. You can actually, because it's the same functionality I have mentioned, switch to local, which you can use, for example, for this, but the user language is all only used for the admin. So the site, the language of the font that is still the same which you have selected in the site. So if a user selected, for example, German, but your site is said to Spanish, the font that is still in Spanish, not in German. It will be not for front end users. Right. It's only for the admin. Okay. Thank you. Okay. Okay. I think we're out of time for questions. I know some of you still had some, but maybe you can go look Dominic up during the break. So he'll maybe hear. So let's give one more time applause for Dominic. Thank you. So next up, we already have our first break. And if you, when you signed up, you said that you'd like a scarf. They're now giving out those scarves or the swag stuff in the main lobby where you did the registration. So go ahead and get your swag. And the program will be back 20 past 10.