{"id":233497,"date":"2023-02-15T16:44:00","date_gmt":"2023-02-15T13:44:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233497"},"modified":"2022-11-11T00:00:59","modified_gmt":"2022-11-10T21:00:59","slug":"criar-bloco-personalizado-do-gutenberg-parte-8-suporte-a-traducao","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/criar-bloco-personalizado-do-gutenberg-parte-8-suporte-a-traducao\/","title":{"rendered":"Criar bloco personalizado do Gutenberg &#8211; Parte 8: suporte \u00e0 tradu\u00e7\u00e3o"},"content":{"rendered":"\n<p>Nesta parte, vamos nos concentrar em como traduzir os textos e valores em nosso bloco Gutenberg personalizado. Usamos o WP-CLI para gerar os arquivos necess\u00e1rios para que o Gutenberg possa carregar nossas tradu\u00e7\u00f5es ao alternar o idioma do WordPress.<\/p>\n<p>Antes de prosseguir com isso, voc\u00ea precisa ter o <a href=\"https:\/\/wp-cli.org\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP CLI<\/a> (interface de linha de comando para WordPress) instalado. Se voc\u00ea n\u00e3o tiver, basta seguir o <a href=\"https:\/\/make.wordpress.org\/cli\/handbook\/installing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">guia no WordPress Handbook for CLI<\/a>.<\/p>\n<p>Para explicar resumidamente como traduzir para scripts Javascript (Gutenberg): WordPress requer <code>.mo<\/code>arquivos para tradu\u00e7\u00e3o de arquivos PHP, mas para Javascript o WordPress requer um <code>.json<\/code>arquivo. Cada arquivo Javascript precisa de um arquivo JSON para tradu\u00e7\u00e3o. O JSON deve ter um formato espec\u00edfico (o WP CLI o gerar\u00e1 para n\u00f3s) com nossas strings traduzidas. Precisamos de um arquivo JSON por idioma para o qual desejamos traduzir.<\/p>\n<p>Ent\u00e3o o que precisamos fazer \u00e9 primeiro adicionar as fun\u00e7\u00f5es gettext (<code>__()<\/code>, <code>_e()<\/code>etc.) em nossos arquivos Javascript e gerar um arquivo PO como de costume para nosso tema ou plugin. Como envolvemos os textos em nossos arquivos de script com, por exemplo <code>__()<\/code>,, o arquivo PO deve ser capaz de inclu\u00ed-los. Em seguida, fazemos a tradu\u00e7\u00e3o como de costume em nosso arquivo PO. E, finalmente, usamos WP CLI para extrair as strings necess\u00e1rias do arquivo PO e gerar arquivos JSON para todos os nossos arquivos Javascript.<\/p>\n<p>Lembre-se de que os arquivos \/ &#8211; do seu tema ou plug-in <code>.po<\/code>nunca <code>.mo<\/code>ter\u00e3o efeito em seus arquivos Javascript &#8211; mesmo que contenham strings traduzidas de nossos arquivos Javascript.<\/p>\n<h2>Implementando a tradu\u00e7\u00e3o em Javascript<\/h2>\n<p>O primeiro passo \u00e9 agrupar todos os textos em nosso arquivo Javascript dentro das fun\u00e7\u00f5es de tradu\u00e7\u00e3o. Se voc\u00ea j\u00e1 lidou com a tradu\u00e7\u00e3o para WordPress em PHP, provavelmente est\u00e1 muito familiarizado com as fun\u00e7\u00f5es <code>__()<\/code>, <code>_e()<\/code>, <code>esc_html__()<\/code>e assim por diante. O WordPress possui um pacote <code>wp.i18n<\/code>que cont\u00e9m essas fun\u00e7\u00f5es, que funcionam exatamente como no PHP.<\/p>\n<p>Assim como no PHP, voc\u00ea precisa fornecer um dom\u00ednio de dom\u00ednio de texto (nome\/identificador). Pode ser o que voc\u00ea quiser, mas mantenha-o curto, pois voc\u00ea provavelmente precisar\u00e1 digit\u00e1-lo com muita frequ\u00eancia. Para o meu tema, configurei meu textdomain com o dom\u00ednio <code>awhitepixel<\/code>. Ent\u00e3o dentro do PHP eu vou fazer <code>__('My string', 'awhitepixel')<\/code>para traduzir strings, e vai ser exatamente igual nos arquivos Javascript.<\/p>\n<p>Vamos come\u00e7ar a editar nosso arquivo Javascript. Primeiro precisamos desestruturar a fun\u00e7\u00e3o <code>__<\/code>and <code>_e<\/code>do <code>wp.i18n<\/code>pacote. Por causa da natureza do React, provavelmente voc\u00ea usar\u00e1 principalmente ou talvez apenas a <code>__<\/code>fun\u00e7\u00e3o.<\/p>\n<pre><code>const { __, _e } = wp.i18n;<\/code><\/pre>\n<p>E ent\u00e3o \u00e9 uma quest\u00e3o de encontrar todos os nossos textos codificados no arquivo Javascript e atualiz\u00e1-los. Tenha em mente que as fun\u00e7\u00f5es <code>__<\/code>e <code>_e<\/code>requerem contexto Javascript. Isso significa que quando digitamos strings como, por exemplo, valores de propriedades de objetos, usamos <code>__()<\/code>imediatamente, mas como valores para, por exemplo, props, precisamos envolver tudo dentro <code>{ }<\/code>para significar que este \u00e9 um c\u00f3digo Javascript.<\/p>\n<p>Por exemplo, nosso <code>registerBlockType<\/code>com suporte para tradu\u00e7\u00e3o ficar\u00e1 assim:<\/p>\n<pre><code>registerBlockType('awp\/firstblock', {\n    title: __('My first block', 'awhitepixel'), \n    category: 'common',\n    icon: 'smiley',\n    description: __('Learning in progress', 'awhitepixel'),\n    keywords: [__('example', 'awhitepixel'), __('test', 'awhitepixel')],\n    attributes: {\n        ...<\/code><\/pre>\n<p>E quanto aos adere\u00e7os, ou seja, em <code>InspectorControls<\/code>:<\/p>\n<pre><code>&lt;InspectorControls&gt;\n    &lt;PanelBody\n        title={__(\"Most awesome settings ever\", 'awhitepixel')}\n        initialOpen={true}\n    &gt;\n    ...\n        &lt;ToggleControl\n            label={__(\"Toggle me\", 'awhitepixel')}\n            checked={attributes.toggle}\n            onChange={(newval) =&gt; setAttributes({ toggle: newval })}\n        \/&gt;\n        ...<\/code><\/pre>\n<p>Enrole todos os textos para os quais voc\u00ea deseja apoiar a tradu\u00e7\u00e3o em <code>__()<\/code>e <code>_e()<\/code>. Se voc\u00ea seguiu este tutorial passo a passo, n\u00e3o deve ter nenhum caso em que precise usar <code>_e()<\/code>. Quando terminar, recompile o Javascript e nos afastaremos do Javascript.<\/p>\n<h2>Configurando arquivos po e\/ou pot<\/h2>\n<p>Esta etapa varia um pouco dependendo do que voc\u00ea j\u00e1 fez e configurou para o seu tema ou plugin. Voc\u00ea pode estar escrevendo seus scripts Gutenberg em um plugin novo e vazio que n\u00e3o foi configurado para tradu\u00e7\u00e3o PHP, ou dentro de um tema que j\u00e1 tenha um dom\u00ednio de texto registrado. Voc\u00ea pode ter arquivos PO (e MO) prontos ou pode ter apenas um arquivo POT. Vou tentar o meu melhor para cobrir todas as bases.<\/p>\n<h3>Meu tema ou plugin j\u00e1 tem um arquivo po(t)<\/h3>\n<p>Se voc\u00ea j\u00e1 tem um arquivo PO ou POT em seu projeto, provavelmente tamb\u00e9m tem a fun\u00e7\u00e3o PHP <code>load_theme_textdomain()<\/code>, <code>load_child_theme_textdomain()<\/code>ou <code>load_plugin_textdomain()<\/code>em algum lugar em seu c\u00f3digo. Certifique-se de que o dom\u00ednio registrado \u00e9 o mesmo que voc\u00ea usou em seus arquivos Javascript.<\/p>\n<p>Tudo o que voc\u00ea precisa fazer \u00e9 carregar o arquivo PO para o idioma que deseja traduzir (ou gerar um a partir do arquivo POT) em, por exemplo <a href=\"https:\/\/poedit.net\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">, PoEdit<\/a>. Clique em &quot;Atualizar do c\u00f3digo&quot; (ou similar em outros programas) para que o programa possa verificar todos os arquivos do projeto (incluindo nossos arquivos Javascript atualizados recentemente) e atualizar o conjunto de strings para tradu\u00e7\u00e3o. As strings em nosso arquivo Javascript devem aparecer. Em seguida, voc\u00ea s\u00f3 precisa traduzi-los normalmente e salvar.<\/p>\n<p>PS: Se voc\u00ea n\u00e3o conseguir clicar em &#8220;Atualizar do c\u00f3digo&quot; ou redigitalizar os arquivos, o arquivo PO provavelmente n\u00e3o foi configurado corretamente. Procure dicas na pr\u00f3xima se\u00e7\u00e3o.<\/p>\n<h3>N\u00e3o tenho nenhum arquivo de tradu\u00e7\u00e3o<\/h3>\n<p>Se o seu tema ou projeto n\u00e3o foi configurado com tradu\u00e7\u00e3o, voc\u00ea precisa gerar um arquivo POT usando WP-CLI ou criar manualmente um arquivo PO.<\/p>\n<p>Eu tenho um guia completo sobre como criar um arquivo PO no meu <a href=\"https:\/\/awhitepixel.com\/blog\/wordpress-theme-tutorial-for-beginners-part-8-translation-of-your-theme\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Tutorial de Tema para Iniciantes \u2013 parte 8<\/a>. A postagem descreve como voc\u00ea pode criar o arquivo e configur\u00e1-lo corretamente para pesquisar seus arquivos de tema e as palavras-chave para pesquisar (<code>__<\/code>, <code>_e<\/code>, etc.).<\/p>\n<p>Se voc\u00ea preferir criar um arquivo POT, voc\u00ea pode usar o <a href=\"https:\/\/developer.wordpress.org\/cli\/commands\/i18n\/make-pot\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">comando wp i18n make-pot<\/a> no WP-CLI e, em seguida, criar um arquivo PO usando, por exemplo, PoEdit. Lembre-se de que voc\u00ea precisar\u00e1 gerar novamente o arquivo POT (e, em seguida, o arquivo PO) toda vez que atualizar qualquer string em seu c\u00f3digo.<\/p>\n<h3>Resultado final<\/h3>\n<p>O que voc\u00ea precisa \u00e9 de um arquivo PO que encontrou suas strings Javascript onde elas foram traduzidas. Eu recomendo colocar seus arquivos de tradu\u00e7\u00e3o em uma pasta separada em seu tema ou plugin. Quando come\u00e7armos a gerar arquivos JSON, teremos alguns arquivos para tradu\u00e7\u00e3o e ser\u00e1 bom mant\u00ea-los todos juntos em sua pr\u00f3pria pasta.<\/p>\n<p>Como ponto de refer\u00eancia, estou colocando todos os arquivos de tradu\u00e7\u00e3o no meu arquivo <code>theme\/assets\/lang\/<\/code>. Adicionei uma tradu\u00e7\u00e3o norueguesa para o meu tema, chamada <code>nb_NO.po<\/code>, que cont\u00e9m as strings traduzidas do nosso arquivo Javascript de bloco personalizado.<\/p>\n<h2>Gerando arquivos JSON a partir do arquivo po<\/h2>\n<p>O pr\u00f3ximo passo \u00e9 usar o WP-CLI para gerar arquivos JSON do nosso arquivo po. Para isso usamos o comando <a href=\"https:\/\/developer.wordpress.org\/cli\/commands\/i18n\/make-json\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wp i18n make-json<\/a>.<\/p>\n<p>Esteja ciente de que, por padr\u00e3o, este comando retirar\u00e1 as strings traduzidas do seu arquivo PO para uso na gera\u00e7\u00e3o do arquivo JSON. Isso pode ser complicado no meio do desenvolvimento do seu tema ou plugin. Porque quando voc\u00ea adiciona novas strings ou ajusta strings, voc\u00ea ter\u00e1 que redigitalizar os arquivos e traduzir todas as strings novamente (e novamente e novamente). Felizmente, h\u00e1 um sinalizador no comando para evitar isso.<\/p>\n<p>Vamos come\u00e7ar! No seu terminal, navegue at\u00e9 o diret\u00f3rio de idioma do seu projeto. Execute o seguinte comando e consulte o seu arquivo po (como mencionado, eu tenho um <code>nb_NO.po<\/code>arquivo pronto).<\/p>\n<pre><code>wp i18n make-json nb_NO.po --no-purge<\/code><\/pre>\n<p>Se voc\u00ea n\u00e3o tiver nenhum problema em remover as strings traduzidas do seu arquivo PO (por exemplo, se estiver fazendo sua compila\u00e7\u00e3o final), pule o <code>--no-purge<\/code>sinalizador.<\/p>\n<p>O terminal deve solicitar &#8220;Sucesso&#8221; e indicar quantos arquivos JSON foram criados. Se voc\u00ea vir que ele gerou dois arquivos JSON, \u00e9 porque ele leu nosso arquivo Javascript de c\u00f3digo-fonte e o arquivo de compila\u00e7\u00e3o e gerou um para cada um. Se voc\u00ea tiver mais arquivos Javascript em seu projeto, ter\u00e1 ainda mais arquivos JSON.<\/p>\n<p>No momento em que escrevo isso (WordPress v 5.3.2 e WP-CLI vers\u00e3o 2.4.0), os arquivos JSON s\u00e3o gerados com o c\u00f3digo do idioma e um hash \u2013 uma string enigm\u00e1tica como nomes de arquivos. Precisamos encontrar o caminho certo e renome\u00e1-lo.<\/p>\n<h2>Renomeando o arquivo JSON e carregando-o em PHP<\/h2>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153240-61e50a824a365.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153240-61e50a824a365.png\" alt=\"Criar bloco personalizado do Gutenberg - Parte 8: suporte \u00e0 tradu\u00e7\u00e3o\" ><\/a><\/p>\n<p>Sua pasta de idioma provavelmente se parece com isso:<\/p>\n<p>Lembre-se de que o comando gerou um arquivo JSON por arquivo Javascript \u2013 e como na verdade temos dois arquivos para nosso bloco personalizado (o c\u00f3digo-fonte e o build), ele gerou dois arquivos. Se o seu c\u00f3digo Javascript for dividido em v\u00e1rios arquivos, cada um receber\u00e1 dois de seus pr\u00f3prios arquivos JSON.<\/p>\n<p>Se voc\u00ea est\u00e1 sentado com apenas dois arquivos JSON (porque nenhum outro arquivo Javascript foi encontrado), voc\u00ea pode excluir um deles agora. Se voc\u00ea tiver mais de dois, precisar\u00e1 abrir os arquivos JSON e ver para qual arquivo eles s\u00e3o. Os arquivos JSON cont\u00eam uma propriedade &#8221; <code>source<\/code>&#8221; que informa para qual arquivo Javascript este arquivo JSON se destina. Use isso para descobrir qual arquivo JSON manter. Eu recomendo encontrar o arquivo de compila\u00e7\u00e3o final (em oposi\u00e7\u00e3o aos arquivos dev), pois ele deve conter todas as strings de todos os arquivos.<\/p>\n<p>Quando voc\u00ea encontrar o correto, precisamos renome\u00e1-lo. Precisamos renome\u00e1-lo para seguir este padr\u00e3o:<\/p>\n<p><code>[textdomain]-[language code]-[script handle].json<\/code><\/p>\n<p>Use o textdomain que voc\u00ea usou em todos os lugares (por exemplo <code>__('My string', 'awhitepixel')<\/code>, ), adicione um tra\u00e7o e o c\u00f3digo do idioma. Em seguida, forne\u00e7a um tra\u00e7o e o identificador de script que voc\u00ea usou para registrar seu arquivo Javascript do Gutenberg (<code>wp_register_script()<\/code>). Como refer\u00eancia, meu textdomain \u00e9 <code>awhitepixel<\/code>, meu c\u00f3digo de idioma \u00e9 <code>nb_NO<\/code>, e meu identificador de script para o script Gutenberg \u00e9 <code>awp-myfirstblock-js<\/code>. Ent\u00e3o eu renomeio o arquivo JSON para:<\/p>\n<p><code>awhitepixel-nb_NO-awp-myfirstblock-js.json<\/code><\/p>\n<h3>Diga ao WordPress para carregar nosso JSON<\/h3>\n<p>Tudo o que resta agora \u00e9 a etapa final \u2013 dizer ao WordPress para carregar nosso arquivo JSON. Precisamos usar a fun\u00e7\u00e3o <code>[wp_set_script_translations](https:\/\/developer.wordpress.org\/reference\/functions\/wp_set_script_translations\/)()<\/code>. Esta \u00e9 uma fun\u00e7\u00e3o muito nova do WordPress, ent\u00e3o eu recomendo envolv\u00ea-la dentro de um arquivo <code>function_exists()<\/code>. Aceita tr\u00eas par\u00e2metros; o identificador de script para nosso bloco, o textdomain e o caminho para nossa pasta de tradu\u00e7\u00e3o (observa\u00e7\u00e3o: o caminho, n\u00e3o o URL).<\/p>\n<p>Dentro da nossa fun\u00e7\u00e3o hooked to <code>init<\/code>, onde registramos nosso script de bloco e chamamos <code>register_block_type<\/code>, tamb\u00e9m podemos chamar essa nova fun\u00e7\u00e3o para carregar nosso arquivo de tradu\u00e7\u00e3o JSON. PS: Tenha em mente que o gancho <code>enqueue_block_assets<\/code>n\u00e3o funcionar\u00e1 para registrar tradu\u00e7\u00f5es.<\/p>\n<pre><code>add_action('init', function() {\n    wp_register_script('awp-myfirstblock-js', ....);\n    register_block_type('awp\/firstblock', ....\n\u00a0\n    if (function_exists('wp_set_script_translations')) {\n        wp_set_script_translations('awp-myfirstblock-js', 'awhitepixel', get_template_directory(). '\/assets\/lang');\n    }\n});<\/code><\/pre>\n<p>E isso \u00e9 tudo! Seu bloco agora deve ser traduzido. Mude o idioma do WordPress para o idioma para o qual voc\u00ea traduziu e verifique por si mesmo. Quando mudo meu idioma do WordPress para noruegu\u00eas e adiciono meu bloco, o nome e tudo dentro dele s\u00e3o traduzidos:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153240-61e50a83bedae.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153240-61e50a83bedae.png\" alt=\"Criar bloco personalizado do Gutenberg - Parte 8: suporte \u00e0 tradu\u00e7\u00e3o\" ><\/a><\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Esta li\u00e7\u00e3o se concentra em como apoiar a tradu\u00e7\u00e3o dos textos em nosso bloco Gutenberg. Usamos o WP-CLI para gerar os arquivos JSON necess\u00e1rios para o WordPress.<\/p>\n","protected":false},"author":1,"featured_media":153241,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,898,941,941,1110,806,806,816,816,846,846,867,867],"tags":[1170],"class_list":["post-233497","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-gutenberg-8","category-n-a","category-php-8","category-plug-ins","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233497","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=233497"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233497\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/153241"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=233497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=233497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=233497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}