Joaquín Cuenca
Si habeis conseguido crear una aplicación web (¡felicidades!), lo más probable es que la hayais escrito en inglés o en castellano. No creo que tenga que convencer a nadie de que en ese caso, estais dejando pasar un mercado potencial enorme, ya que hay más gente en el mundo qué no habla inglés o castellano qué la que lo hablan. Para aprovechar el trabajo que teneís hecho y lanzaros a esos nuevos mercados es necesario (aunque tal vez no sea suficiente) traducir vuestra página web a otros idiomas.
El mayor problema con el que os vais a encontrar es la falta de conocimientos sobre internacionalización. Es increíble como muchos programadores, por lo demás perfectamente capacitados, parecen convertirse en Paris Hilton cuando hablan de internacionalización. Eso si llegan a hablar... Vamos a empezar sentando las bases de lo que es un juego de carácteres (charset) y una codificación (encoding). El juego de carácteres es la tabla que traduce de un número a un "carácter" (o para ser más precisos un "codepoint"), y la codificación es el algoritmo que hemos seguido para guardar ese número.
Por ejemplo, el juego de carácteres ISO-8859-1 (también conocido como ISO-Latin-1) es una tabla idéntica a ASCII para números menores de 128, y entre 128 y 255 incluye todos los carácteres necesarios para las lenguas usadas en Europa occidental, excepto por los carácteres Š, š, Ž, ž, Œ, œ, Ÿ, y el €. ISO-8859-15 es idéntico a ISO-8859-1 excepto por la inclusión de estos ocho carácteres. Si usais ISO-Latin-1 y siempre os habeis preguntado por qué había que usar € para conseguir el € en HTML en lugar de poder escribirlo directamente, ya conoceis el motivo. Dado que estos dos charsets, al igual que todos los de la familia ISO-8859 sólo contienen 255 carácteres, el encoding que siempre se usa es el más trivial: guardar cada carácter en un byte.
Sirviendo las páginas siempre en este juego de carácteres podremos tener textos en cualquier idioma de europa occidental. Pero ¿qué pasa con el resto del mundo? podríamos imaginarnos un sistema donde elegimos un juego de carácteres en función del idioma, pero esto no funcionaría si tenemos una página con una mezcla en varios idiomas (muy común si tenemos un sistema de comentarios, y una audiencia internacional) y en general es engorroso e innecesario. Afortunadamente, este problema ha sido resulto por el consorcio Unicode, que se lanzó a la creación de un juego de carácteres que incluyese todos los carácteres usados en el mundo.
Para codificar Unicode se empezó usando dos bytes por carácter. Este encoding se llama UCS-2, y se sigue usando en Windows y en Java. Por algún motivo, en toda la documentación tanto para usuarios como para desarrolladores, a UCS-2 se le llama "Unicode". Dependiendo de la arquitectura en la que estemos, el byte menos significativo de un carácter puede ser el primero, o el segundo, así que tenemos dos variantes de UCS-2, UCS-2LE (LittleEndian) y UCS-2BE (BigEndian). Para distinguir qué variante se está usando se le añade al principio del texto el carácter 0xFEFF "ZERO WIDTH NO-BREAK SPACE" (también conocido como el "BOM", Byte Order Marker). Así, si nos encontramos con un carácter BOM sabemos que estamos leyendo UTF-16 en el orden correcto. Si nos encontramos con un BOM reflejado (0xFFFE) sabemos que estamos leyendo al revés, ya que 0xFFFE no existe en Unicode.
Cuando UCS-2 se quedó corto para almacenar todos los carácteres del mundo y hubo que ir más allá de 0xFFFF, se añadió una extensión y se le llamó UTF-16, donde se usan dos carácteres especiales (llamados surrogates pair) para indicar que los bytes siguientes están fuera del plano básico. Se pierde así el único interés que tenía UTF-16, y es que se podía saltar directamente al carácter en la posición "n", ya que se conocía el tamaño de cada carácter (2 bytes). En realidad UCS-2 nunca tuvo esta cualidad, ya que ciertos carácteres en Unicode no son tales (por eso su nombre técnico es¨"codepoint"). Algunos codepoints son sólo un indicador que dice que hay que modificar el carácter que le sigue, por ejemplo añadiéndole un acento. ¿Y por qué no podían codificar cada carácter con un acento por separado, sin tener que recurrir a modificadores? Empezaron así, por eso tenemos un carácter independiente para "á", pero este método dejó de funcionar cuando se llegó al vietnamita (echadle un vistazo a un texto en vietnamita y vereis en seguida el motivo...).
También se creó otra codificación alternativa, UTF-32 (o UCS-4), qué consistía en guardar cada codepoint con 4 bytes. En realidad 3 bastan, pero en aras de mantener todos los carácteres alineados para arquitecturas de 4 bytes se añade uno extra (ya que estamos desperdiciando espacio...). Este es el motivo por el que en linux wchar_t mide 4 bytes, mientras que en Windows mide 2.
Estos dos encodings tienen en común que para los carácteres occidentales incluyen un byte con valor 0. Pero en una cadena C, el byte con valor 0 tiene el significado especial de ser el final de la cadena de texto. Todos los programas que usan C y leen texto tienen que cambiarse, ya que strlen, strcpy, etc. ya no funcionan con estos textos.
Así estaban las cosas cuando Ken Thompson y Rob Pike inventaron un nuevo encoding de tamaño variable llamado UTF-8. UTF-8 es idéntico a ASCII para todos los carácteres inferiores a 128, y usa uno o varios bytes extra (hasta un máximo de 4) cuando tiene que almacenar un número superior a 128. Cualquier texto ASCII en inglés es automáticamente un texto UTF-8 válido. Los textos europeos son en torno a un 2% más grandes que usando ISO-8859-15, ya que sólo los carácteres acentuados aumentan de tamaño. Los únicos que realmente salen perdiendo son aquellos que tenían un alfabeto pequeño (griego, ruso, ...) sin nada en común con el inglés, ya que antes podían codificar cada carácter con un 1 byte y ahora necesitan más. UTF-8 no usa ningún byte 0 en su codificación, y funciones como strcpy funcionan con textos UTF-8.
Mi recomendación es usar UTF-8 tanto en la base de datos como en la interfaz web. Algunos consejos prácticos:
Si guardais un texto en Windows como UTF-8, teneis muchas posibilidades de que el editor añada un "BOM" (también llamado "signature"). El BOM era útil para UTF-16, pero para UTF-8 es totalmente irrelevante, ya que en UTF-8 los carácteres se leen en un array de bytes, y el orden de la arquitectura no cambia nada (no existe un UTF-8 LE o UTF-8 BE). Pero en Windows lo siguen escribiendo para poder distinguir texto codificado en UTF-8 del codificado con otro encoding. Cuidad de usar un editor que os permita guardar en UTF-8 sin BOM, o vereis como vuestras páginas escriben tres bytes de más al principio de cada página web (el carácter BOM escrito en UTF-8 es EF BB BF). Si no la función headers en PHP os da un error porque ya habeis escrito "algo" en la página, y no sabeis lo que es, comprobad si el BOM está ahí y quitadlo.
Codificar vuestros textos en UTF-8 es el primer paso, pequeño pero significativo, para la internacionalización de vuestra página. En el próximo artículo veremos un ejemplo práctico de como traducir una página web.
Por último, es interesante saber que no basta con conocer el carácter que se le quiere mostrar al usuario para saber que grafía (en inglés, el glyph) hay que mostrar en pantalla.
Algunos idiomas como el árabe son contextuales, el mismo carácter puede tener 4 grafías distintas según esté solo, empiece la palabra, esté en medio, o la termine. Otros idiomas comparten carácteres, pero cambian ligeramente (o radicalmente) su grafía. El ejemplo más conocido es el de los scripts hanzi (Chino), kanji (Japonés) y hanja (Koreano). Estos scripts tienen un origen común, pero con el tiempo la forma de representar esos carácteres ha ido evolucionando. Así, si tenemos que mezclar en un mismo documento un carácter kanji Japonés con su equivalente en Chino tradicional, debemos indicar de alguna forma que una parte del texto está en Japones y otra en Chino tradicional. El mismo problema tiene el serbio, que se puede escribir en latín, o en cirílico, pero con la particularidad de que en cirílico algunas grafías cambian con respecto al cirílico ruso (ver este artículo sobre tipografía para más información). A pesar de que en HTML podemos indicar el language del documento, o de trozos de texto, usando el atributo "lang".
Ningún navegador cambia las grafías en función del idioma elegido, así que podeis considerar el párrafo anterior como puramente teórico, pero aún así es interesante poner correctamente el atributo "lang" ya que la pronunciación al igual que las grafías dependen del idioma (¡y de forma muchísimo más marcada!) y para personas invidentes es importante que su lector sepa con que voz debe de leer el texto.
Por cierto, Rob Pike trabaja en Google. Si quieres trabajar en un ambiente genial, con brillantes compañeros, envía tu CV a Google.

13 comments:
¡Genial!
El mejor artículo que he leído sobre la Internacionalización, sobre todo el más claro, preciso y sobre todo profesional.
Gracias y enhorabuena
P.D. Estaré esperando la segunda parte.
Por fin algo de luz sobre internacionalización. Había intentado unas cuantas veces aprender sobre el tema, pero todos los articulos y tutoriales que leía era bastante confusos.
Este artículo me ha encantado por lo claro que es. Podrías hacer además un artículo sobre como manejar los distintos idiomas y codificaciones en Python.
Un saludo
Impresionante el artículo, felicidades. Intenté pasar una vez a UTF-8 desde ISO-8859-15 pero me daba problemas precisamente el BOM y los editores de Windows. Se resolvió cambiando a Ubuntu.
Lo de Ken Thompson y Rob Pike inventando el UTF-8 es una historia muy interesante; el sistema se diseñó prácticamente desde cero en una cena, y se implementó en el código fuente de Plan 9 en un par de días. Amigo, esto si que es ser auténticos hackers. Se comprende que los dos sean leyendas.
Si alguien quiere más trasfondo histórico, aquí hablan del asunto, entre otros, el propio Rob Pike: http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt
Genial el artículo, enhorabuena! esperando la continuación para meternos en harina :)
Y por cierto, menudas oficinas, envidia no es la palabra...
Muy buen artículo, ahora a esperar la segunda parte.
Lástima que cuando haya leído las dos partes, seguiré sin saber aplicarlo, pero sabré lo que no aplico.
"Por último, es interesante saber que no basta con conocer el carácter que se le quiere mostrar al usuario para saber que grafía (en inglés, el glyph) hay que mostrar en pantalla."
y aqui me has dejado con la duda. y como se supone que arreglan esto?. metiendo mas caracteres (en plan bestia), o se encarga el propio navegador de cambiar el caracter por el contexto (creo que esto seria un poco pesado para el navegador).
lo que queda claro que segun se vaya escribiendo (por da un ejemplo) se tiene que revisar el contexto para ver si hay que colocar en pantalla, o como segunda opcion se le deja al que escribe que el mismo coloque la opcion que crea conveniente (lo que puede necesitar un teclado mas grande o que utilice teclas de control para introducir ciertos caracteres).
p.d.: no he puesto acentos por esto de que todo se codifique en ascii sin problemas ;)
Hola vainas,
para saber que grafia hay que mostrar, el navegador tiene que conocer en que idioma esta el texto, no solo el codepoint. Esto es en teoria, como digo los navegadores hoy en dia no usan esta informacion.
En la practica, el usuario tiene instalada una fuente que tiene la grafia a la que esta acostumbrado, asi que las fuentes chinas y japonesas son distintas, a pesar de cubrir los mismos codepoints en los alfabetos hanzi y kanji.
El problema surge cuando se intenta leer una pagina en japones usando un ordenador en chino. En lugar de aparecer las grafias tipicas del japones salen las del chino. Hasta que los navegadores no arreglen este problema, no hay nada que se pueda hacer.
Un saludo!
豆豆聊天室 aio交友愛情館 2008真情寫真 2009真情寫真 aa片免費看 捷克論壇 微風論壇 大眾論壇 plus論壇 080視訊聊天室 情色視訊交友90739 美女交友-成人聊天室 色情小說 做愛成人圖片區 豆豆色情聊天室 080豆豆聊天室 小辣妹影音交友網 台中情人聊天室 桃園星願聊天室 高雄網友聊天室 新中台灣聊天室 中部網友聊天室 嘉義之光聊天室 基隆海岸聊天室 中壢網友聊天室 南台灣聊天室 南部聊坊聊天室 台南不夜城聊天室 南部網友聊天室 屏東網友聊天室 台南網友聊天室 屏東聊坊聊天室 雲林網友聊天室 大學生BBS聊天室 網路學院聊天室 屏東夜語聊天室 孤男寡女聊天室 一網情深聊天室 心靈饗宴聊天室 流星花園聊天室 食色男女色情聊天室 真愛宣言交友聊天室 情人皇朝聊天室 上班族成人聊天室 上班族f1影音視訊聊天室 哈雷視訊聊天室 080影音視訊聊天室 38不夜城聊天室 援交聊天室080 080哈啦聊天室 台北已婚聊天室 已婚廣場聊天室 夢幻家族聊天室 摸摸扣扣同學會聊天室 520情色聊天室 QQ成人交友聊天室 免費視訊網愛聊天室 愛情公寓免費聊天室 拉子性愛聊天室 柔情網友聊天室 哈啦影音交友網 哈啦影音視訊聊天室 櫻井莉亞三點全露寫真集 123上班族聊天室 尋夢園上班族聊天室 成人聊天室上班族 080上班族聊天室 6k聊天室 粉紅豆豆聊天室 080豆豆聊天網 新豆豆聊天室 080聊天室 免費音樂試聽 流行音樂試聽 免費aa片試看A片 免費a長片線上看 色情貼影片 免費a長片 本土成人貼圖站 大台灣情色網 台灣男人幫論壇 A圖網 嘟嘟成人電影網 火辣春夢貼圖網 情色貼圖俱樂部 台灣成人電影 絲襪美腿樂園 18美女貼圖區 柔情聊天網 707網愛聊天室聯盟 台北69色情貼圖區 38女孩情色網 台灣映像館 波波成人情色網站 美女成人貼圖區 無碼貼圖力量 色妹妹性愛貼圖區 日本女優貼圖網 日本美少女貼圖區 亞洲風暴情色貼圖網 哈啦聊天室 美少女自拍貼圖 辣妹成人情色網 台北女孩情色網 辣手貼圖情色網 AV無碼女優影片 男女情色寫真貼圖 a片天使俱樂部 萍水相逢遊戲區 平水相逢遊戲區 免費視訊交友90739 免費視訊聊天 辣妹視訊 - 影音聊天網 080視訊聊天室 日本美女肛交 美女工廠貼圖區 百分百貼圖區 亞洲成人電影情色網 台灣本土自拍貼圖網 麻辣貼圖情色網 好色客成人圖片貼圖區 711成人AV貼圖區 台灣美女貼圖區 筱萱成人論壇 咪咪情色貼圖區 momokoko同學會視訊 kk272視訊 情色文學小站 成人情色貼圖區 嘟嘟成人網 嘟嘟情人色網 - 貼圖區 免費色情a片下載 台灣情色論壇 成人影片分享 免費視訊聊天區 微風 成人 論壇 kiss文學區 taiwankiss文學區
85cc免費影城 愛情公寓正妹牆川藏第一美女 成人影片 情色交友網 美女視訊 美女視訊 視訊情人高雄網 JP成人影城 383成人影城 aa片免費a片下載 a片線上看aa片免費看 ※a片線上試看※sex520免費影片※ aa片免費看 BT成人論壇 金瓶影片交流區 自拍美女聊天室 aa片免費a片下載 SEX520免費影片 免費a片 日本美女寫真集 sex520aa免費影片 sex520aa免費影片 BT成人網 Hotsee免費視訊交友 百分百貼影片區 SEX520免費影片 免費視訊聊天室 情人視訊高雄網 星光情色討論版 正妹牆 383成人影城 線上85cc免費影城 85cc免費影城 85cc免費影城 85cc免費影城 ※免費視訊聊天室※ ※免費視訊聊天室※ 免費視訊聊天室 85cc免費影片 85cc免費影片 080苗栗人聊天室 080苗栗人聊天室 080中部人聊天室 080中部人聊天室 免費a片下載 免費a片 AA片免費看 aa片免費看 aa片免費看 aa片免費看 aa片免費看 日本av女優影片 av女優 av女優無碼影城 av女優 av女優 百分百成人圖片 百分百成人圖片 視訊情人高雄網 電話交友 影音電話交友 絕色影城 絕色影城 夜未眠成人影城 夜未眠成人影城 色咪咪影片網 色咪咪影片網 色咪咪影片網 色咪咪影片網 色咪咪影片網 免費色咪咪貼影片 免費色咪咪貼影片 色情遊戲 色情遊戲 色情遊戲 色情遊戲 影音視訊交友網
視訊交友網 080視訊聊天室 ※免費視訊聊天室※ ※免費視訊聊天室※ 視訊聊天室 成人影音視訊聊天室 ut影音視訊聊天室 ※免費視訊聊天室※ 視訊ukiss聊天室視訊ukiss聊天室 視訊交友90739 視訊交友90739 情人視訊網 168視訊美女 168視訊美女 168視訊美女 視訊美女館 視訊美女館 免費視訊美女網 小高聊天室 小高聊天室 aio交友聊天室 aio交友聊天室 交友聊天室 交友聊天室 線上a片 線上a片 線上a片 線上a片 線上a片 免費線上a片 免費線上a片 嘟嘟成人網站 成人漫畫 情色文學 嘟嘟成人網 成人貼圖區 情色文學成人小說 微風成人區 情色貼圖區 免費視訊聊天 免費成人圖片區 愛情公寓 愛情公寓聊天室 寄情築園小遊戲 免費aa片線上看 aa片免費看 情色SXE聊天室 SEX情色遊戲 色情A片 免費下載 av女優 俱樂部 情色論壇 辣妹視訊 情色貼圖網 免費色情 聊天室 情人視訊聊天室 免費a片成人影城 免費a片-aa片免費看 0204貼圖區 SEX情色 交友聊天-線上免費 女優天堂 成人交友網 成人情色貼圖區 18禁 -女優王國 080視訊美女聊天室 080視訊聊天室 視訊交友90739 免費a片 aio 視訊交友網 成人影城-免費a片※免費視訊聊天※85cc免費影片日本線上免費a片 免費色咪咪影片免費色咪咪影片aaa片免費看影片aaa片免費看成人影城情人視訊高雄網sex520免費影片080聊天室080聊天室aa的滿18歲影片免費av18禁影片免費av18禁影片免費av18禁影片aa的滿18歲影片
環球影音城玩美女人影音秀ET成人文學AV女優王國18禁地少女遊戲無碼肛交影片下載波波線上遊戲網海綿寶寶小遊戲愛愛成人影片下載av女優電影下載美女短片免費試看熟女人妻無碼電影分享楓之谷小遊戲台灣18成人網人妻熟女三級片正妹潮吹影片分享成人動畫免費看多人雜交 肛交 顏射飲精系列小弟弟貼影片小潘潘寫真圖片美臀長腿絲襪影片下載亂倫熟女情色網小弟弟貼影片區jp成人小弟弟貼片麗的娛樂網只有貼圖區月宮貼 - 情色貼圖區成人卡漫18百分百成人貼圖片區一葉情成人貼圖片區成人卡通頻道西洋成人貼圖片區成人免費貼圖片區100one百萬成人貼電影夜未眠成人影城成人文章 免費分享區a38av383影音城微風成人區成人影音live秀女優王國亞洲成人圖片區徐若瑄寫真集
A片 免費a長片線上看 色情貼影片 免費a長片 本土成人貼圖站 大台灣情色網 台灣男人幫論壇 A圖網 嘟嘟成人電影網 火辣春夢貼圖網 情色貼圖俱樂部 台灣成人電影 絲襪美腿樂園 18美女貼圖區 柔情聊天網 707網愛聊天室聯盟 台北69色情貼圖區 38女孩情色網 台灣映像館 波波成人情色網站 美女成人貼圖區 無碼貼圖力量 色妹妹性愛貼圖區 日本女優貼圖網 日本美少女貼圖區 亞洲風暴情色貼圖網 哈啦聊天室 美少女自拍貼圖 辣妹成人情色網 台北女孩情色網 辣手貼圖情色網 AV無碼女優影片 男女情色寫真貼圖 a片天使俱樂部 萍水相逢遊戲區 平水相逢遊戲區 免費視訊交友90739 免費視訊聊天 辣妹視訊 - 影音聊天網 080視訊聊天室 日本美女肛交 美女工廠貼圖區 百分百貼圖區 亞洲成人電影情色網 台灣本土自拍貼圖網 麻辣貼圖情色網 好色客成人圖片貼圖區 711成人AV貼圖區 台灣美女貼圖區 筱萱成人論壇 咪咪情色貼圖區 momokoko同學會視訊 kk272視訊 情色文學小站 成人情色貼圖區 嘟嘟成人網 嘟嘟情人色網 - 貼圖區 免費色情a片下載 台灣情色論壇 成人影片分享 免費視訊聊天區 微風 成人 論壇 kiss文學區 taiwankiss文學區 自拍美女聊天室 日本成人短片 洪爺影城 豆豆聊天室 aio交友愛情館 2008真情寫真 2008真情寫真 aa片免費看 捷克論壇 微風論壇 plus論壇 080視訊聊天室 情色視訊交友90739 做愛成人圖片區 080豆豆聊天室 台中情人聊天室 桃園星願聊天室 高雄網友聊天室 新中台灣聊天室 中部網友聊天室 嘉義之光聊天室 中壢網友聊天室 南台灣聊天室 南部聊坊聊天室 台南不夜城聊天室 南部網友聊天室 屏東網友聊天室 台南網友聊天室 屏東聊坊聊天室 網路學院聊天室 屏東夜語聊天室 一網情深聊天室 流星花園聊天室 真愛宣言交友聊天室 上班族f1影音視訊聊天室 哈雷視訊聊天室 080影音視訊聊天室 援交聊天室080 080哈啦聊天室 台北已婚聊天室 已婚廣場聊天室 夢幻家族聊天室 摸摸扣扣同學會聊天室 520情色聊天室 QQ成人交友聊天室 免費視訊網愛聊天室 愛情公寓免費聊天室 拉子性愛聊天室 柔情網友聊天室 哈啦影音交友網 哈啦影音視訊聊天室 櫻井莉亞三點全露寫真集 123上班族聊天室 尋夢園上班族聊天室 成人聊天室上班族 080上班族聊天室 6k聊天室 粉紅豆豆聊天室 080豆豆聊天網 新豆豆聊天室 080聊天室 免費音樂試聽 流行音樂試聽 免費aa片試看 美女交友聊天室 色色網 聊天室交友 情人視訊網 0401成人交友 080哈拉聊天室 成人交友聊天室 嘟嘟成年人網 洪爺成人影片 嘟嘟成人網 免費視訊 免費視訊聊天
童裝批發
童裝
童裝
酒店喝酒
暑假打工
寒假打工
酒店
酒店經紀人
酒店現領
酒店經紀爆米花
酒店上班PRETTY GIRL
酒店小姐
酒店兼職
禮服店
酒店經紀
酒店兼差
酒店打工
酒店上班
假日打工
台北酒店經紀
童裝批發
Publicar un comentario en la entrada