Accesos rápido de teclado en Excel para Mac 2016

Por algún motivo que me encantaría entender, Microsoft, decidió cambiar radicalmente los accesos directos de Excel para Mac en su más reciente versión.

No puedo dejar de alabarla, es realmente mejor y se acerca muchísimo a la de Windows que siempre parecían muy distantes (no había prácticamente nada similar). Pero lo cierto es que uno termina acostumbrándose y estaría bueno – muy bueno – que nos dijeran cómo reemplazar los accesos rápidos viejos y cómo son estos nuevos. Bueno, no lo hicieron. :(

Afortunadamente una persona muy inteligente publicó estos cambios en otro blog (en inglés). Dejo este link acá por si alguna persona llega buscándolo.

 

Algunos experimentos con HMTL5

Si bien hace rato estamos cosechando los frutos de las novedades que llegan con HTML5 y CSS3; muchas de ellas, por falta de tiempo y dedicación, sólo podemos escuchar su nombre y dejarlas pasar.

Una de estas tecnologías es WebComponents. Realmente ese nombre es un paráguas para varias tecnologías relacionadas pero independientes:

  • Custom elements
  • Shadow DOM
  • Templates
  • Otras que no utilicé

Hace unos días meses decidí intentar hacer algo para, al menos, saborear su potencial.

El resultado fue este pequeño ejemplo que se puede ver en el siguiente GitHub:
https://github.com/soluciones3f/html5-webcomponents-experiments (también se puede ver online en http://codepen.io/fniwes/pen/eNqxPb pero por delays en cargar las imágenes puede no ejecutarse correctamente)

Repasemos cada una de las tecnologías y el como fue que me surgió el deseo de utilizar cada una de ellas, cuando intenté hacer una página simple, en la cual haciendo click sobre unas imágenes, estas se dieran vueltas como si fueran naipes.

Custom Elements

Yo soy un fanático del HTML Semántico y como tal, me disgusta el abuso de tags que no tienen un significado intrínseco como, como son los famosos DIV y SPAN.

Lamentablemente, cuando se quiere utilizar Javascript en algo no trivial, el uso de estos elementos, para demarcar fragmentos de un documento, o para crear elementos extras es inevitable.

En mi caso, necesitaba un elemento que representara cada una de las cartas de mi pequeño juego.

¿Que tag se puede utilizar en HTML para representar un naipe? La verdad es que no existe algo que signifique naipe, por lo que generalmente usaríamos un tag DIV y le daríamos un class para identificarlo como tal.

Pero yo no estaba conforme con eso. Quería un tag que significara Naipe. ¿Qué me impide tener un tag ?

Idealmente, además de tener un tag Naipe, sería grandioso que tuviera su propio comportamiento. En mi caso, el comportamiento sería rotar cuando le hacen click.

Bueno, para esto tenemos Custom Elements.

Hay mucho más que decir sobre este tema que lo que yo se, y lo que necesité para hacer este ejemplo. Pero básicamente, se registra el nombre del tag, se le asocia una clase (realmente un prototype) y en un método llamado createdCallback inicializo todo lo que necesito inicializar, y hago todos los bindings que necesite hacer.

Podemos ver en el ejemplo, que en ese momento lo que hago es escuchar el evento onClick sobre el elemento para llamar al método spin, y también importar en el HTML el resto del HTML necesario para generar el naipe utilizando ShadowDom y Templates.

Templates

Algo terrible cuando utilizamos Javascript y necesitamos generar HTML dinámicamente, es el tener que estar concatenando strings. No sólo el código se ve horrible, además perdemos la ayuda de los editores de texto, el colores de sintaxis y otras cosas más.

Un truco que se suele utilizar es crear un tag <script> con un type que lo identifique como cualquier cosa menos javascript, para que no sea ejecutado, y luego utilizar INNER HTML para obtener su contenido como un String, sin tener que usar concatenaciones.

Esto es algo que aprendí utilizando Handlebars pero que en mi fuero interno siempre odié, en parte porque no es semántico, y principalmente porque al hacer esto perdía el coloreo de sintaxis en mi editor de texto favorito.

En resumidas cuentas, Templates es una forma oficial de hacer lo mismo.

Shadow DOM

Desde mi punto de vista, de todas las tecnologías que utilicé en este ejemplo, ésta es la que más me voló la cabeza.

¡Shadow DOM nos permite tener un DOM dentro de otro DOM sin que interfieran!

El concepto es bastante simple, lo que se hace es crear, sobre un determinado punto del HTML un Shadow DOM, el cual se comporta como un nuevo documento, totalmente independiente.

Por ejemplo, si dentro del Shadow DOM creo un elemento con id=”foo”, cuando ejecuto document.getElementById(“foo”), el resultado será NADA, debido a que ese elemento no pertenece al DOM del documento principal, sino que corresponde al Shadow DOM.

En el ejemplo que hice, utilizo utilizo el atributo ID para ubicar determinadas partes del HTML de cada naipe. Sabemos que en un DOM no puede haber ID repetidos, pero entonces ¿cómo puedo tener varios naipes sin repetir ID? Respuesta: Como cada naipe está en un DOM independiente, dentro de cada uno el ID es único

Y esto no es todo, el sandbox del Shadow DOM no se limita únicamente al HTML, sinó también al CSS.

Si observamos el ejemplo, cada naipe (tile) es agregado con un pequeño bloque de estilos, cuyo objetivo es que todos los DIV tengan color rojo.

Pero, los DIVS que están en el documento principal, no aparecerán de color rojo, ya que el CSS pertenece a otro DOM solo afecta a ese.

Otras cosas muy interesante de Shadow DOM es que permite componer HTML. Esto es dentro de algún punto del HTML del Shadow DOM, el HTML del documento que está siendo tapado.

Recordemos que yo indico en que TAG del documento comienza se insertará el nuevo DOM, pero nada le impedía a ese tag tener su propio contenido, el cual será ocultado (a menos que el Shadow DOM indique donde debería mostrarse)

Esto ya es un tema más avanzado y merece su propio post al respecto.

Algunas notas finales

Para las animaciones utilicé la fabulosa librería GSAP. Hablar sobre ella le corresponde más a mis compañeros que la han usado mucho más que yo.

Un tema que me hubiera encantado hablar, pero no ya era mucho es sobre HTML Imports el cual nos permite disgregar un HTML en varios fragmentos.

Lamentablemente, al momento de escribir este ejemplo (no se si al momento de escribir el artículo, porque han pasado varios meses) Chrome Canary (otra forma de decir beta) era el único que lo soportaba y por default estaba desactivado tras un flag de la configuración.

Juegos que jugamos en 3f

Snow Bros de consolas

Snow Bros de arcade

El otro día una pareja de franceses pasó por la oficina para una entrevista y entre las preguntas que hicieron al equipo, hubo una que llamó mucho la anteción: ¿cuáles son los 5 juegos que considerás memorables?

Es interesante porque uno generalmente no piensa en una unidad concreta “emblemática”, sino que segmenta y agrupa por géneros, épocas, equipamiento. Acá hubo de todo un poco.

Nuestras respuestas fueron:

Pablo

  • Scorched Earth
  • Warcraft
  • Starcraft
  • Medal of Honor Allied Assault
  • Age of Empires

Facundo

  • Dungeon Siege
  • Unreal Tournament
  • Snow bros
  • Goonies
  • Under a Killing Moon

Fernando

  • Secreto de la isla de los monos (Monkey Island)
  • Prince of Persia
  • Morrowind
  • Mortal Kombat
  • Age of Empires

Francisco

  • Secreto de la isla de los monos (Monkey Island)
  • Wolf 3D
  • Quake
  • Green Fandango
  • Morrowind

Cómo cambiar el banner de Spring en aplicaciones de Grails 3

Una vez que logramos descubrir los secretos para que las aplicaciones de Grails 3 se puedan desplegar en un Tomcat sin problemas, veremos que cuando se inicializan aparece un lindo ascii art.

Springboot Banner

Si tenemos varias aplicaciones, todos los banners son iguales. Lo cual además de ser aburrido, no ayuda a identificar que aplicación se está ejecutando.

La documentación de Spring Boot nos da algo de información sobre cómo cambiar esta imagen en una aplicación Spring Boot. Esta documentación la pueden leer en el sitio de spring.io

¿Pero cómo hacemos en Grails? Simplemente creamos un archivo llamado banner.txt en la carpeta /src/main/resources

El contenido de ese archivo pasará a ser nuestro banner.

Interpolación de Strings en Groovy y Map con valores por Default

Todos los usuarios de Groovy o Grails saben lo bueno que es la interpolación de GStrings, la cual funciona tan bien que a veces nos olvidamos que no son Strings de java lo que estamos manejando.

Hoy me surgió el problema de leer un string desde un archivo y en ese string tener expresiones como ${myvar} las cuales debían ser resueltas utilizando un mapa con las claves y valores necesarios.

El primer problema era como procesar ese string como si fuera un GString, buscando en Internet hay varias formas de hacerlo, la más simple que encontré o se me ocurrió es utilizar el llamado SimpleTemplateEngine de Groovy.

import groovy.text.SimpleTemplateEngine

def stringTemplate = 'Hola ${nombre} ${apellido}'
def variables = [nombre: 'Fernando', apellido: 'Niwes']

def simpleTemplateEngine = new SimpleTemplateEngine()
def template = simpleTemplateEngine.createTemplate(stringTemplate)
def result = template.make(variables)

println result

Aunque en muchos casos esto es más que suficiente, yo tenia un requisito más: Cuando interpolaba el String podían faltarme algunas variables por ejemplo, que en el caso anterior el Hash no hubiera tenido el atributo “apellido”. En esa circunstancia quería que quedara como ${apellido}

El código tal cual está generaría una excepción. Específicamente un MissingPropertyException lo cual era inaceptable.

Además, por las peculiaridades del proyecto, yo no tenía idea de que variables se usarían en el String, por lo que no podía chequear o setearle un valor prefijado a los datos del Hash antes de invocar el método Make.

Hablando con mis compañeros se nos ocurrió resolver el problema usando propertyMissing pero incluso intentando de diferentes formas no logré encontrar la forma de que funcionara.

Luego, milagrosamente encontré una clase en el código fuente de Groovy llamada MapWithDefault que su descripción indica que es un Wrapper que permite a un mapa, retornar un valor por default cuando un dato no existe.

O sea, que había encontrado justo lo que necesitaba. Un poco más de información y un ejemplo de uso se puede ver en el sitio http://mrhaki.blogspot.com.ar/2010/07/groovy-goodness-map-with-default-values.html

Aplicando este nuevo conocimiento y el método de los Maps de groovy withDefault podemos lograr nuestro propósito de la siguiente manera.

import groovy.text.SimpleTemplateEngine

def stringTemplate = 'Hola ${nombre} ${apellido}'
def variables = [nombre: 'Fernando'].withDefault { name -> "\${${name}}" }

def simpleTemplateEngine = new SimpleTemplateEngine()
def template = simpleTemplateEngine.createTemplate(stringTemplate)
def result = template.make(variables)

println result

Noten en este ejemplo como, en el mapa he borrado el atributo apellido y además, llamo al método withDefault el cual si no encuentra un valor en el mapa, retorna el mismo nombre que estaba buscando, decorado con ${}

Espero me haya podido explicar correctamente, y que a alguien le sea de utilidad. En verdad fue un hallazgo que me facilitó mucho el trabajo.

Simular un Redirect con método POST

Tarde o temprano, cualquier desarrollador se encuentra con el deseo de poder realizar un Redirect a una página, pero pasarle parámetros por POST en lugar de hacerlo como si fuera un GET.

Lamentablemente esto es imposible, porque por su funcionamiento un Redirect a otra página siempre será un GET. La única forma de realizar un POST sin recurrir a Javascript es utilizando un formulario con un atributo method=”post”

Aunque no es posible hacer un redirect por post, con muy poco javascript es posible conseguir un resultado similar.

El truco es crear un formulario con method=”post” y cuyo action sea la url a la cual se quiere redirigir. Luego crear en el formulario los parámetros que se quieren pasar a la url como campos hidden para que no sean vistos (otra alternativa sería crearlos como text, y agregarle al formulario display=”none”, la idea es que el formulario no se vea)

Luego utilizamos un poco de Javascript, para que el formulario se envíe automáticamente, sin intervención alguna del usuario.

El resultado será que el explorador apuntará a la pagina destino, y se habrán enviado los parámetros deseados por POST. ¿Cual es la diferencia con un verdadero redirect? Por un lado que es un POST, y además que requiere una página intermedia que se encargue de armar un formulario y enviarlo.

Para demostrar esta idea creé en GitHub un simple proyecto en Grails que hace precisamente esto. Pueden ver el proyecto en https://github.com/soluciones3f/postredirect

Si este pequeño ejemplo te ayudó, o conoces otra forma de lograr esto, o encontraste un error, por favor dejanos un comentario.

Relaciones usando MongoDB GORM

Hoy me encontré con un nuevo desafío. Necesitaba hacer una consulta, considerando una tabla relacionada, teniendo configurado el plugin MongoDB GORM. Gran desafío, porque MongoDB no soportan JOINs, entonces, la implementación del plugin directamente las omite (cosa que pareciera ser el comportamiento clásico en este aspecto: si no se que es, en vez de disparar un error, directamente no lo tomo en cuenta).

En líneas generales, me han dado muchísimas satisfacciones los plugins de Grails. Este en particular está mantenido por uno de los desarrolladores principales de toda la arquitectura, así que menos todavía. Aunque en esta ocasión, mi problema era algo parecido a esto. Nota mental: siempre buscar información entre los bugs cuando tenemos un problema.

Resumiendo, lo encontrado fue:

  • Un lindo conjunto de recetas para usar GORM. Ver link.
  • Cuando se quiere obtener información relacionada, a pesar que lo lógico podría ser buscar a través de eq("parent.id", valor), en realidad hay que usar eq("parent") porque es así como lo resguarda en Mongo
    • Cuando se guarda la informacion en la base de datos, a diferencia de cuando usamos Hibernate, el campo no tiene el nombre parent_id ni tampoco se crea un mapa, como para que pueda ser obtenido como parent.id, sencillamente el nombre del campo en la base será equivalente al nombre del atributo en nuestro clase de dominio.
  • Cuando querramos obtener filtros usando tablas relacionadas, una forma es buscar los identificadores en las relacionadas y después, como tenemos una referencia en nuestra tabla, usar esos identificadores.

 

/**
 *  Los Ids son diferentes a los estándard, para mostrar que el ejemplo es versatil
 */
class Parent {
  Long id
  // Aquí puede haber información del tipo
  // miMapa = { id: 1, texto: 'xxyyzz', ...}
  Map miMapa 
  // .. 
  static hasMany = [child: Child]

}

class Child {
  String id
  // ..
  static belongsTo = [parent: Parent]
}

/**
 * Nuestro objetivo es buscar los Childs, 
 * cuyo padre tengan la propiedad parent.miMapa.id = id
 * (esto se resolvería muy fácil con un JOIN de SQL, pero en NoSQL no tenemos esa opción)
 * child.parent.miMapa.id == 1 --> debería estar en los resultados
 * child.parent.miMapa.id != 1 --> **NO** debería estar en los resultados
 */

def id = 123 // id que voy a buscar

def parents = Parent.createCriteria().list {
  eq("miMapa.id", id)
}
def parents_ids = parents.id

def resultados = Child.createCriteria().list {
  inList("parent", parents_ids)
}

resultados.each() { it ->
  assert(it.parent.miMapa.id == id)
}

Si alguien tuvo ese problema, aquí tienen una solución “saludable”. :)

Los watch (obervables) en AngularJS

Quizás todos saben ya que estoy convirtiéndome en un fan de AngularJS. ¿Por qué? Supongo que porque me resulta una forma útil de programar del lado del cliente sin tener que volverme loco para integrar montones de tecnologías.

En esta ocasión me parece meritorio comentarles sobre el manejo de los $watch y $watchCollection que nos permiten escuchar los cambios en el modelo a diferentes niveles. A saber:

  • watch(,,false) o watch(,): percibe el cambio entre algún valor del $scope
  • watchCollection: percibe el cambio en la cantidad de contenidos de una Array, dentro del $scope
  • watch(,,true): percibe el cambio en cualquier valor dentro del árbol de la variable de scope analizada
    • es la version más costosa, porque recorre todos los valores del contenido observado, permitiendo saber si hubo el más mínimo cambio. Hay que tener mucha precaución antes de usarlo

Me robé una imagen de acá http://teropa.info/blog/2014/01/26/the-three-watch-depths-of-angularjs.html como para ilustrar los casos posibles. Ideal para quienes preferimos no leer mucho.

angular_watch_depths

 

También, me encontré con algunas ayudas sobre cómo verificar que estos $watch no se ejecuten más de una vez. Haciendo una validación previa.

if (newValue !== oldValue) {
    // hacer lo que tengamos que hacer
}

Ver más datos aquí.

Y un muchacho que se tomó el trabajo de hacer un lindo post sobre el tema aquí.

Accediendo a información del Scope de AngularJS desde la consola en Chrome

Ya hace varios meses venimos trabajando con AngularJS, el framework JavaScript super heróico. :)

Algún día juntaré fuerzas para comentar mis impresiones, pero primero necesitaría entenderlo con mayor profundidad cosa que al día de hoy no he logrado completamente. Así que voy a concentrarme, esta vez, en sacar a relucir una característica que me pareció interesante a la hora de hacer testing y aprender a usarlo.

Básicamente, cuando se trabaja con AngularJS, se usa muchísimo algo conocido como $scope que vendría a ser un contender de atributos para cierta sección. Un formulario está dentro de un scope, cada item de una lista tendrá definido un scope propio, de hecho, cada componente HTML define un scope. Podríamos decir que es el canal de comunicación que se usa dentro de toda aplicación AngularJS.

Mi sorpresa vino cuando, buscando sobre cómo leer ese contenedor de información desde la consola de Chrome, me encontré con esta explicación y todo cobró vida. Básicamente lo que proponen hacer es:

1. Abrir la consola ([cmd] + [alt] + i)

2. Usar la lupa para indicar el contendor donde esté la información scope a la que querramos acceder

3. Tipear

angular.element($0).scope()

Y podremos ver la cantidad de información que nos muestra el Chrome. Ideal para hacer debug! :)

Bundle Transformer para ASP.NET MVC y sucedaños

Recién hablábamos en la oficina sobre los JS minimificados.

Me vino a la cabeza el Bundle Transformer. Un framework copado que intenta evolucionar el bundle que viene con MVC4 que, aunque está bueno, está a años luz de otras alternativas en tecnologías Web como Rails o Grails.

Hace algún tiempo, para Tonojogo, habíamos investigado alguna herramienta potente que permitiera programar en coffee y además tuviera más flexibilidad. Resulta que la que usábamos compilaba los coffee por cada request de lo usuarios y, llegado el caso de muchos usuarios simultaneos, terminaría siendo extremadamente pesada.

Bundle Transformer es un framework de NuGet para .NET que precompila los archivos y deja todo de una forma que, después de un primer uso, es cuestión de transferir los archivos de recursos generados, sin requerir uso del procesador. Permitiéndole al servidor ocuparse de servir a los usuarios.

Además, como unifica muchos recursos en pocos archivos, el tiempo de descarga se vería mejorado.