{"id":233456,"date":"2023-02-15T17:10:00","date_gmt":"2023-02-15T14:10:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233456"},"modified":"2022-11-10T23:47:45","modified_gmt":"2022-11-10T20:47:45","slug":"crear-bloque-de-gutenberg-personalizado-parte-8-soporte-de-traduccion","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/crear-bloque-de-gutenberg-personalizado-parte-8-soporte-de-traduccion\/","title":{"rendered":"Crear bloque de Gutenberg personalizado &#8211; Parte 8: Soporte de traducci\u00f3n"},"content":{"rendered":"\n<p>En esta parte nos centraremos en c\u00f3mo traducir los textos y valores en nuestro bloque de Gutenberg personalizado. Usamos WP-CLI para generar los archivos necesarios para que Gutenberg pueda cargar nuestras traducciones al cambiar el idioma de WordPress.<\/p>\n<p>Antes de continuar con esto, debe tener instalado <a href=\"https:\/\/wp-cli.org\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP CLI<\/a> (interfaz de l\u00ednea de comandos para WordPress). Si no lo tiene, simplemente siga la <a href=\"https:\/\/make.wordpress.org\/cli\/handbook\/installing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">gu\u00eda en el Manual de WordPress para CLI<\/a>.<\/p>\n<p>Para explicar brevemente c\u00f3mo traducir scripts de Javascript (Gutenberg): WordPress requiere <code>.mo<\/code>archivos para la traducci\u00f3n de archivos PHP, pero para Javascript WordPress requiere un <code>.json<\/code>archivo. Cada archivo Javascript necesita un archivo JSON para la traducci\u00f3n. El JSON debe tener un formato espec\u00edfico (WP CLI lo generar\u00e1 por nosotros) con nuestras cadenas traducidas. Necesitamos un archivo JSON por idioma al que deseamos traducir.<\/p>\n<p>Entonces, lo que debemos hacer primero es agregar las funciones gettext (<code>__()<\/code>, <code>_e()<\/code>etc.) en nuestros archivos Javascript y generar un archivo PO como de costumbre para nuestro tema o complemento. Debido a que hemos envuelto los textos en nuestros archivos de script con, por ejemplo <code>__()<\/code>, el archivo PO deber\u00eda poder incluirlos. Luego hacemos la traducci\u00f3n como de costumbre en nuestro archivo PO. Y finalmente usamos WP CLI para extraer las cadenas necesarias del archivo PO y generar archivos JSON para todos nuestros archivos Javascript.<\/p>\n<p>Tenga en cuenta que los archivos \/ de su tema o complemento <code>.po<\/code>nunca <code>.mo<\/code>tendr\u00e1n un efecto en sus archivos Javascript, aunque contengan cadenas traducidas de nuestros archivos Javascript.<\/p>\n<h2>Implementando la traducci\u00f3n en Javascript<\/h2>\n<p>El primer paso es envolver todos los textos en nuestro archivo Javascript dentro de las funciones de traducci\u00f3n. Si ha manejado la traducci\u00f3n de WordPress en PHP, probablemente est\u00e9 muy familiarizado con las funciones <code>__()<\/code>, <code>_e()<\/code>, <code>esc_html__()<\/code>etc. WordPress tiene un paquete <code>wp.i18n<\/code>que contiene estas funciones, que funcionan exactamente como en PHP.<\/p>\n<p>Al igual que con PHP, debe proporcionar un dominio de dominio de texto (nombre\/identificador). Puede ser lo que quieras, pero s\u00e9 breve, ya que es probable que tengas que escribirlo muy a menudo. Para mi tema, configur\u00e9 mi dominio de texto con el dominio <code>awhitepixel<\/code>. Entonces, dentro de PHP, lo har\u00e9 <code>__('My string', 'awhitepixel')<\/code>para traducir cadenas, y ser\u00e1 exactamente lo mismo en los archivos Javascript.<\/p>\n<p>Comencemos a editar nuestro archivo Javascript. Primero necesitamos desestructurar la funci\u00f3n <code>__<\/code>y <code>_e<\/code>del <code>wp.i18n<\/code>paquete. Debido a la naturaleza de React, lo m\u00e1s probable es que use la <code>__<\/code>funci\u00f3n principalmente o quiz\u00e1s solo.<\/p>\n<pre><code>const { __, _e } = wp.i18n;<\/code><\/pre>\n<p>Y luego es cuesti\u00f3n de encontrar todos nuestros textos codificados en el archivo Javascript y actualizarlos. Tenga en cuenta que las funciones <code>__<\/code>y <code>_e<\/code>requieren el contexto de Javascript. Eso significa que cuando escribimos cadenas como, por ejemplo, valores de propiedades de objetos, los usamos <code>__()<\/code>de inmediato, pero como valores para, por ejemplo, accesorios, necesitamos envolver todo dentro <code>{ }<\/code>para indicar que se trata de c\u00f3digo Javascript.<\/p>\n<p>Por ejemplo, nuestro <code>registerBlockType<\/code>soporte para traducci\u00f3n se ver\u00e1 as\u00ed:<\/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>Y en cuanto a accesorios, es decir, en <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>Envuelva todos los textos para los que desee admitir la traducci\u00f3n en <code>__()<\/code>y <code>_e()<\/code>. Si ha seguido este tutorial paso a paso, no deber\u00eda tener ning\u00fan caso en el que necesite usar <code>_e()<\/code>. Cuando haya terminado, vuelva a compilar el Javascript y nos alejaremos de Javascript.<\/p>\n<h2>Configuraci\u00f3n de archivos po y\/o pot<\/h2>\n<p>Este paso var\u00eda un poco seg\u00fan lo que ya haya hecho y configurado para su tema o complemento. Es posible que est\u00e9 escribiendo sus scripts de Gutenberg en un complemento nuevo y vac\u00edo que no se ha configurado para la traducci\u00f3n de PHP, o dentro de un tema que ya tiene un dominio de texto registrado. Es posible que tenga archivos PO (y MO) listos, o que solo tenga un archivo POT. Har\u00e9 todo lo posible para cubrir todas las bases.<\/p>\n<h3>Mi tema o complemento ya tiene un archivo po(t)<\/h3>\n<p>Si ya tiene un archivo PO o POT en su proyecto, lo m\u00e1s probable es que tambi\u00e9n tenga la funci\u00f3n PHP <code>load_theme_textdomain()<\/code>, <code>load_child_theme_textdomain()<\/code>o <code>load_plugin_textdomain()<\/code>en alg\u00fan lugar de su c\u00f3digo. Aseg\u00farese de que el dominio registrado sea el mismo que ha utilizado en sus archivos Javascript.<\/p>\n<p>Todo lo que necesita hacer es cargar el archivo PO para el idioma que desea traducir (o generar uno desde el archivo POT) en, por ejemplo <a href=\"https:\/\/poedit.net\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">, PoEdit<\/a>. Haga clic en &quot;Actualizar desde el c\u00f3digo&quot; (o similar en otros programas) para que el programa pueda escanear todos los archivos del proyecto (incluidos nuestros archivos Javascript actualizados recientemente) y actualizar el grupo de cadenas para la traducci\u00f3n. Deber\u00edan aparecer las cadenas en nuestro archivo Javascript. Luego solo necesita traducirlos como normales y guardar.<\/p>\n<p>PD: si no puede hacer clic en &quot;Actualizar desde el c\u00f3digo&quot; o volver a escanear los archivos, es probable que el archivo PO no se haya configurado correctamente. Busque consejos en la siguiente secci\u00f3n.<\/p>\n<h3>No tengo ning\u00fan archivo de traducci\u00f3n.<\/h3>\n<p>Si su tema o proyecto no ha sido configurado con traducci\u00f3n, necesita generar un archivo POT usando WP-CLI o crear manualmente un archivo PO.<\/p>\n<p>Tengo una gu\u00eda detallada sobre c\u00f3mo crear un archivo PO en mi <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 temas para principiantes, parte 8<\/a>. La publicaci\u00f3n describe c\u00f3mo puede crear el archivo y configurarlo correctamente para buscar sus archivos de tema y las palabras clave para buscar (<code>__<\/code>, <code>_e<\/code>, etc.).<\/p>\n<p>Si prefiere crear un archivo POT, puede usar el <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> en WP-CLI y luego crear un archivo PO a partir de eso usando, por ejemplo, PoEdit. Tenga en cuenta que deber\u00e1 volver a generar el archivo POT (y luego el archivo PO) cada vez que actualice cualquier cadena en su c\u00f3digo.<\/p>\n<h3>Resultado final<\/h3>\n<p>Lo que finalmente necesita es un archivo PO que haya encontrado sus cadenas de Javascript donde se han traducido. Recomiendo colocar sus archivos de traducci\u00f3n en una carpeta separada en su tema o complemento. Cuando comencemos a generar archivos JSON, terminaremos con bastantes archivos para traducir y ser\u00e1 bueno mantenerlos todos juntos en su propia carpeta.<\/p>\n<p>Como punto de referencia, estoy colocando todos los archivos de traducci\u00f3n en mi archivo <code>theme\/assets\/lang\/<\/code>. Agregu\u00e9 una traducci\u00f3n al noruego para mi tema, llamada <code>nb_NO.po<\/code>, que contiene las cadenas traducidas de nuestro archivo Javascript de bloque personalizado.<\/p>\n<h2>Generaci\u00f3n de archivos JSON desde el archivo po<\/h2>\n<p>El siguiente paso es usar WP-CLI para generar archivos JSON desde nuestro archivo po. Para ello usamos el 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>Tenga en cuenta que, de manera predeterminada, este comando eliminar\u00e1 las cadenas traducidas de su archivo PO para usarlas en la generaci\u00f3n de archivos JSON. Esto puede ser engorroso mientras se encuentra en medio del desarrollo de su tema o complemento. Porque cuando agrega cadenas nuevas o las ajusta, tendr\u00e1 que volver a escanear los archivos y traducir todas las cadenas nuevamente (y otra y otra vez). Afortunadamente, hay una bandera en el comando para evitar esto.<\/p>\n<p>\u00a1Empecemos! En su terminal, navegue hasta el directorio de su idioma para su proyecto. Ejecute el siguiente comando y consulte su archivo po (como se mencion\u00f3, tengo un <code>nb_NO.po<\/code>archivo listo).<\/p>\n<pre><code>wp i18n make-json nb_NO.po --no-purge<\/code><\/pre>\n<p>Si no tiene problemas para eliminar las cadenas traducidas de su archivo PO (por ejemplo, si est\u00e1 haciendo su compilaci\u00f3n final), puede omitir la <code>--no-purge<\/code>bandera.<\/p>\n<p>El terminal deber\u00eda indicar &quot;\u00c9xito&quot; e indicar cu\u00e1ntos archivos JSON se crearon. Si ve que gener\u00f3 dos archivos JSON, es porque ley\u00f3 nuestro archivo Javascript de c\u00f3digo fuente y el archivo de compilaci\u00f3n, y gener\u00f3 uno para cada uno. Si tiene m\u00e1s archivos Javascript en su proyecto, terminar\u00e1 con a\u00fan m\u00e1s archivos JSON.<\/p>\n<p>Al momento de escribir esto (WordPress v 5.3.2 y WP-CLI versi\u00f3n 2.4.0), los archivos JSON se generan con el c\u00f3digo de idioma y un hash, una cadena cr\u00edptica como nombres de archivo. Necesitamos encontrar el correcto y cambiarle el nombre.<\/p>\n<h2>Cambiar el nombre del archivo JSON y cargarlo en 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=\"Crear bloque de Gutenberg personalizado - Parte 8: Soporte de traducci\u00f3n\" ><\/a><\/p>\n<p>Su carpeta de idioma probablemente se parece a esto:<\/p>\n<p>Recuerde que el comando ha generado un archivo JSON por archivo Javascript, y como en realidad tenemos dos archivos para nuestro bloque personalizado (la fuente y la compilaci\u00f3n), gener\u00f3 dos archivos. Si su c\u00f3digo Javascript se divide en varios archivos, cada uno obtendr\u00e1 dos de sus propios archivos JSON.<\/p>\n<p>Si solo tiene dos archivos JSON (porque no se encontraron otros archivos Javascript), puede eliminar uno de ellos ahora. Si tiene m\u00e1s de dos, debe abrir los archivos JSON y ver para qu\u00e9 archivo son. Los archivos JSON contienen una propiedad &quot; <code>source<\/code>&quot; que le indica para qu\u00e9 archivo Javascript es este archivo JSON. \u00daselo para averiguar qu\u00e9 archivo JSON conservar. Recomiendo encontrar el archivo de compilaci\u00f3n final (a diferencia de los archivos de desarrollo), ya que debe contener todas las cadenas de todos los archivos.<\/p>\n<p>Cuando haya encontrado el correcto, debemos cambiarle el nombre. Necesitamos cambiarle el nombre para que siga este patr\u00f3n:<\/p>\n<p><code>[textdomain]-[language code]-[script handle].json<\/code><\/p>\n<p>Use el dominio de texto que ha usado en todas partes (por ejemplo <code>__('My string', 'awhitepixel')<\/code>), agregue un gui\u00f3n y el c\u00f3digo de idioma. Luego proporcione un gui\u00f3n y el identificador de secuencia de comandos que utiliz\u00f3 para registrar su archivo Gutenberg Javascript (<code>wp_register_script()<\/code>). Como referencia, mi dominio de texto es <code>awhitepixel<\/code>, mi c\u00f3digo de idioma es <code>nb_NO<\/code>y mi identificador de script para el script de Gutenberg es <code>awp-myfirstblock-js<\/code>. As\u00ed que cambio el nombre del archivo JSON a:<\/p>\n<p><code>awhitepixel-nb_NO-awp-myfirstblock-js.json<\/code><\/p>\n<h3>Dile a WordPress que cargue nuestro JSON<\/h3>\n<p>Todo lo que queda ahora es el paso final: decirle a WordPress que cargue nuestro archivo JSON. Necesitamos usar la funci\u00f3n <code>[wp_set_script_translations](https:\/\/developer.wordpress.org\/reference\/functions\/wp_set_script_translations\/)()<\/code>. Esta es una funci\u00f3n bastante nueva de WordPress, por lo que recomiendo envolverla dentro de un archivo <code>function_exists()<\/code>. Acepta tres par\u00e1metros; el identificador del script para nuestro bloque, el dominio de texto y la ruta a nuestra carpeta de traducci\u00f3n (nota: la ruta, no la URL).<\/p>\n<p>Dentro de nuestra funci\u00f3n conectada a <code>init<\/code>, donde registramos nuestro script de bloque y llamamos <code>register_block_type<\/code>, tambi\u00e9n podemos llamar a esta nueva funci\u00f3n para cargar nuestro archivo de traducci\u00f3n JSON. PD: Tenga en cuenta que el gancho <code>enqueue_block_assets<\/code>no funcionar\u00e1 para registrar traducciones.<\/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>\u00a1Y eso es todo! Su bloque ahora deber\u00eda estar traducido. Cambie el idioma de WordPress al idioma al que tradujo y compru\u00e9belo usted mismo. Cuando cambio mi idioma de WordPress a noruego y agrego mi bloque, el nombre y todo lo que contiene se traduce:<\/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=\"Crear bloque de Gutenberg personalizado - Parte 8: Soporte de traducci\u00f3n\" ><\/a><\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <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 lecci\u00f3n se enfoca en c\u00f3mo apoyar la traducci\u00f3n de los textos en nuestro bloque de Gutenberg. Usamos WP-CLI para generar los archivos JSON necesarios para 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":[892,892,810,935,935,1110,800,800,810,840,840,861,861],"tags":[1172],"class_list":{"0":"post-233456","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-codigo","9":"category-complementos","10":"category-gutenberg-2","12":"category-n-a","13":"category-php-2","16":"category-tutoriales","18":"category-wordpress-2","20":"tag-affiai-es"},"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/233456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=233456"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/233456\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/153241"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=233456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=233456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=233456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}