Una estrategia simple para traducir rutas en Ruby on Rails

Las calles de Guatapé, Antioquia, Colombia

Photo by Daniel Vargas on Unsplash

Hace poco empecé un nuevo proyecto personal. Se trata de un listado de trabajos remotos en tecnología. Admito que no es la idea más novedosa que hay, pero no he visto un tablero enfocado en el mercado Colombiano o latino que haya encontrado tracción. Así que decidí hacer el intento y lanzarla yo mismo.

Escogí Rails ya que me siento bastante cómodo con el framework y estaba seguro que la integración con ActiveStorage para archivos adjuntos y ActionText para el editor de texto me ahorrarían una buena parte del trabajo.

Parte de mi hipótesis por la que no existe un buen tablero de trabajos remotos en Latam (a parte de lo complicadísimos que son los sitios existentes) es que están 100% en inglés. Por lo tanto quería que esta app estuviera completamente en español. Si bien Rails tiene un módulo de i18n, siento que está más enfocado en la traducción de textos, sin embargo deja por fuera una parte clave de una app web, la URL.

Adicionalmente, mi objetivo no es tener una aplicación internacionalizada para incluir otros lenguajes a futuro, simplemente quiero que todo lo que esté de cara al usuario esté en español.

Históricamente, he tratado la traducción de URLs en rails de las siguientes formas:

Para este proyecto, ninguna de estas opcionese parecía ideal. Pensé que debía existir una forma más sencilla de lograr traducir URLs. Después de todo, Rails es reconocido por ser un framework modular y flexible (a pesar de que algunas personas no estarían de acuerdo con esta afirmación, en el fondo lo es).

Resulta que existe una forma más sencilla y siempre estuvo al frente mio. Se trataba de mirar un poco más de cerca la forma en la que rails maneja la definición de rutas. Al definir un recurso con la directiva resource, esta recibe ciertos kwargs o keyword arguments. Uno de ellos es el argumento path que nos permite cambiar el prefijo de la ruta según'lo descrito en la documentación. En un caso hipotético para un recurso jobs podríamos hacer lo siguiente:

resources :jobs, path: 'trabajos'
# Generates the following routes:
# jobs GET /trabajos(.:format)
# POST /trabajos(.:format)
# new_job GET /trabajos/new(.:format)
# edit_job GET /trabajos/:id/edit(.:format)
# job GET /trabajos/:id(.:format)
# PATCH /trabajos/:id(.:format)
# PUT /trabajos/:id(.:format)
# DELETE /trabajos/:id(.:format)

Excelente, por un lado tenemos nuestras rutas de cara a los usuarios en español (en su mayoría) y por otro podemos mantener las referencias internas al código consistentes en inglés.

No obstante, aún nos falta una parte para tener las rutas completamente traducidas. new y edit todavía están en inglés. Esto lo podemos solucionar fácilmente gracias al argumento path_name:

resources :jobs, path: 'trabajos', path_names: {new: "nuevo", edit: "editar"}

Yendo un paso más allá, podemos aplicar path_names a todo un scope, evitando que tengamos que repetirlo en cada ruta que defina la aplicación.

scope(:path_names => { :new => 'nuevo', :edit => 'editar' }) do
resources :jobs, path: 'trabajos'
resources :tags, path: 'etiquetas'
end
# new_job GET /trabajos/nuevo(.:format)
# edit_job GET /trabajos/:id/editar(.:format)

¡Y eso es todo! ahora todas las URLs están en el lenguaje que deseamos sin incluir dependencias extenas complejas, sacrificar la legibilidad de nuestro código o perder unos hipotéticos puntos de SEO.

Espero que este ejemplo haya servido para ilustrar como una solución simple muchas veces puede ser suficiente y recordarnos que a veces debemos mirar dentro de las posibilidades que ofrecen las herramientas que usamos, un lugar de mirar hacia afuera e incluir dependencias que cubren más casos de usos de los que necesitamos.