Publicidad:
Terra
La Coctelera

Mis Tags > codigo

Hay 13 artículos con el tag codigo.

Otros artículos en La Coctelera
clasificados con codigo

Frontend de andar por casa

Me encanta dar cursitos. En realidad me gusta todo lo que implique hablar e intercambiar opiniones.

Hace unos meses tuve la suerte de dar un cursete para un pequeño puñado de almas pacientes. Todo empezó con un mensaje de Raul Murciano en la lista de madrid-rb y de ahí salió una propuesta de temario sobre temas variados de front dirigido a desarrolladores y preparados para degustar en una tarde de viernes y una mañana de sábado.

En resumen, me lo pasé genial, y encima ellos me trataron como un rey.

Como todo el mundo sabía algo de html (algunos sabían mucho) la idea era reforzar conceptos, jugar con ejemplos y aprender truquitos para usar todos los días.

Al terminar el curso quedamos en que les enviaría material, pero la verdad es que había preparado una presentación con tan poquito texto que enviar un pdf con notas y unos ejemplos se me quedaba muuuy cortito.

Tras darle un par de vueltas la docu del curso ha quedado tal que así, y por aquí queda por si alguien más puede sacarle partido.

Poniendo bonito un input file

Revisando los diseños de formularios que últimamente pasan por mis manos no está de más revisitar las técnicas que nos permiten "poner bonito un input file".

Las más populares son la clásic de shaun inman, y una elaborada por Michael McGrady (según PPK). Por mi parte estoy mucho más de acuerdo esta última, aunque creo que si la vamos a usar varias veces en un proyecto necesitamos que sea un poquito más flexible.

He escrito un plugin pequeñito que hace el trabajo sucio y nos permite centrarnos en estilizar el input file falso y no en todo lo demás. Depende de jquery porque la mayoría del tiempo trabajo con este framework, pero sería fácil dejarlo limpio de dependencias.

Por el momento funciona, echadle un vistazo a la demo :)

El código fuente lo podéis encontrar en su correspondiente repositorio en github..

Vago-receta: validado masivo de tu html

Composición:

Esta vago-receta necesita de un poquito de preparación. Debemos de instalar la gema w3c_validators. Una vez hecho eso necesitaremos copiar este cachito de código en un archivo Rakefile en la raiz de donde tengamos nuestras maquetas. Si ya tenemos un Rakefile sólo añadiremos la tarea:

 # # Massive html validation task
 # 
 # This rake task comes from the nanoc validation task (http://gist.github.com/8961)
 # Copy this Rakefile to the root of your htmls or add the task to your existing Rakefile 
 # and run:
 # 
 #   rake validate
 # 
 # and that's all :)
 
 task :validate do
 
   require 'w3c_validators'
   include W3CValidators
 
   desc "W3C validation of all the files of the current folder"
   task :validate do
     validate '.html'
     # add validate '.theextensionofyourhtml' to extend this task
   end
 
 
   private
   
   # Colorize your output :) 
   def colorize(text, color_code); "#{color_code}#{text}\e[0m"; end
   def red(text); colorize(text, "\e[31m"); end
   def green(text); colorize(text, "\e[32m"); end
 
   # Validation calling to the w3c_validators methods
   def validate ext
     @validator = (ext == ".css" ? CSSValidator.new : MarkupValidator.new )
 
     files(".", true, ext).each do |file|
       results = @validator.validate_file(file)
       if results.errors.length > 0
           results.errors.each do |err|
             puts "** #{file} => #{red(err)}"
           end
         else
           puts "** #{file} => #{green('Valid!')}"
         end
     end
 
   end
   
   # Stoled from nanoc :) (but with a lot of love)
   def files(dir, recursively, ext = '')
     glob = File.join([dir] + (recursively ? [ "**", "*#{ext}" ] : [ "*#{ext}" ]))
     Dir[glob].reject { |f| File.directory?(f) or f =~ /(~|\.orig|\.rej|\.bak)$/ }
   end
 end
 
  

La última versión y correcciones estarán siempre en este gist.

Si la extensión de los archivos a validar no es .html, no dude en variar la línea de la tarea donde se especifica la extensión o añada tantas líneas como sea necesario (esssto hay que mejorarlo)

Esta vago-receta no usa nanoc ni nada por el estilo. La podemos usar en cualquier carpeta llena de archivitos html.

Indicaciones:

Se indica su uso especialmente en todos aquellos casos en el que necesitemos validar el código y tengamos más de 3 htmls :)

Especialmente recomendable cuando más de un zángano guarrea sobre el código.

Posología:

Vaya hasta la carpeta raiz de su proyecto en un terminal y escriba rake validate tantas veces como sea deseable y usted obtendrá un ouput coloreadito super majo.

Cada validación tarda casi nada, pero cuando hay un buen puñado de htmls necesitamos un poquito de paciencia. Aunque bien mirado siempre es mejor que ir uno por uno.

Contraindicaciones y sobredosis:

Validar constantemente puede convertirte en un pequeño psicópata, úsalo con mesura ;)

Otras presentaciones:

Añadiendo en la tarea un validate ".css" conseguimos validar nuestros estilos. Funciona pero en hojas de estilo enormes saca cositas un poco raras.

El día a día con nanoc

Hace bastante tiempo intentamos usar nanoc para maquetar proyectos más o menos grandes. Era una versión muy decente, pero que necesitaba madurar. Al mismo tiempo exploramos algún otro mini framework similar como staticmatic, pero estaba todavía menos cocido.

Desde la versión 2 de nanoc el framework se ha convertido en algo bastante sólido, pero además es open souce, es extensible, el código está documentadísimo y su uso también. Si hace mucho que lo probaste tal vez deberías darle una segunda oportunidad.

Vaaale

Está claro, hay métodos más sencillos de hacer html, y que requieren menos conocimientos técnicos, quién no se acuerda de home site.

Tampoco hace falta ser ingeniero aeronáutico para manejar esto. Con tener ruby y rubygems es suficiente para instalarlo y comenzar a trabajar, y hasta ahí llegamos todos.

"Envíeme las maquetas a..."

El clásico include de php nos permite reutilizar gran parte de nuestro código, incluso introducir lógica en nuestra maquetación, nada nuevo. Pero si el sistema nos obliga a tener configurado un host o no funciona si no es bajo un servidor con unas características determinadas (más o menos comunes, eso da igual) sólo nos sirve a nosotros y a nuestro entorno de trabajo cercano.

Con nanoc tenemos las mismas ventajas pero su output es siempre html independiente del framework, de manera que podemos enviar el directorio de salida a cualquiera y lo podrá ver sin obligarle a configurarse nada, como en los viejos tiempos :)

Si son 4 comandos!

Tanto keko como Jose han hablado ya de las maravillas del tutorial de nanoc2 que escribe y actualiza el gran Ale y que nació del tallercito de maquetación ágil que vivimos hace ya casi un año.

No te voy a contar nada que no puedas ver en el tutorial de Ale o en la documentación oficial, de hecho sólo estoy rascando la superficie un poquito.

  • nanoc create_site nombredelsite para crear un proyecto nuevo. Tienes muchísimas posibles combinaciones, pero los valores por defecto nos permiten trabajar estupendamente.
  • nanoc create_layout nombredellayout. Hay un layout por defecto con el que puedes trabajar. Aquí el concepto de layout es también el de partial. Puedes incluir un layout que contenga, por ejemplo, la cabecera de nuestro site en el layout por defeto llamándolo <%= render 'cabecera' %>.
  • nanoc create_page nombredelapagina para crear las páginas. Cada página tiene un yaml en el que le podemos definir filtros, variables a usar...
  • nanoc compile hace lo necesario para juntar layout, páginas, lógica, etc... y meterlo en la carpeta de salida que hayamos definido.

Para no tener que estar compilando el proyecto a cada cambio (sí, yo también soy de los que cambia dos divs y tiene que recargar la página) existe el comando nanoc autocompile, que nos lanza un servidor, por defecto en el puerto 3000, y cada vez que entramos a http://0.0.0.0:3000/nombredelapagina recompila esa página. Este comando no funciona bien en windows al menos en esta versión, puedes ver el html generado, pero muestra las imágenes como corruptas.

Vamos, que son 4 comandos! A cambio tenemos un proyecto mucho más sostenible y hemos reducido al mínimo el impacto de los cambios sobre la maqueta.

Hay varios comandos más, pero con estos ya podrías crearte un site majísimo. ¿Merecería la pena construir una aplicación de ejemplo complejita por entregas?

Big, bigger, biggest

Lo mejor de todo es que podemos dejar nanoc como está e ir extendiendo nuestra aplicación. Lo podemos hacer a base de plugins, que son archivos .rb situados en el directorio lib o bien con rake tasks, en el directorio tasks.

Así que el límite está en tu imaginación, en tu dominio de ruby y tu experiencia con rake.

Por poner un ejemplo. Sería maravilloso que en un proyecto enorme, antes de entregar, tuviésemos una manera de validar de golpe todas las maquetas (y bola extra css).

Lo más fácil sería crear una tareita rake que analizase nuestro output por nosotros. Si copias este validate.rake (*) en tu directorio tasks podrías ir a la raiz de tu proyecto y correr rake validate. En un momentito tooooodo validado :)

(*) en el momento que escribo esto el gist de la tarea rake está fallando, así que puedes verlo aquí.

Esta y otras tareas y plugins las trataremos de colgar (y mantener) en nuestro gist, por si encontráis alguna cosilla que os resulte útil.

Si todavía tienes dudas instálalo, trastea un poquito con cosas nada comprometidas y si no encuentras respuesta a tus dudas siempre puedes unirte a la lista de nanoc en castellano.

Youtube, dame el flv!! (con ruby)

Actualización: Esta técnica ya no funciona, tal vez me anime a actualizarlo. Mientras tanto puedes destripar acts as unvlogable :)


Hola de nuevo! Vuelvo a la carga tras mi temporada de barbecho digital bloguero en la que he hecho en the cocktail cosas tan divertidas y bonitas como la web de mtv españa. Qué voy a decir yo que no haya dicho álvaro.

Ahora a divertirme. Jugando con la api de youtube vemos que podemos conseguir lo básico para poder tirar de su información con nuestra aplicación. Tenemos una gema que nos hace la vida más fácil.

Lo único que no nos devuelve la api de youtube directamente es la url del flv que va a cargar su player. No es que nos valga para muchas cosas, pero en casos concretos nos puede interesar (nah, nada de detalles).

Pongamos el caso de la url este video. La anatomía de la url (http://www.youtube.com/watch?v=0xaX7ZfX054) nos da la id del video, y incluso sin tirar de la gema sabremos que la url del player es http://www.youtube.com/v/0xaX7ZfX054.

La url directa al flv no es tan intuitiva de construir.

http://www.youtube.com/get_video.php?video_id=la sabemos&t=token de youtube a averiguar

Así que con un poquito de ruby (y definiendo un método string.to_hash):

Así con una simple llamada a get_flv('http://www.youtube.com/v/0xaX7ZfX054') nos devolverá la url al flv.

A disfrutar!

Mi buen amigo Sergio me sugiere una revisión del post anterior complicando un poquito más el baremo.

El nivel de desconexión en este caso se mediría tomando como base no el número de posts, sino el funcionamiento de bloglines:

Bloglines guarda un máximo de 200 items por feed (esto no lo he podido confirmar, pero seguro que googleando un poquito sale). Por tanto 200 x número de feed a los que estás suscrito => 100%. Así que sólo tenemos que compararlo con los items que nos faltan por leer, y el resultado será nuestro nivel de desconexión.

Esto se complica un poquito (por no decir bastante), más que nada porque la api de bloglines no nos deja sacar así por las buenas el número de feeds al que estamos suscritos, nos los devuelve en un opml monísimo, pero poco práctico para lo que nos hace falta. Para hacer eso nos pide que además de nuestro email de suscripción le demos nuestra contraseña (pero bueno, todo sea por saber cuanto estamos de desconectados).

Así que variaciones las variaciones con respecto al script anterior son:

  • Necesitamos el email y el password para poder pasar.
  • Tenemos que parsear el ompl que nos devuelva el listsubs.

De este modo nos quedaría una acción tal como esta:

     def desconector2
       
       begin
         bloglines = Bloglines::WebServices.new(:user => params[:username], :password => params[:password])    
         content = bloglines.listsubs
     
         @subscripciones = 0
         # parseamos el xml de subscripciones
         REXML::XPath.match(content, '//outline').each do |item|
           if item.has_attributes?
             @subscripciones = @subscripciones+1 if !item.attributes['xmlUrl'].nil?
           end
         end
     
         @maximo = @subscripciones*200
     
         @post_pendientes = bloglines.update
         desconexion = (@post_pendientes*100)/@maximo
         @resultado = "Estoy al #{desconexion.to_s}% de desconexion"
       rescue Exception => e
     
         @resultado =  e 
     
       end
         
     end
 

Para que hagais vuestras pruebas correspondientes he metido en mi routes.rb

     map.connect 'desconector/:username/:password', :controller => "bloglines", :action => 'desconector2'
 

Así que para probar podeis ir a http://mamuso.net/desconector/tuemail/tucontraseña.

Como se que no andan los tiempos como para ir dejando por ahí contraseñas en texto plano, debemos de buscar una alternativa. Otra forma de obtener el opml propio es a través de la página pública de blogroll. De esta manera los únicos datos que necesitaríamos serían nuestro email de suscripción y nuestro nombre de usuario para la página pública. Si no sabes cual es entra en la opción share de tu bloglines.

Por tanto unas leves modificaciones y… hecho:

 def desconector3
   begin
   
     bloglines = Bloglines::WebServices.new(:user => params[:username])    
     
     @subscripciones = 0
     # parseamos el xml de subscripciones
 
     url= "http://www.bloglines.com/export?id=#{params[:screenname]}"
     xmldata = Net::HTTP.getresponse(URI.parse(url)).body
     doc = REXML::Document.new(xmldata)
     
     REXML::XPath.match(doc, '//outline').each do |item|
       if item.hasattributes?
         @subscripciones = @subscripciones+1 if !item.attributes['xmlUrl'].nil?
       end
     end
 
     @maximo = @subscripciones200
 
     @post_pendientes = bloglines.update
     desconexion = (@post_pendientes100)/@maximo
     @resultado = "Estoy al #{desconexion.to_s}% de desconexion"
   rescue Exception => e
 
     @resultado =  e 
 
   end
     
 end
 

En el routes.rb:

     map.connect 'desconectorb/:username/:screenname', :controller => "bloglines", :action => 'desconector3'
 

De manera que podéis probar con http://mamuso.net/desconectorb/tuemail/tunombredeusuario.

Este baremo tampoco es perfecto, porque yo tengo feeds que no actualizan nada desde junio, por tanto si tienes muchos blogs de este tipo, tu nivel de desconexión será ‘irrealmente bajo’, además si estás suscrito a muchísimos blogs raramente pasarás del 5-10% con más de 2000 items sin leer. A lo mejor podríamos combinarlo con el nivel de desconexión que tienen nuestros suministradores de feeds hacia nosotros (uuuuh, esto se complica brothers!).

Como veis el fin de semana ha sido largo y aburrido. ¿Pensabais que este post era interminable? Yo también :D

Hoy es día de trastear con APIs, y he pensado que podía retomar una vieja idea de furilo(tm) y jugar un poco con la de bloglines.

Se trata de mostrar tu nivel de desconexión con la realidad en base a los posts que te quedan por leer en bloglines y aplicar un baremo. Ya que hemos empezado con el post de furilo, pues tomaremos la proporción que él planteaba: 787 items pendientes = 65% de desconexión, por lo que 1210 serían el 100%.

Podríamos hacerlo sin instalar absolutamente nada, simplemente deberíamos de tratar lo que devuelve el rpc, pero para facilitar el trabajo usaremos la gema Bloglines4R 0.1.0, que tiene poquitos métodos pero los suficientes para hacer lo que queremos. De hecho es una de las cosas más básicas que se pueden hacer.

  • Conseguimos los posts pendientes de leer
  • Operamos para obtener el porcentaje de desconexión
  • Et voilà
 class BloglinesController < ApplicationController
 
   require 'bloglines'
 
   def desconector
     
     maximo = 1210
     
     begin
       
       bloglines = Bloglines::WebServices.new(:user => params[:id])
       post_pendientes = bloglines.update
       desconexion = (post_pendientes*100)/maximo
       @resultado = "Estoy al #{desconexion.to_s}% de desconexion"
     
     rescue Exception => e
       
       @resultado =  e 
     
     end
   
   end
 
 end
 

El manejo de excepciones en este caso no es más que recoger si el usuario existe o no (ni lo traduzco en este caso)

Podéis probarlo aquí mismo entrando a http://mamuso.net/bloglines/desconector/tuemail@debloglines.com. Si funciona a la velocidad de la tortuga coja es porque dreamhost es lento hasta decir basta (pero barato, eso sí).

Un host en condiciones, unos test (que el personal se me echa encima si no), un formateo en javascript para poder incrustarlo en cualquier blog de forma fácil, y servicio hecho :)

Yo estoy varios días desatendiendo mi bloglines así que según el script Estoy al 218% de desconexion. Así que voy a ponerme al día ya!

Estoy enamorado de los observers. Son muy básicos, casi de 'primero de rails', pero la verdad es que evitan muchísimo trabajo y son ante todo muy DRY.

En rails el observer es una clase más de ActiveRecord. El concepto no es nada novedoso: es un trigger que actúa cuando el objeto al que vigilamos cambia, a modo de callback. Sus usos son variados, pero me quedo con dos muy típicos pero muy útiles.

Por ejemplo, enviar un correo informativo cuando el estado de una solicitud ha cambiado, sacado de la misma página de rails.

   class SolicitudObserver < ActiveRecord::Observer
     def after_save(solicitud)
       Notifications.deliver_status("admin@do.com", "Se ha cambiado el estado de la solicitud", status)
     end
   end
 

Y el que más me gusta: hacer el trabajo sucio una sola vez. Ampliando el ejemplo anterior, imaginemos que hay que desencadenar varios cambios cada vez que uno hace un cambio en esa solicitud, o simplemente que tenemos un modelo desnormalizado de datos que nos obliga a mantener una tabla cada vez que algo cambia (y además nos manda el mail :) ). Pues nada más fácil.

   class SolicitudObserver < ActiveRecord::Observer
     def after_save(solicitud)
       addons = SolicitudAddons.find(solicitud.id)
       addons.updated = Time.now
       addons.status = solicitud.status
       addons.otrapropiedad = loquesea
       addons.save
 
       Notifications.deliver_status("admin@do.com", "Se ha cambiado el estado de la solicitud", status)
     end
   end
 

Así no tendremos que pensar que en cada acción que modifique el modelo de solicitudes hay que cambiar datos en otras tablas.

Se que es una chorradilla, pero me parece fascinante poder desencadenar esas cascadas solo con un pequeño cambio :)