{"id":114,"date":"2016-06-06T20:39:34","date_gmt":"2016-06-06T20:39:34","guid":{"rendered":"https:\/\/blog.jkanework.com\/post.php?idpost=114"},"modified":"2016-06-06T20:39:34","modified_gmt":"2016-06-06T20:39:34","slug":"linux-crea-scripts-multilenguaje-de-forma-simple-alternativa-a-gettext","status":"publish","type":"post","link":"https:\/\/blog.jkanetwork.com\/?p=114","title":{"rendered":"[Linux] Crea scripts multilenguaje de forma simple (Alternativa a gettext)"},"content":{"rendered":"<p>Bienvenidos a otro corto tutorial de JKANetwork<\/p>\n<p>Estos d&iacute;as, haciendo traducciones para unos scripts de un nuevo proyecto por parte de JKANetwork, vimos que hab&iacute;a varias formas para traducir programas, siendo sin duda la m&aacute;s utilizada (y con m&aacute;s herramientas) gettext. Pero, hay veces que, por bien no complicarse, o por simplificar, o bueno, por cualquier otra razon, quieres algo m&aacute;s \u00absencillo\u00bb sin archivos en carpetas aparte, etc. Aqu&iacute; se me ocurri&oacute; una idea, usando una funcion, a la que llamaremos T (De translate, si,muy currado). En esta funcion se iban poniendo los textos, y sus traducciones en diferentes idiomas adem&aacute;s de la del texto original. Evidentemente, con soporte multiidioma por parte de la distribucion (Recogiendo el idioma), o poniendo tu menu de idioma, para gustos los colores.<\/p>\n<p>Primero os mostrare la funcion en si metida en un script, y despu&eacute;s lo explicar&eacute; trozo por trozo a&ntilde;adiendo tambi&eacute;n un fichero al final descargable.<\/p>\n<p>El codigo .sh sobre el que har&eacute; la explicaci&oacute;n es el siguiente:<\/p>\n<p><span style=\"color: #800000;\">#!\/bin\/bash<\/span><br \/><span style=\"color: #800000;\">sclang=$(echo $LANG | cut -c1-2)<\/span><\/p>\n<p><span style=\"color: #800000;\">function T {<\/span><br \/><span style=\"color: #800000;\">case \u00ab$1\u00bb in<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; \u00abHello\u00bb)<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case $sclang in<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; \u00abes\u00bb)&nbsp;&nbsp;&nbsp; echo \u00abHola\u00bb;;<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *)&nbsp;&nbsp;&nbsp; echo \u00ab$1\u00bb;;<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; esac;;<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; \u00abGoodbye\u00bb)<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case $sclang in<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; \u00abes\u00bb)&nbsp;&nbsp;&nbsp; echo \u00abGoodbye\u00bb;;<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *)&nbsp;&nbsp;&nbsp; echo \u00ab$1\u00bb;;<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; esac;;<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; *)&nbsp;&nbsp;&nbsp; echo \u00ab$1\u00bb;;<\/span><br \/><span style=\"color: #800000;\">esac<\/span><br \/><span style=\"color: #800000;\">}<\/span><\/p>\n<p><span style=\"color: #800000;\">echo \u00ab$(T \u00abHello\u00bb)\u00bb<\/span><\/p>\n<p>Explicaci&oacute;n por lineas..<br \/><span style=\"color: #800000;\">sclang=$(echo $LANG | cut -c1-2) &#8211; <span style=\"color: #000000;\">Esta linea mete en una variable el idioma del ordenador en el que se ejecuta, en este caso solo con la parte general (Es decir, \u00abes\u00bb, \u00aben\u00bb&#8230;), si cambiais el 2 por un 4 seria entero tipo <\/span><\/span>es_ES, en_UK, etc, pero habr&iacute;a que hacer m&aacute;s traducciones claro, y aqu&iacute; tratamos de simplificar<\/p>\n<p>La funcion T es la que hace el proceso, empieza con un <span style=\"color: #800000;\">case \u00ab$1\u00bb in , <span style=\"color: #000000;\">siendo $1 lo que va a traducir (Es decir, el argumento de la funci&oacute;n, la palabra o frase a traducir)<\/span><br \/><\/span><\/p>\n<p><span style=\"color: #800000;\"><span style=\"color: #000000;\">Dentro de ese case se forma la siguiente estructura repetida muchas veces:<\/span><\/span><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; \u00abHello\u00bb)&nbsp; <span style=\"color: #000000;\">-&gt; Palabra a traducir<\/span><\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case $sclang in&nbsp; <span style=\"color: #000000;\">-&gt; Aqu&iacute; hace otro \u00abcase\u00bb para traducir al idioma de la m&aacute;quina concreta, con la variable de antes<\/span><\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; \u00abes\u00bb)&nbsp;&nbsp;&nbsp; echo \u00abHola\u00bb;; <span style=\"color: #000000;\">-&gt; Y en cada uno, se a&ntilde;ade la traducci&oacute;n, en este caso es la \u00abes\u00bb de castellano\/espa&ntilde;ol<\/span><\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *)&nbsp;&nbsp;&nbsp; echo \u00ab$1\u00bb;; <span style=\"color: #000000;\">-&gt;Al final, siempre una con * que devuelve lo mandado a la funci&oacute;n (Que normalmente se escribe en ingl&eacute;s), es un fallback<\/span><\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; esac;; <span style=\"color: #000000;\">-&gt; Cerramos el case<\/span><br \/><\/span><\/p>\n<p><span style=\"color: #000000;\">Al acabar todas las traducciones, evidentemente hay que cerrar el otro case \u00ab$1\u00bb in con otro esac;;<br \/><\/span><\/p>\n<p><span style=\"color: #000000;\">En mi caso puse un fallback de la funci&oacute;n debajo de las traducciones con \u00ab<\/span><span style=\"color: #800000;\"><span style=\"color: #800000;\">*)&nbsp;&nbsp;&nbsp; echo \u00ab$1\u00bb;;<\/span><span style=\"color: #000000;\">\u00bb para que siempre aparezca algun texto, mejor mal que nada<\/span><\/span><\/p>\n<p><span style=\"color: #800000;\"><span style=\"color: #000000;\">Para mandar algo a traducir ah&iacute; es t&aacute;n facil como mandar a la funci&oacute;n la palabra<br \/>Ejemplo: <\/span><\/span><span style=\"color: #800000;\">echo \u00ab$(T \u00abHello\u00bb)\u00bb<\/span><\/p>\n<p><span style=\"color: #000000;\">Eso manda \u00abHello\u00bb a la funci&oacute;n, y nos devolver&aacute; el texto traducido, en nuestro caso, al espa&ntilde;ol<br \/><\/span><\/p>\n<p>Hasta aqui la parte b&aacute;sica del tutorial, pero para gente que quiera un poco m&aacute;s, ampliamos.<\/p>\n<p>Por ejemplo, que pasa si quieres que a&ntilde;ada un \u00abargumento\u00bb , palabra, o parametro a esa traduccion? Por ejemplo, si queremos que responda \u00abHola Kevin\u00bb o \u00abHola Rosa\u00bb etc?<\/p>\n<p>La funci&oacute;n lee $1 que ser&iacute;a el primer argumento, el texto, y luego, puedes a&ntilde;adir otro m&aacute;s que leer&iacute;a como $2 (y m&aacute;s si se quiere claro)<\/p>\n<p>Entonces.. Mandas por ejemplo <span style=\"color: #800000;\">echo \u00ab$(T \u00abHello\u00bb \u00abKevin\u00bb)\u00bb<\/span>&nbsp; , como ves, Kevin esta entrecomillado aparte, lo manda como $2. Ahora bien, la funci&oacute;n cambia un poco, pero muy poco<\/p>\n<p><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; \u00abHello\u00bb)<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case $sclang in<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; \u00abes\u00bb)&nbsp;&nbsp;&nbsp; echo \u00abHola $2\u00bb;; <span style=\"color: #000000;\">-&gt; Como se puede ver, a&ntilde;ad&iacute; $2 para que muestre Kevin por ejemplo en este caso<\/span><\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *)&nbsp;&nbsp;&nbsp; echo \u00ab$1 $2\u00bb;;<\/span><br \/><span style=\"color: #800000;\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; esac;;<\/span><\/p>\n<p>Asi de facil ser&iacute;a<\/p>\n<p>Por cierto, como dec&iacute;a al principio, algunos querr&eacute;is tenerlo en un archivo separado, verdad?<br \/>Entonces solo ten&eacute;is que tener un bash (Llamalo como quieras, en el ejemplo ser&aacute; traduccion.sh) con el \u00ab#!\/bin\/bash\u00bb y la funcion T, y luego, donde lo quer&aacute;is usar, llamadlo asi:<br \/><span style=\"color: #800000;\">source .\/traduccion.sh<\/span> <br \/>As&iacute; cargar&aacute; la funci&oacute;n, y podr&eacute;is usarla igual que si estuviera en el fichero original<\/p>\n<p>Aqu&iacute; teneis un fichero de ejemplo de todo lo dicho, para que hag&aacute;is pruebas.&nbsp;<a href=\"https:\/\/mirror.jkanetwork.com\/Scripts\/blogjkanetwork\/funciontraduccion.sh\" target=\"_blank\">https:\/\/mirror.jkanetwork.com\/Scripts\/blogjkanetwork\/funciontraduccion.sh<\/a> (Si el fichero no se abre, comprobad si tiene permisos de ejecucion [chmod +x fichero] )<\/p>\n<p>&nbsp;<\/p>\n<p>Espero que esto os sirva para aprender otras formas de traducci&oacute;n no tan estandar, y esta es bastante.. \u00abcustomizable\u00bb. Si me expres&eacute; mal, hacedmelo saber y corregir&eacute; el tutorial \ud83d\ude42<\/p>\n<p><strong>Actualizaci&oacute;n:<\/strong> Correcci&oacute;n de la explicaci&oacute;n y subida de un ejemplo<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bienvenidos a otro corto tutorial de JKANetwork Estos d&iacute;as, haciendo traducciones para unos scripts de un nuevo proyecto por parte de JKANetwork, vimos que hab&iacute;a varias formas para traducir programas, siendo sin duda la m&aacute;s utilizada (y con m&aacute;s herramientas) gettext. Pero, hay veces que, por bien no complicarse, o por simplificar, o bueno, por [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-114","post","type-post","status-publish","format-standard","hentry","category-tutoriales"],"_links":{"self":[{"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=\/wp\/v2\/posts\/114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=114"}],"version-history":[{"count":0,"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=\/wp\/v2\/posts\/114\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jkanetwork.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}