Variable not found
Caching de bundles en MVC 4 (o MVC 3, o Webforms…)
Abril 11th, 2012
Hace unos meses ya estuvimos comentando el interesante paquete System.Web.Optimizations que se distribuía con la developer preview de MVC 4, aunque también decíamos que este paquete era igualmente descargable a través de Nuget, y esto hacía posible su uso con MVC 3 o incluso con WebForms.
Como vimos en su momento, su uso era bastante sencillo. En resumidas cuentas, si no queríamos complicarnos demasiado la vida, era suficiente con introducir el siguiente código en la inicialización de la página (en el Application_Start del Global.asax):
BundleTable.Bundles.RegisterTemplateBundles();
(Bueno, en la preview el método a llamar era EnableDefaultBundles(), pero el resultado era el mismo)Simplemente con ello, ya podíamos acceder a dos recursos que eran generados automáticamente por el sistema:
- /scripts/js, que contiene un único archivo .js con todos los scripts existentes en la carpeta /scripts del proyecto, convenientemente minimizados.
- /content/css, donde encontramos en un único archivo todos los .css presentes en /content, también minimizados para aligerar su descarga.
- /content/themes/base/css, nuevo en la última versión del componente, que incluye los estilos relativos al tema básico de jQuery UI, utilizado en la plantilla del proyectos de MVC 4.
Con la beta de MVC 4 recientemente liberada, este componente ha incluido también un interesante sistema de cacheo que hace aún más eficiente y automático su uso. Si observamos el layout de la plantilla de proyectos ASP.NET MVC 4 veremos que incluye las siguientes líneas:
<link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/css")"
rel="stylesheet" type="text/css" />
<link href="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/themes/base/css")"
rel="stylesheet" type="text/css" />
<script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")">
</script>
Observad que las referencias a los distintos recursos se generan a través del método ResolveBundleUrl(). Pues bien, el código generado por las líneas anteriores es, más o menos así de sorprendente:<link href="/Content/css?v=oI5uNwN5NWmYrn8EXEybCIbINNBbTM_DnIdXDUL5RwE1" rel="stylesheet" type="text/css" /> <link href="/Content/themes/base/css?v=UM624qf1uFt8dYtiIV9PCmYhsyeewBIwY4Ob0i8OdW81" rel="stylesheet" type="text/css" /> <script src="/Scripts/js?v=GP89PKpk2iEmdQxZTRyBnKWSLjO7XdNG4QC1rv6LPxw1"></script>En las referencias se está añadiendo un parámetro que contiene un valor hash correspondiente al contenido de la carpeta empaquetada en el momento de generación de la vista. La primera petición que se realice enviará de vuelta los recursos empaquetados y minimizados con una validez a nivel de caché de un año; las siguientes peticiones, por tanto, se resolverán muy rápidamente mediante un HTTP 304 (No modificado):

A partir de ahí, cualquier cambio que se realice en alguno de los archivos o directorios incluidos en los bundles provocará un cambio de hash, por lo que la petición será diferente y, por tanto, el resultado no se tomará desde la caché.
Publicado en: Variable not found.
» Leer más, comentarios, etc...
Escuela De Codigo
Twitter Boostrap Alerts en Ruby on Rails
Abril 11th, 2012
Los alerts en el ahora famoso framework de Twitter Boostrap, no son mas que cuadros de colores para mostrar al usuario un mensaje y a la vez llamar su atención, todos los hemos usado alguna vez,un mensaje en un cuadro rojo para cuando hay algún tipo de error, uno verde para cuando todo ha ido bien, uno amarrillo para un warning y un azul para algo meramente informativo.
Actualmente trabajo en una aplicación en Rails, en la que quiero hacer uso de los alerts para mostrar al usuario unos llamativos mensajes, lo que he hecho para lograrlo ha sido sencillo, si te interesa saberlo no dejes de leer.
Primeramente cree un partial como el que se muestra a continuación
#app/views/shared/_messages.html.erb
<% flash.each do |key, value| %>
<%= content_tag(:div, value, :class => "flash alert alert-#{key}") %>
<% end %>
Y luego para utilizarlo solo lo agrego a la vista que lo necesite, de la siguiente forma:
<%= render :partial => "shared/messages", :locals => { :flash => flash } %>
Claro todo esto seria inútil si en mis controladores no hiciera un adecuado uso de flash, para crear los mensajes que deseo mostrar
#para mostrar un alert tipo 'error' flash.now[:error] = "Errors" #tipo 'info' flash.now[:info] = "Informacion importante" #tipo 'success' flash.now[:success] = "Perfil actualizado exitosamente!" #tipo 'warning' flash.now[:warning] = "Precuacion!"
El resultado final:
Como puedes ver no ha sido para nada complicado, tomarse un par de minutos para embellecer la aplicación que estas desarrollando es algo que tus usuarios te agradecerán ;)
» Leer más, comentarios, etc...
Viricmind Labs
PHP, sesiones y alta concurrencia
Abril 9th, 2012
Hoy voy a escribir brevemente sobre cierta problemática asociada al manejo de sesiones en PHP que surge cuando nuestra aplicación web debe soportar un alto nivel de concurrencia.
PHP guarda las sesiones en archivos por defecto, aunque hay otros mecanismos posibles: por ejemplo usar bases de datos como MySQL (o bien SQLite), tirar de Memcache, guardar la información cifrada dentro de cookies, etc.
Ninguno de estos sistemas alternativos está exento de problemas. Las bases de datos al uso añaden una latencia inaceptable en la mayoría de casos, SQLite permite lecturas muy rápidas, pero como contrapartida bloquea la base de datos entera cuando se escribe, Memcache puede sobrecargar nuestra memoria y tiene el riesgo potencial de pérdida de datos por la volatilidad de su sistema de almacenaje, y por último, guardar las sesiones en cookies aumenta ligeramente el riesgo de robo de datos y puede añadir un overhead importante a todas las peticiones HTTP.
¿Y qué pasa con las sesiones en ficheros? Pues también tienen su problemática. Cada petición HTTP llega acompañada de la cookie con el ID de sesión, cuando se llama al método session_start se abre un descriptor de fichero que guarda la información asociada a la sesión con el ID ya mencionado y... se bloquea el archivo para poder escribir sobre él los cambios que hagamos en las variables de sesión sin que haya conflictos entre peticiones distintas que usan la misma sesión.
El bloqueo que menciono desaparece por defecto en cuanto finaliza la ejecución del script PHP. Esto significa que si en cierto sitio web realizamos (por ejemplo) 5 llamadas AJAX de forma paralela a scripts que hacen uso de la información de sesión, el resultado que obtendremos es una serie de respuestas serializadas en el tiempo, una detrás de otra.
Una solución parcial para conseguir aumentar el nivel de paralelización de las llamadas AJAX (o cualquier otro tipo de petición HTTP) es desbloquear el archivo de sesión lo antes posible, es decir, cuando sepamos que ya no vamos a modificar las variables de sesión y solo vamos a realizar operaciones de lectura. Para ello podemos usar la función session_write_close, en algunos casos se puede conseguir una reducción impresionante de los tiempos de carga, por lo que os recomiendo tenerlo muy en cuenta.
Otro detalle importante: es desaconsejable permitir que PHP inicie la sesión de forma automática (es preferible iniciarla solo cuando sea estrictamente necesario). Si podéis, intentad que la opción session.auto_start esté a false en el fichero de configuración php.ini.
Espero que os haya servido
.
» Leer más, comentarios, etc...
Picando Código
Apuntes Rails: Controladores
Abril 9th, 2012
Los controladores son el pegamento entre la lógica de negocios y las vistas en el patrón de diseño MVC – Model, View, Controller.
Cuando el ruteo de Rails determiná qué controlador va a usar para un pedido, nuestro controlador se va a encargar de darle sentido a este pedido y devolver una salida correspondiente.
Cada controlador es una clase Ruby que hereda de la clase de Rails ApplicationController.
Métodos y Acciones
El ruteo determina qué controlador y acción debe ejecutar. Rails crea una instancia del controlador y ejecuta el método con el mismo nombre de la acción correspondiente.
Parámetros
Desde el controlador podemos acceder a todos los parámetros enviados en el pedido HTTP. Los dos tipos de parámetros son:
- Query String Parameters – Los enviados a través de la URL (lo que está en la URL después del signo “?”).
- Post Data – Información de un pedido POST HTTP, generalmente enviado desde un form html.
Ambos tipos de parámetros están disponibles a través del hash params.
El hash params puede contener Arrays y Hashes:
GET /clients?ids[]=1&ids[]=2&ids[]=3
> params[:id] = ["1", "2", "3"]
<form method="post"> <input type="text" name="client[name]" value="Acme" /> <input type="text" name="client[phone]" value="8881234" /> </form>
> params[:client] {
"name" => "Acme",
"phone" => "8881234"
}El objeto params es de la clase HashWithIndifferentAccess de Active Support, una clase totalmente imprescindible cuya función es permitir escribit params[:key] y params['key'] y obtener el mismo valor por ambas claves…
Parámetros JSON y XML
Rails convierte automáticamente los parámetros JSON y XML al hash params.
Ejemplo JSON:
{ "company": { "name": "acme", "address": "Lo que sea" } } >params[:company] { :name => “acme”, “address” => “Lo que sea” }
Omitir elemento raíz de JSON/XML:
En initializers – config.wrap.parameters = on
En controlador – wrap_parameters
Ruteando parámetros
En el hash params siempre encontramos las llaves :controller y :action pero deberíamos acceder a ellos con :controller_name y :action_name.
match 'clients/:status' => 'cliens#index', :foo => "bar"
GET /clients/active > params[:status] = "active" params[:foo] = "bar"
Sesiones
Las aplicaciones web tienen una sesión por cada usuario en la que se pueden guardar pequeñas cantidades de información que será persistida entre pedidos.
La sesión está disponible únicamente en el Controlador y la Vista. Se puede usar uno de varios mecanismos:
- ActionDispatch::Session::cookieStore – Guarda todo del lado del cliente
- ActiveRecord::SessionStore – Guarda la información en la base de datos usando ActiveRecord
- ActionDispatch::Session::CacheStore – Guarda la información en la cache de Rails
- ActionDispatch::Session::MemCacheStore – Guarda la información en un clúster memcache (implementación legacy, usar CacheStore en su lugar)
Todos los mecanismos de guardado de sesión usan una cookie para guardar un ID único para cada sesión (obligatorio usar una cookie, Rails no permite pasar el id de sesión a través de la URL).
Cookie Store
Guarda el id y la información en la cookie. Todos los otros mecanismos guardan el id y la información se obtiene con ese id buscando en el servidor. Es muy lviano, no requiere configuración. La información de la cookie está firmada pero no encriptada, Rails no la aceptará si ha sido editada.
Permite 4Kb de información. No debería guardar objetos complejos (como instancias de modelos).
ActionDispatch::Session::CacheStore
Para casos en los que la sesión de usuario no necesita guardar información crítica o no se necesita por períodos largos de tiempo. Usa la implementación de caché de tu aplicación para guardar sesiones.
Ventaja: Usar estructura actual de caché.
Desventaja: las sesiones serán efímeras, podrían desaparecer.
Archivo:
config/initializers/session_store.rb
- Cambiar el mecanismo de almacenamiento de sesión.
- Establecer la llave de sesión (nombre de la cookie)
- Pasar una llave de dominio para especificar el nombre de dominio para la cookie
Establecer una clave secreta para el firmado de la información de sesión – config/initializers/secret_token.rb
Accediendo a la sesión
En los Controladores se puede acceder a la sesión a través de metódos de instancia de sesión.
Los valores de la sesión se guardan usando pares clave valor como en un hash.
En el controlador:
def current_user @current_user ||= session[:current_user_id] && User.find_by_id(session[:current_user_id] end
Guardando valores:
def create if user = User.authenticate(params[:username], params[:password]) session[:current_user_id] = user.id redirect_to root_url end end
Para eliminar algo de la sesión, simplemente asignamos el valor nil a la clave. Para reiniciar toda la sesión, usamos el método reset_session.
Flash
El flash es una parte especial de la sesión que desaparece con cada request. Ejemplo:
def destroy session[:user_id] = nil flash[:notice] = "Has cerrado sesión" redirect...
También es posible asignar mensajes flash en redirecciones:
redirect_to root_url, :notice => "Has cerrado sesión correctamente"
flash.keep mantiene el valor para otro request.
flash.now Accede a los valores en el mismo request.
Cookies
Las cookies (o galletitas) son pequeñas cantidades de información del lado del cliente que es persistida a través de pedidos y sesiones.
cookies – Funciona como un hash:
cookies[:commenter_name] = @comment.name ... cookies.delete(:commenter_name)
Observar que para borrar el valor de una sesión, se asignaba nil a la clave. En el caso de las cookies, se debe usar cookies.delete(:llave)
Conclusión
Voy a dejar por acá este primer post sobre Controladores en Rails. Si les interesa ir siguiendo este tema, a esta altura deberían entender el flujo de un request en un controlador, y por qué y cómo guardar información en la sesión o con cookies.
Hay más para ver sobre los controladores: filtros, los objetos request y response y algo de seguridad básica. Pero lo dejo para la próxima entrega de “Apuntes Rails” ![]()
» Leer más, comentarios, etc...
Variable not found
Enlaces interesantes 77
Abril 9th, 2012
Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 2 al 9 de abril de 2012. Espero que os resulten interesantes :-)
.Net
- How to pad number with leading zero with C#
Jalpesh P. Vadgama - ¿Qué hay de malo en este código? (C#)
Eduard Tomás - .NET Versioning and Multi-Targeting - .NET 4.5 is an in-place upgrade to .NET 4.0
Scott Hanselman - A LINQ Style Range Generator
BlackWasp
Asp.net
- With HTTP, your application is your API
Hadi Hariri - Creación de una barra de progreso con SignalR
Dino Esposito - 67% of ASP.NET websites have serious configuration related security vulnerabilities
Troy Hunt - .NET 4.0 ASP.NET MVC 3 plug-in architecture with embedded views
Liviu Ignat - Creating a JSONP Formatter for ASP.NET Web API
Rick Strahl - Shhh… don’t let your response headers talk too loudly
Troy Hunt - Using SpecsFor.Mvc – Introduction
Matt Honeycutt - Configuring Bundles in MVC 4
Tom Dupont - JsAction: call MVC Action Methods from javascript
XVincentX - Infinite Scroll in ASP.NET MVC
Tomasz Pęczek - ASP.net MVC generic client and server side validation
DotNetStep
Data access
Html/Css/Javascript
- Drag and Drop and Automatically Send to the Server
Remy Sharp - 18 Most Popular jQuery Plugins of March 2012
More Tech Tips - Getting Cozy With Underscore.js
Nettuts - Knockout.js Performance Gotcha #1–if/with bindings are not always cheap
Ryan Niemeyer
Otros
- Nuevas obligaciones en relación a las cookies
Xavier Ribas (vía @jm_alarcon) - La fiebre del oro o cómo hacerte rico vendiendo picos y palas
José Manuel Alarcón
Publicado en Variable not found
» Leer más, comentarios, etc...
Koalite's blog
Echo de menos la BCL: formato y parsing de fechas en Javascript
Abril 9th, 2012
Hay cosas de Javascript que me enfadan a las que no estoy acostumbrado. Cosas que doy por sentadas en otras plataformas y que, cuando llego al mundo de Javascript, no existen. Al final todo se puede solucionar, pero no deja de resultarme incómodo en algunos momentos.
Conversiones de fechas a string y viceversa
Formatear fechas (y datos en general) en javascript no es fácil. Los métodos que existen por defecto están muy limitados, nada que ver con las variedad de formatos que encontramos en .NET, tanto predefinidos como personalizables.
La parte positiva es que es fácil encontrar librerías para ello, algunas muy ligeras, como date.format.js, y otras más completas, como datejs.
Al parsear strings para convertirlos en fechas tenemos un problema similar, que se hace especialmente patente al recibir datos serializados en JSON desde un servidor. No todos los navegadores soportan los mismos formatos a la hora de realizar la conversión.
Por ejemplo, Firefox y Chrome manejan sin problemas fechas en formato ISO 8601, tal y como define el estándar ECMAScript 5, pero Explorer 9 no es capaz de parsear la cadena si incluye la zona horaria y Safari ni siquiera sin la zona horaria es capaz de parsearla.
Al final no queda más remedio que cambiar la forma en que se envían las fechas en el servidor, lo que no siempre es posible, o realizar el parsing a mano en el cliente, cosa que es relativamente fácil si sabemos de antemano el formato a parsear, pero que no deja de ser un fastidio.
Y por otra parte está el tema de la globalización/localización, que es una bestia completamente distinta y que puede ser atacada con herramientas como el plugin Globalize para jquery.
Conclusión
Una cosa que me atrajo desde el primer momento de Javascript (y que pasa con otros lenguajes de filosofía similar) es que, a diferencia de .NET o Java, en lugar de tener un framework muy completo y pesado, existen multitud de pequeñas librerías especializadas que puedes componer cómo necesites, haciendo además que cada librería sea más fácil de entender y modificar por tratarse de unidades de menor tamaño.
Sin embargo, tengo que reconocer que a veces echo de menos el abrigo protector de la BCL de .NET con sus mil clases y utilidades para casi todo a las que recurrir sin tener que pasar un buen rato buscando en Google cual es la mejor forma de formatear una fecha.
Posts relacionados:
- Cosas que echo de menos en Javascript
- Mixins en Javascript
- Modificar una clase en Javascript: Eliminar los markers de Google Maps
» Leer más, comentarios, etc...
Escuela De Codigo
¿Aprender a programar? Buenos sitios web para lograrlo
Abril 9th, 2012
Es común que me lleguen mensajes (emails, mensajes privados en foros, twits, etc, etc.) donde me hacen una sencilla pero gran pregunta: ¿Donde aprendo a programar? Es una interrogante muy común entre los que recién empiezan o los que ya tienen un buen rato en la profesión de desarrolladores pero, quieren ampliar sus conocimientos o profesionalizar lo aprendido porque en muchos casos (como el mio) nuestra escuela únicamente ha sido Google, mucha paciencia para prueba/error y la mejor cualidad que una persona puede tener: ser autodidacta. Pero, nunca cae mal el conocer las mejores practicas y aprender los trucos de los mejores.
Asi que si te interesa conocer buenos sitios web y herramientas para aprender a programar como la providencia lo exige, te invito a que sigas leyendo.
Sin mayor preambulo a continuación el listado.
CodeAcademy
Si lo que quieres es aprender Javascript, HTML y ponerte a crear grandes aplicaciones web lo mas pronto posible, este sitio es recomendado para empezar, aplicando técnicas de Gamificacion se enseña de una manera divertida lo básico de los lenguajes preferidos de la web.
Como dicen en el sitio web
Codecademy es la forma más fácil de aprender a codificar. Es interactivo, divertido, y puedes hacerlo con tus amigos.
TryRuby
¿Has escuchado hablar de Ruby? ¿Te pica la curiosidad por probar este lenguaje? ¿Pero, te detiene el hecho de tener que instalar no sabes cuantas cosas en tu PC antes de ver las maravillas que puede ofrecerte? No hay problema!! Aqui tengo la solución para ese programador escéptico que no le gusta llenar su disco duro de vichos raros sin saber si de verdad vale la pena. TryRuby es para ti!! Prueba Ruby desde la seguridad de tu casa, desde un navegador web!!!
Solo sigue el enlace y te encontraras con un excelente tutorial que te mostrara las bondades de Ruby a la vez que te introduce en los conceptos basicos de programación.
Try Clojure
Al igual que TryRuby, un sitio web para aprender y probar un nuevo lenguaje desde la comodidad y seguridad de un navegador web, en esta ocasión el lenguaje elegido: Clojure.
Try Haskell
Y como dicen que lo bueno hay que imitarlo, tenemos un sitio web mas siguiendo la linea de TryRuby, esta vez para aprender e interactuar con Haskell sin necesidad de instalar nada.
Try Python
Y si pensaron que el afamado Python no tenia su propio sitio web “try”, se equivocaron, porque si lo tienen, un sitio web para aprender de una manera interactiva las maravillas de este gran lenguaje.
Code School
Sitio web al que este blog le debe el nombre
CodeSchool es una aplicación web en la que podemos aprender de las tecnologías que hoy por hoy son la base de la web: Javascript, Ruby, HTML, CSS, etc. Los cursos son excelentes, si quieren probarlo antes decidirse si pagar o no una membresia (si el sitio es de pago pero, la verdad por todo lo que ofrecen y la calidad del producto es algo que vale la pena invertir) les recomiendo el curso Rails for Zombies, para que se den una idea de como son los demas cursos.
Learn Python The Hard Way
Si una chica que no sabe como programar pudo aprender Python para darle una sospresa de San Valentin a su novio, no se uds pero, debe ser un buen sitio para aprender.
CSS3Please
Aprende las nuevas reglas de CSS3 modificandolas al vuelo a un elemento del sitio web. Cambia los valores a tu antojo y ve como funcionan inmediatamente.
Team TreeHouse
Al igual que CodeSchool este sitio es de pago pero, la calidad y cantidad de recursos valen la pena el precio, y no solo se limitan al aprendizaje de tecnologías exclusivamente web (javascript, html, etc, etc) sino que tambien se amplían en el desarrollo para dispositivos moviles (IOS).
Hackety Hack
Que no te engañen los dibujos infantiles, ni el gracioso nombre que pueda evocar una serie televisiva infantil que alguna vez pudiste haber visto. Hackety Hack es un sitio que te permite aprender a programar de manera fácil y sencilla, haciendo uso de un programa tutorial interactivo, que te guiara por las bondades del lenguaje Ruby a la vez que te enseña lo mas básico de la programación.
JavaPassion
En un principio, hace mucho mucho tiempo cuando Sun aun existía y el mundo Java no era vendido a Oracle, existía un sitio web lleno de recursos gratuitos para aprender Java de las manos de uno de los mejores, una vez Sun se vendió, algunas cosas cambiaron y una de ellas fue que el afamado sitio JavaPassion y sus cursos pasaron a ser accesibles mediante una previa suscripción, pero, quien los culpa, de alguna manera hay que llevar el pan a la boca ¿no?. Aun asi la calidad de los cursos disponibles no disminuyo y el sitio aun es un excelente lugar para iniciarse en el mundo Java.
¿Aun tienes excusas para no aprender a programar?
Espero que tu respuesta sea no.
¿Se me quedo algún sitio web? ¿Ustedes cual recomiendan?
» Leer más, comentarios, etc...
HardBit
Uso de la API REST de Windows Azure Service Management con NodeJS
Abril 7th, 2012
En esta entrada explico la manera de utilizar la API REST de Windows Azure Service Managment, para los que no conocen esta API es la que nos permite realizar ciertas operaciones sobre nuestras subscripción de Windows Azure como es administrar los siguientes elementos (Storage Accounts, Hosted Services, Certificates, Affinity Groups, Locations, Tracking Asynchronous Requests, Retrieving Operating System Information, Retrieving Subscription History)
Necesitamos autenticarnos para ejecutar las operaciones REST por lo que primero debemos crear un self-signed certificate y subirlo a nuestra cuenta de Windows Azure como lo muestra las siguiente imagen.

- Ya que tenemos nuestro archivo MyCertificate.cer lo vamos a convertir a un archivo .pem con la herramienta de OpenSSL con la siguiente instrucción openssl x509 -in MyCertificate.cer -inform DER -outform PEM -out MyCertificate.pem
- El siguiente paso es exportar nuestra llave privada a un archivo .pfx como lo muestra la siguiente imagen y una vez exportada nuestra llave la convertiremos con la siguiente instrucción openssl pkcs12 -in MyKey.pfx -out MyKey.pem -nodes



» Leer más, comentarios, etc...
Picando Código
Gira Mozilla MDN Hack Day – Argentina, Uruguay, Brazil y Chile
Abril 6th, 2012
La gira de Mozilla Developer Network (MDN) se nos acerca ![]()
Estoy muy contento de poder comentar que la gente de Mozilla visitará nuestras ciudades de Buenos Aires, Montevideo, São Paulo y Santiago difundiendo su mensaje: La Web es la plataforma. Sí, Mozilla, los creadores de nuestros amados Firefox, Thunderbird y responsables de gran parte de la evolución de la web en los últimos años, se van a dar una vuelta por acá.
Les dejo una traducción del anuncio publicado en el blog de Mozilla Hacks por Havi Hoffman:
La gira MDN de primavera continua con un viaje al otoño en el Conosur – la región más sureña de Sudamérica. Nos dirigimos al sur para participar de MozCamp, una reunión de la comunidad Mozilla Hispano, y para conocer desarrolladores en Buenos Aires, Argentina; Montevideo, Uruguay; São Paulo, Brasil; y Santiago, Chile. Presentaremos algunos nuevos proyectos emocionantes de Mozilla como Boot-to-Gecko (B2G), Apps, Persona, y WebFWD y mostraremos algo de nuestro trabajo en herramientas para desarrolladores, Firefox y el SDK de Add-ons. Nos gustaría pasar tiempo programando con desarrolladores web y compartiendo la vision de Mozilla de la Web abierta y centrada en el usuario.
Nuestro mensaje: La Web es la plataforma y está construída de tecnologías abiertas. Aprende cómo puedes colaborar con MDN en documentación agnóstica de navegador para la Web como un todo, o contribuir a la misión Mozilla e iniciativas Open Source a través de código y evangelización. Hay muchas, muchas formas de involucrarse.
Si eres un desarrollador, diseñador, escritor de documentación, tecnologista, emprendedor, o entusiasta del open source en Buenos Aires, Montevideo, São Paulo o Santiago, estas invitado a registrate, pasar y compartir lo que estás trabajando. Si simplemente tienes curiosidad de conocer Mozillianos o quieres aprender más sobre nuestro trabajo, nos encantaría conocerte. Nunca olvides que la Web está hecha de todos, para todos (original en español).
Buenos Aires
Viernes, 20 de Abril: En Buenos Aires, nos hemos aliado con Mozilla Hispano, el grupo de Hacks/Hackers de Buenos Aires y Blue Via para un evento de un día el Viernes 20 de abril en el hotel NH City & Tower en el corazón de la ciudad. Abriremos con charlas cortas sobre HTML5 y amigos, APIs Javascript, el SDK de Add-ons, herramientas de desarrolladores, y nuestras ofertas más nuevas: Apps y Persona.
El registro para el MDN Hack Day, Bs As 2012 está abierto y todavía tenemos espacio. Por favor regístrate aquí.
Montevideo, Uruguay
Martes, 24 de Abril: Damos puntapié inicial a nuestra gira torbellino de 3 ciudades del sur en 5 días, con una noche de desarrolladores en la capital de Uruguay, Montevideo. Estamos agradecidos por la amable hospitalidad de la gente de La Diaria, un periódico de noticias innovador con una fuerte presencia web y un lugar maravilloso y popular en la comunidad de tecnología y negocios de Uruguay. También un gran agradecimiento al equipo de Cubox, una tienda de desarrollo de software que mira hacia el futuro, y está “disponible para la genialidad”, y han estado definitivamente geniales y disponibles en guiarnos a los Norteamericanos en cómo armar una noche de desarrolladores desde la lejana Mountain View, a más de 10 mil kilómetros de distancia. Se unen al equipo de MDN para hablar en Montevideo: Dan Mills (@thunder), líder de producto para Persona; Shane Caraveo (@mixedpuppy) de Mozilla Labs; y Andrés Leonardo Martínez Ortíz de BlueVia, un sponsor del MDN Hack Day Tour en Montevideo y Santiago, así como Buenos Aires. Vamanos!
Ya está abierto el registro para el Montevideo MDN Hack Day Developer Evening.
São Paulo, Brasil
Jueves, 26 de Abril: Robert Nyman (@robertnyman), evangelista técnico de Mozilla de Suecia (¡no Suiza!) visitará São Paulo, Brasil para representar al MDN en un evento nocturno organizado por el miembro de la comunidad Mozilla, desarrollador de software de Caelum y todo terreno Paulo Silveira (@paulo_caelum) el jueves 26 de abril. La charla de Robert se titula “JavaScript APIs – The web is the platform” y describirá cómo HTML5, Boot-toGecko, y otros nuevos APIs inspiran una nueva era de desarrollo innovador en la Web abierta. Muchas gracias a Paulo y el equipo de Caelum por ser anfitriones del evento en su auditorio, y hacer que Robert se sienta bienvenido en São Paulo.
El registro está abierto para el São Paulo MDN Hack Day Developer Evening, organizado por Caelum.
Santiago, Chile
Sábado, 28 de Abril: Cerramos la la gira MDN Hack Day del Conosur el sábado de tarde con una noche de desarrolladores en Santiago, Chile, alojada y organizada por Jano Gonzáles (@janogonzales) en la Escuela de Economía y Negocios – Universidad de Chile. Esta vez se nos unirá Hernán Colmeiro (@peregrinogris), interno de Firefox y evangelista de Jetpack; así como Shane Caraveo, Robert Nyman y como siempre el único Shezmeen Prasad, quien se asegura que todo esté perfecto.
El registro está abierto para la Santiago MDN Hack Day Developer Evening.
Créditos de la foto: Look, a mouse pointer on the screen!
(Jeff Griffiths Presents..)
Hagamos sentir bienvenidos a los Mozillianos del Norte durante su estadía por nuestro barrio, y aprovechemos esta oportunidad para aprender, conectarnos y dar a conocer el talento que tenemos por acá. ¡Nos vemos ahí!
» Leer más, comentarios, etc...
Fetishcode
ADF Mobile
Abril 6th, 2012
A
» Leer más, comentarios, etc...
Fetishcode
ADF Customer Success Stories
Abril 6th, 2012
A
» Leer más, comentarios, etc...
Picando Código
Apuntes Rails
Abril 6th, 2012
He estado estudiando bastante de las Rails Guides últimamente. Mi kit de estudio sigue siendo tan primitivo como cuando iba al liceo: un cuaderno de papel y una lapicera, además del material de estudio (en este caso Internet).
Estoy abierto a sugerencias de métodos más modernos. Debería probar sacar apuntes en un editor de texto directamente en la computadora, pero evitando la tentación de copiar y pegar texto…
El tema es que pienso compartir mis apuntes por acá. La idea es que al tener que pasar esos apuntes a un post prolijo en el blog, no solo vuelvo a estudiar sino que quede explicado de la mejor manera posible. Así, no solo comparto el conocimiento, sino que lo afirmo en mi cabeza. También queda abierta la discusión sobre los temas estudiados en los comentarios. Por último, es un registro para cuando quiera repasar algún concepto ya adquirido.
Ya había leído varias partes de la guía Rails hace un buen tiempo, pero siempre a modo de “hobby” (lo que venía siendo Ruby para mí hasta que me puse en serio con eso). Así que arranqué de cero con el objetivo de leer toda la guía (requisito también en mi trabajo).
La guía asume un poco de conocimiento de Ruby, y algunos requisitos de software en nuestra computadora que no voy a comentar por acá. Tampoco voy a seguir un orden exacto, hay cosas que se pueden ir leyendo independientemente de otras. Pero cualquier duda la pueden dejar en los comentarios que con gusto intentaré contestar.
Introducción a Rails
La guía contempla la versión 3.2.3 de Rails. Para dejar una “definición” de lo que es Rails, tiro un apunte:
Rails es un framework de desarrollo de aplicaciones web.
En teoría sigue el patrón de diseño MVC, pero he oído fundamentos para creer que no es tan así (otro tema…). En fin, sigamos asumiendo que es así. El patrón MVC consta básicamente de:
Modelo – La representación de la información, los datos. Define las reglas para manipular la información (lógica de negocios).
Vista – Anoté “UI”, o interfaz de usuario. Es cómo vamos a mostrar la información
Controladores – El pegamento entre los modelos y las vistas. Procesa los requests entrantes en la aplicación. Interroga a los modelos para obtener información y le pasa datos a la vista.
Es un patrón de uso bastante común en otras tecnologías y lenguajes, así que asumo que la mayoría de las personas que hayan trabajado en proyectos web lo conocen. Y si no es así, tienen un concepto para ir conociendo ![]()
Componentes de Rails
Rails tiene muchos componentes internos encargados de cada aspecto de la aplicación web. Es bueno tener una idea de qué hace cada uno, aunque en su momento la guía profundiza según tema.
- Action Pack – Gema que contiene:
- Action Controller – Procesa los requests, extrae los parámetros, despacha a acciones. Servicios que provee: manejo de sesión, renderización de plantillas, gestión de redireccionamiento.
- Action View – Puede crear HTML y XML por defecto, gestiona renderización de plantillas, AJAX incluido.
- Action Dispatch – Maneja el ruteo de los pedidos web.
- Action Mailer – Servicios de correo electrónico.
- Active Model – Interfaz entre Action Pack y el ORM.
- Active Record – Base para los modelos en Rails. Provee:
- Independencia de la base de datos.
- Funcionalidad CRUD.
- Capacidades avanzadas para buscar.
- Relaciones entre modelos.
- Active Resource – Conexión entre los objetos de negocio y servicios web que siguen los principios REST. Mapea recursos basados en web a objetos locales con semántica CRUD.
- Active Support – Clases utilitarias y extensiones a bibliotecas estándard Ruby.
- Railties – Código central de Rails que construye nuevas aplicaciones y junta todos los frameworks y plugins.
REST
Para comprender Rails (y básicamente tener una idea de cómo se desarrolla para web actualmente), hay que tener un concepto de REST – Representational State Transfer (Transferencia de Estado Representacional). Es una forma de construir software, y pueden leer más en Wikipedia.
Pero a modo de resumen, Rails nos dice esto:
- Usar identificadores de recursos como URL para representar recursos.
- Transferir representaciones del estado de ese recurso entre componentes de sistema.
Por ejemplo el siguiente request HTTP:
DELETE /books/14
Es un recurso de libro con el id 14, y la acción borrar.
Aplicación Rails
No voy a pasar por el proceso de crear una primera aplicación. Lo mejor para esto es abrir la Guía de Rails y empezar a crear una aplicación por cuenta propia siguiendo los pasos y aplicando los conocimientos.
Cierro el post con un poco de música. Un tema de Rancid del discazo “And Out Come The Wolves”:
Rancid – RUBY Soho
En próximos posts seguiré digiriendo y publicando apuntes de otras partes de la guía Rails.
» Leer más, comentarios, etc...
Picando Código
Trine 2 disponible para Linux
Abril 5th, 2012
Hace unos días Phoronix anunció la disponibilidad del cliente para GNU/Linux del juego Trine 2. Sin embargo, Frozenbyte el estudio encargado de su desarrollo no había hecho ningún anuncio. En su sitio web no encontrábamos noticias al respecto.
De todas formas, si entrábamos al sitio oficial de Trine 2 para comprarlo, un widget nos mostraba la posibilidad de comprarlo con unos íconos de Apple y Tux. El widget pertenece a la Humble Store, en versión beta, un sistema de compra de juegos de Humble Bundle. Explicado todo esto, les comento que hace un par de días pude comprar Trine 2 para GNU/Linux. Y luego fue anunciado oficialmente en el blog de la empresa.
Comenté sobre Trine cuando hablé de Frozenbyte el año pasado. El juego se puso para pre-venta en octubre, y se prometió una versión para GNU/Linux para este año.
Sobre Trine 2
Es un juego de plataformas, acción y puzzles. Podemos jugar con uno de tres personajes con distintas características cada uno: Amadeus el mago, con la habilidad de materializar objetos sólidos de la nada y el poder de levitar objetos. Pontius el caballero, el guerrero, equipado con un escudo capaz de manipular su entorno físico, espada y martillo. Zoya la ladrona, armada de arco y flecha y un gancho que le permite escalar y alcanzar lugares de altura.
Al tener habilidades tan distintas, los personajes nos permiten alcanzar ciertos lugares o vencer ciertos enemigos de maneras distintas. El juego cuenta con muchos puzzles basados en física, teniendo que manipular fuego, agua, magia y la gravedad para alcanzar distintos objetivos.
Esta secuela trae un nuevo modo cooperativo disponible online o local. También podemos salvar la partida en cualquier momento. También incluye muchos ítems coleccionables escondidos y los populares “Achievements” o logros para aumentar el valor de volver a jugarlo.
Los gráficos están mejorados ampliamente, y ya tuve algún encuentro con nuevos puzzles sumamente interesantes. Es accesible para todo tipo de jugadores, y está disponible en muchas plataformas: Playstation 3, Xbox 360, Mac, Linux y Windows. Su precio es de U$S 14.99 y U$S 24.99 la edición para coleccionistas que incluye el artbook y soundtrack.
El video presentación:
Les recomiendo adquirir el juego, y quedo a la espera para alguna partida cooperativa con otro(s) jugador(es) ![]()
» Leer más, comentarios, etc...
Ingenieria de Software / Software Engineering / Project Management / Business Process Management
Requirements Webinar Karl Wiegers
Abril 5th, 2012
No hay que dejar pasar la oportunidad de tomar este webinar tanto por el expositor como por el precio (es gratuito)
» Leer más, comentarios, etc...
Picando Código
Necesito un título para este post
Abril 3rd, 2012
Como comentaba en Nuevo Camino, hace un mes empecé a trabajar en Cubox. Esto me llevó a tener que aprender muchas cosas nuevas, encontrarme con una forma y ambiente de trabajo totalmente distinto, etc.
Por esto, podría decir que estoy aprendiendo cosas nuevas prácticamente todo el tiempo. Además, tengo mucho por estudiar y aprender todavía para acercarme al nivel del resto del equipo.
Creo que para un programador trabajar con gente que sabe mucho más que uno es ideal: tenemos de quién aprender. A su vez, estar en una situación desafiante a nivel técnico resulta inspirador (al menos en mi caso).
Hacía tiempo que no me llevaba un problema a casa en la cabeza, y lo resolvía al día siguiente tras haberlo masticado. Al no estar en la zona de confort, me siento en una mejora constante como desarrollador (inspirado en la filosofía Kanban aprendida a través de Scrum).
En fin, todo esto viene a que tengo ganas de “volver a las raíces” con el blog. En un principio el blog era un reflejo de lo que iba progresando y trabajando en programación. Cuando conocía algo nuevo (por muy básico o simple que resultara) lo dejaba publicado acá para tener como referencia en el futuro. En verdad siempre intenté seguir esa tendencia, pero a veces la rutina, y la falta de desafíos en el trabajo me volvió apático. Si bien siempre buscaba algo interesante para publicar, no era lo mismo.
A partir de ahora, voy a intentar volver a la tendencia de publicar siempre los nuevos conocimientos que vaya adquiriendo. Estoy estudiando y viendo mucho sobre Ruby y Rails particularmente. Pero también metodologías, buenas prácticas, y demás. Capaz que publico cosas bastante básicas como cosas super específicas sobre cómo resolver un problema o simplemente ideas. Esto me va a ayudar a fijar los conocimientos, compartirlos con otra gente, y de repente recibir información relevante de gente con más experiencia. Cumplir el objetivo por el que me hice un blog en primer lugar digamos ![]()
Una de las primeras cosas que tengo que terminar es de estudiar por completo Rails. Ya estoy trabajando en un proyecto hecho en Rails, así que me estoy dando un poco la cabeza contra la pared. Pero cada golpe es un aprendizaje. Así que seguramente vaya publicando mis apuntes sobre lo que vaya leyendo de Rails.
No tengo pensado mantener una periodicidad específica, pero voy a intentar postear siempre que encuentre algo útil y me pueda servir para más adelante.
» Leer más, comentarios, etc...
Picando Código
Invitación a Reunión del Grupo de usuarios Ruby
Abril 3rd, 2012
Estimados lectores, por la presente extiendo a ustedes la invitación a la reunión mensual del grupo Ruby Uruguay.
La invitación está abierta a desarrolladores de todo tipo, NO ES NECESARIO QUE SEPAN RUBY.
La idea es juntarse a conversar y conocerse, hablar sobre las cosas que anda haciendo cada uno -tanto Ruby como tecnologías asociadas- y tomar algo. El grupo pienza empezar a reunirse los segundos martes de cada mes.
Así que si saben Ruby, si no saben pero les interesa conocer más, si tienen conocimientos para compartir, o simplemente quieren conocer gente en el ambiente del desarrollo web local, acérquense a la reunión ![]()
Fecha:
Martes 10 de Abril – 19:30 horas
Lugar:
CoworkingMVD (via Cubox)
Bulevar España 2529, esquina Libertad (mapa)
Visiten el sitio del grupo Ruby, y anótense para el evento si quieren asistir:
Si alguien tiene alguna charla para dar, está bueno, y si no se dará un ambiente de conversación nomás para saber en qué anda cada uno, y cómo aprender más de ruby y las tecnologías en las que trabajamos (o tenemos ganas de trabajar).
Por favor confirmen asistencia en meetup.com así podemos hacer estimaciones de cuántos seremos.
¡Nos vemos ahí!
» Leer más, comentarios, etc...
Arragonán
Nuevo producto: Minchador, sistema de reservas para restaurantes
Abril 3rd, 2012
Algunos ya lo sabéis. Aunque no le haya dado mucho bombo, no es ningún secreto que estoy trabajando en sacar un producto propio. Y a raíz de ello he pensado darle un poco más de vida al blog escribiendo sobre esta nueva aventurilla; principalmente porque me obligará a ordenar mis pensamientos, a hacer retrospectiva de aciertos y errores, vete a saber si también a alguien le puede servir de algún modo de aprendizaje (aunque las hostias propias enseñan más y mejor)… y si alguien me da algún tipo de feedback, ya perfecto
.
El producto en cuestión se llama minchador. Y es una idea muy sencilla y poco original: un sistema de reservas para restaurantes.
Sí, sé que existe competencia, incluso creo que han habido proyectos/empresas con ideas muy similares que han cerrado… como en cualquier otro sector, supongo. Por supuesto que no se puede entrar a competir con proyectos con muchos más recursos con sus mismas armas, como pueden ser los directorios de restaurantes.com, eltenedor, pidemesa… que con mucha más financiación que la que yo puedo tener, parecen estar en una lucha por captar mucho tráfico, hacer más fuerza comercial llamando a restaurantes y hacer desarrollos más completos (¿complejos?).
Con este panorama (y que mi financiación es entre escasa e inexistente), está claro que hay que enfocarlo desde ya en aportar valor como para que clientes paguen por ello y salir a vender. Y no es por ir del palo Lean, buzzword con tanto hype en los últimos tiempos, es por pura necesidad.
La intención es que sea un producto diferenciado, a grandes rasgos y por orden de prioridad (totalmente subjetivo, por supuesto):
- Simplicidad de uso tanto para los restaurantes como para sus clientes.
- Widgets webs de los restaurantes y aplicación para páginas de facebook.
- API para integraciones propias y de terceros.
Ahora mismo, son las 3 cosas en las que estoy trabajando, teniendo en cuenta también como se va a comercializar. Como podéis ver, pretende ser un servicio casi invisible para los clientes finales, y para los restaurantes un canal nuevo por el que recibir reservas, tratando de ser lo menos intrusivo posible a sus procesos actuales de gestión de reservas.
Por eso más a futuras me planteo cosas como desarrollar plugins para CMSs y demás hierbas, integraciones con servicios externos, posibilidad de crear webs tipo marca blanca para los restaurantes…
Hasta el momento tan sólo existe online una landing para registrarse a la beta, hecha con launchrock y una (mala) foto mía de una cena en un japonés hace la tira de tiempo; ya que por no tener, todavía no tengo logo, pero está de camino
.
Espero en un par de semanas tener una landing en condiciones y empezar la beta cerrada trabajando con muy pocos restaurantes, y poder ver así si el producto está correctamente enfocado o hay que cambiar ciertas cosas.
Por otro lado espero poder terminar de afinar el pricing (ya adelanto que, salvo giro inesperado, se cobrará por reserva) y empezar a hablar con algunos posibles distribuidores, porque ambas cosas están totalmente relacionadas.
Y cuando tenga estas dos cosas más cerradas, también escribiré sobre ello, por supuesto!
» Leer más, comentarios, etc...
Picando Código
Rails: ActsAsList – Herramienta para manipular posición de objetos en una lista
Abril 3rd, 2012
Una gema de Rails que tuve que usar recientemente es ActsAsList. Esta extensión de Rails provee la capacidad de clasificar y ordenar objetos en una lista.La clase con esta necesidad específica debe tener una columna position (posición) definida como Integer en la tabla de base de datos mapeada.
Es bastante sencilla de usar, pueden agregar a su Gemfile la gema:
gem 'acts_as_list'Voy a mostrar un ejemplo bastante sencillo en Rails a efectos de explicar el concepto. Tenemos una aplicación Rails con dos modelos: Book y Bookshelf. Generamos los modelos correspondientes:
$ rails generate model Bookshelf name:string
$ rails generate model Book title:string author:string description:text position:integer bookshelf:referencesY mandamos a generar las tablas:
$ rake db:migrateEditamos el código de app/models/bookshelf.rb para agregar el orden:
class Bookshelf < ActiveRecord::Base has_many :books, :order => 'position' end
Y el libro:
class Book < ActiveRecord::Base belongs_to :book_shelf acts_as_list :scope => :bookshelf end
Hecho esto ya estamos en condiciones de tener una Bookshelf con una colección de libros, y manipular el orden de los libros dentro de esta colección a través del índice “position”. Podemos probar el código en la consola de Rails con:
$ rails consoleEmpezamos por crear un bookshelf para guardar nuestros libros:
bookshelf = Bookshelf.new(:name => "My bookshelf")
Hecho esto, creamos algunos libros asignándoles nuestro objeto bookshelf:
> book1 = Book.new(:title => "1984", :author => "George Orwell", :description => "Dystopian future", :bookshelf => bookshelf) > book2 = Book.new(:title => "A princess of Mars", :author => "Edgar Rice Burroughs", :description => "John Carter is in this book", :bookshelf => bookshelf) > book3 = Book.new(:title => "Ready Player One", :author => "Ernest Cline", :description => "Online virtual world / videogame", :bookshelf => bookshelf) > book4 = Book.new(:title => "Foundation", :author => "Isac Aasimov", :description => "Blow-your-mind-Sci-fi", :bookshelf => bookshelf)
Ya armada la estructura y guardada podemos ver que los libros tienen su posición según fueron siendo guardados:
> bookshelf.books Book Load (0.3ms) SELECT "books".* FROM "books" WHERE "books"."bookshelf_id" = 1 ORDER BY position => [#, #, #, #]
El cuarto libro por ejemplo, podemos moverlo a la primera posición, y tras recargar los objetos, vemos que automáticamente los demás libros sumarán una posición más:
> book4.position => 4 > book4.move_to_top #Mover a la primera posición (0.1ms) begin transaction SQL (0.3ms) UPDATE "books" SET position = (position + 1) WHERE ("books"."bookshelf_id" = 1 AND position < 4) (0.3ms) UPDATE "books" SET "position" = 1, "updated_at" = '2012-04-03 02:47:55.303110' WHERE "books"."id" = 4 (105.5ms) commit transaction => true > book4.position => 1
Podemos comprobar las posiciones de los demás libros:
book1.position => 2 > book2.position => 3
Y mover un libro al final de la lista:
> book2.move_to_bottom (0.1ms) begin transaction SQL (0.3ms) UPDATE "books" SET position = (position - 1) WHERE ("books"."bookshelf_id" = 1 AND position > 3) Book Load (0.3ms) SELECT "books".* FROM "books" WHERE ("books"."bookshelf_id" = 1 AND id != 2) ORDER BY position DESC LIMIT 1 (0.3ms) UPDATE "books" SET "position" = 4, "updated_at" = '2012-04-03 02:50:13.740681' WHERE "books"."id" = 2 (107.7ms) commit transaction => true > book2 = Book.find 2 Book Load (0.2ms) SELECT "books".* FROM "books" WHERE "books"."id" = ? LIMIT 1 [["id", 2]] => #> book2.position => 4
Y la posición final de todos los libros quedó:
> bookshelf.books Book Load (0.3ms) SELECT "books".* FROM "books" WHERE "books"."bookshelf_id" = 1 ORDER BY position => [#, #, #, #]
Una herramienta bastante útil con otros métodos como move_higher, move_lower, y más que pueden leer en el código fuente. Si quieren leer más al respecto visiten acts_as_list.
» Leer más, comentarios, etc...
Variable not found
Enlaces interesantes 76
Abril 2nd, 2012
Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 26 de marzo al 1 de abril de 2012. Espero que os resulten interesantes :-)
.Net
- C#/.NET Little Wonders: Skip() and Take()
James Michael Hare - IQueryable is Tight Coupling
Mark Seeman - Ref and Out (The Inside Story)
Akhil Mittal - C# Value Type Table
Mark Treadwell - Identifying .NET 4.0 Special Folders
Richard Carr - Null is not false
Eric Lippert - C# and VB.NET language specification
Salvo Davide Rapisarda - Do I need to dispose of Tasks?
Stephen Toub - Should I expose asynchronous wrappers for synchronous methods?
Stephen Toub
Asp.net
- Combining LESS with ASP.NET
Malcolm Sheridan - How to fork the ASP.NET Web Stack to GitHub
Jimmy Bogard - Some points to consider while working on ASP.NET MVC and jQuery
Rahul Bandopadhyaya - ASP.NET MVC 4, ASP.NET Web API and ASP.NET Web Pages v2 (Razor) now all open source with contributions
Scott Hanselman - ASP.NET MVC, Web API, Razor and Open Source
Scott Guthrie - Creating Absolute Urls Of Controller Actions In ASP.NET MVC
Mohamed Meligy - How to build a grid with knockout and ASP.Net MVC
David Carter - Tutorial Asp.net Web API con MongoDB – Parte 2.2
Gonzalo Pérez - Securing your ASP.NET MVC 4 App and the new AllowAnonymous Attribute
Rick Anderson - Bringing oData to your WebAPI – just use IQueryable
John V. Petersen
Azure / Cloud
- Ejemplo de NodeJS, Express y Azure en el codemotion
David Salgado
Data access
- EF DateTime2 y el índice perdido
Unai Zorrilla - SQLinq: Use LINQ to generate Ad-Hoc, strongly typed SQL queries
Chris Pietschmann
Html/Css/Javascript
- 10 Tips for Developing Better jQuery Plugins
Craig Buckler - 10 Most Exciting jQuery Plugins of Early 2012
jQuery4u - Providing Synchronous / Asynchronous Flexibility With jQuery.when
Derick Bailey - Using Modernizr to detect HTML5 features and provide fallbacks
Tom Leadbetter - Minimum Paragraph Widths in Fluid Layouts
Gustav Andersson - Saving the values of dynamically populated dropdown on back button
Mark Needham - JavaScript design patterns – Part 1: Singleton, composite, and façade
Joseph Zimmerman - For Modernizr, Don’t Stop with NuGet
Steve Albers - Responsive Content Navigator with CSS3
Mary Lou - Readable DOM Ready Event Handlers
K. Scott Allen
Visual Studio/Complementos
- My Top 5 Visual Studio 11 Designer Improvements for ASP.NET 4.5 Development
Carl Bergenhem - Make IIS Express the Default for VS2010 Web Projects
Steve Smith
Otros
- ¡campusMVP en inglés!
José Manuel Alarcón
Publicado en Variable not found
» Leer más, comentarios, etc...
Koalite's blog
Acceso a recursos externos con PhoneGap/Cordova
Abril 2nd, 2012
En mi último post hablaba de las distintas técnicas que existen para hacer peticiones a otros dominios desde una página web y decía que era importante tenerlo en cuenta cuando desarrollamos una aplicación con PhoneGap/Cordova porque todas las peticiones que realicemos a servidores externos serán consideradas cross-domain.
Tras jugar un poco con Cordova e investigar un poco en internet (todavía no hay demasiada documentación sobre esto y la que hay es poco clara), lo que he visto en que en Cordova todo el acceso a recursos externos es muy dependiente de la plataforma que estemos usando (iOS, android, WP7, etc.) e incluso de la versión de la plataforma.
Hay que tener en cuenta que Cordova depende por completo de los componentes que ofrezca cada plataforma para incrustar un navegador web en una aplicación nativa. En el caso de Android es a través de un WebView, en iOS es un UIWebView, etc.
Cada plataforma permite hacer más o menos cosas desde su WebView y, aunque Cordova trata de unificar el comportamiento, digamos que todavía está la cosa un poco verde.
Lo único que tengo a mano para probar es un teléfono con android 2.3.4, así que lo que voy a contar se refiere a mis pruebas con él. Si repites las mismas pruebas con otro cacharro, puede que los resultados no sean los mismos.
OJO: Cuando hablo en este contexto de acceso a recursos externos me refiero no sólo a realizar invocaciones a servidores remotos usando AJAX, sino también a cargar páginas que estén alojadas en otro servidor.
El primer requisito para que una aplicación de Cordova en android pueda acceder a recursos remotos es solicitar el permiso de acceso a internet en el manifiesto de la aplicación:
En el teléfono con el que he hecho las pruebas, que como comentaba antes lleva android 2.3.4, esto ha sido lo único que he necesitado para poder conectarme a servidores externos.
Parece ser que no siempre es tan sencillo y para esos casos no está de más conocer otra parte de Cordova que incluye en el acceso a servidores externos: la whitelist.
Cordova permite mantener una lista de sitios “permitidos” a los que sí que se puede acceder desde nuestra aplicación. La gestión de esta lista se realiza de forma diferente dependiendo de la plataforma. En el caso de android, se hace mediante el fichero res/xml/cordova.xml. En este fichero podemos añadir tantos elementos access como queramos para permitir acceso a otros dominios:
Existe una última alternativa, en este caso para cargar páginas desde servidores externos, que es habilitar la opción loadInWebView, lo que se salta la validación de whitelist. Para esto hace falta modificar el Activity principal:
public class MyActivity extends DroidGap {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setBooleanProperty("loadInWebView", true);
super.loadUrl("http://dominio-externo.com/index.html");
}
}
Conclusiones
Se nota que el desarrollo de Cordova es muy activo y está muy vivo, porque todavía hay partes de las APIs y las especificaciones que son un poco confusas o inconsistentes. Ojo que no quiero decir con esto que no sea un framework listo para usar en producción, pero hay veces que las cosas no son tan claras como nos gustaría.
Posts relacionados:
» Leer más, comentarios, etc...
Principal
Frónesis: la clave de los nuevos líderes
Abril 1st, 2012
Frónesis es la característica principal de los nuevos líderes, según afirman los autores que hace 30 años nos enseñaron el concepto de agilidad como avance en campos de scrum: Nonaka y Takeuchi; que comparto y me gusta tanto o más como en su momento me gustó Scrum.
Si en su artículo de entonces "The New New product development game" conceptualizaron los principios de scrum como un ecosistema para trabajo en equipo basado en principios entonces poco académicos, ahora en su artículo "The Wise Leader" presentan también nuevos principios, pero esta vez para los líderes.
Según Nonaka y Takeuchi los nuevos líderes no basan sus decisiones en conocimiento científico y técnico, propio de la formación tradicional de directivos, sino en la sabiduría obtenida de la práctica, que además de la capacidad para encontrar respuesta a un contexto particular incluye "virtud" en la toma de decisiones para que éstas sirvan al bien común.
Los mismos autores que conceptualizaron el marco de trabajo Scrum, las diferencias y relaciones entre conocimiento tático y explícito, y la evolución de éste en forma de espiral dialéctica, argumentan ahora que los líderes tradicionales gestionan con conocimiento explícito. Que a muchos les resulta difícil reinventar sus empresas al ritmo que hoy marca la tecnología, la demografía y el mercado. El liderazgo tradicional es incapaz de desarrollar organizaciones para operar en un escenario global, y sobre todo le resulta difícil transmitir a las personas valores éticos. Los CEO's ya desfasados, según esto, siguen creyendo que la codicia es buena y que el objetivo del negocio es el máximo beneficio.
"Los gerentes suelen basarse en el conocimiento explícito que puede ser medido, codificado y generalizado" dicen Takeuchi y Nonaka. Sin embargo este enfoque "supone un mundo independiente del contexto y busca respuestas universales y predictivas". "Todo el conocimiento explícito del mundo no ha evitado el colapso financiero mundial de hace tres años o la quiebra de Lehman Brothers"
Afectada por el engaño y la codicia, la gente está molesta por la ausencia de valores y ética en los negocios. Las empresas de Wall Street pensaron que podían manejar riegos mayores usando números, datos y fórmulas científicas en lugar de analizar con sabiduría la naturaleza de los préstamos.
Lo mismo ocurre con la industria del automóvil de EE.UU. que se basa en la oferta de incentivos financieros en lugar de comprender las necesidades del cliente. Depender sólo del conocimiento explícito impide conocer las dependencias del contexto y su análisis en el entorno social.
Nonaka y Takeuchi proponen en su artículo la frónesis aristotélica, síntesis del conocimiento científico y técnico, como clave del nuevo liderazgo, y la definen como "el conocimiento tácito adquirido por la experiencia que permite a las personas hacer juicios prudentes y actuar de forma adecuada a cada situación, guiadas por los valores y la moral".
Según los autores son seis los principios de los líderes sabios:
- Los líderes sabios toman decisiones sólo despues de averiguar lo que es bueno para la organización y la sociedad.
- Captan rápidamente la esencia de las situaciones y los problemas, comprendiendo la naturaleza y el significado de las personas, las cosas y los hechos
- Crean contextos de trabajo basados en el diálogo y el consenso
- Saben cómo elaborar metáforas e historias para transformar la esencia de su experiencia en el conocimiento tácito de los individuos y los grupos.
- Tienen la capacidad política de reunir a personas con objetivos en conflicto y estimular a la acción.
- Fomentan el desarrollo de la frónesis en otros.
Entrevista a Takeuchi y Nonaka sobre su artículo The Wise Leader
» Leer más, comentarios, etc...
monocaffe
Changes in Jongo 0.2
Marzo 29th, 2012
Lots of changes are being introduced in Jongo 0.2 which I believe are better suited for the scope of the project.
First and most important, I decided to remove the administration console which was to be used as a way for an administrator to customize access to resources, set ID columns and add complex queries. The problem with this approach is that I don't want Jongo to be another tool you have to worry about to keep it running, and most of this things are already on your RDBMS! The basic idea of Jongo: embrace the use of any SQL server.
So, the problems the administration console tried to fix should be fixed on the database:
Resources permissions. Use an specific user for Jongo, and customize access for this user.
Complex Queries. The idea was to allow a GET request to execute a predefined query which was created in Jongo. But why do this when you have triggers, stored procedures, views, etc? So this had to go. Also, stored procedures run faster than running the same query over and over again.
http//.../Jongo/db/sp/myStoredProcedure
[Note: stored procedures are still not supported, but should be in the future]
Custom ID column. If your resource is not using an ID column, this is now supposed to be sent on the requests path:
http//.../Jongo/db/resource/1?customId=rid
Since the administration console is gone, there's no need for Jongo to keep a database to hold its data, so this and the hsqldb.jar were removed too.
Another big change being introduced is the correct use of headers in the request and in the response. In 0.1 the "Accept" header wasn't used at all, and this is not acceptable in REST. So now, instead of changing the format as a path parameter, Jongo handles the appropriate headers.
$curl -H "Accept: application/xml" "http://.../jongo/db/user/1"
On the other hand, response headers include a lot of information about the data being returned: Content-Length, Content-MD5, Content-Count, Date and more depending on the response (error, success, head, stats).
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Count: 1
Content-Location: user
Content-Length: 249
Date: 2012-03-30T12:38:11.581+02:00
Content-MD5: ulYx9Vsbymcq7ExWzdWlFw==
Server: Jetty(8.1.2.v20120308)
During the day I've been working extensively with JAX-RS at work with a project which is very similar to Jongo in how both work, so both of the projects share ideas, and being able to customize the response's JSON and XML is very important. Because of this Jongo will include some filters which will try to ease the unmarshalling in, for example, JAX applications, ExtJS and more.
<response>
<success>OK</success>
<resource>user</resource>
<rows>
<row>
<cell>
<birthday>1992-01-15</birthday>
<credit>0.00</credit>
<lastupdate>2012-03-30T12:38:11.576+02:00</lastupdate>
<name>bar</name>
<age>33</age>
<id>1</id>
</cell>
</row>
</rows>
</response>
By default the XML and JSON returned by Jongo is the same as in version 0.1 but if you configure Jongo's web.xml file to use no filter, then JAX is used to do the marshaling.
<response>
<status>OK</status>
<success>true</success>
<resource>user</resource>
<rows>
<roi>0</roi>
<cells>
<entry>
<key>BIRTHDAY</key>
<value>1992-01-15</value>
</entry>
<entry>
<key>CREDIT</key>
<value>0.00</value>
</entry>
<entry>
<key>LASTUPDATE</key>
<value>2012-03-30T12:30:27.768+02:00</value>
</entry>
<entry>
<key>NAME</key>
<value>bar</value>
</entry>
<entry>
<key>AGE</key>
<value>33</value>
</entry>
<entry>
<key>ID</key>
<value>1</value>
</entry>
</cells>
</rows>
</response>
The objective is to allow to develop different formats which can be read without much development on the consumers.
I'm also working on tests and trying to achieve a 90% coverage. Doing this is a great exercise on fixing code structure and abstraction. Being able to setup an in-memory database with HSQLDB also helps a lot.
Gone is all the code to handle the different database error codes returned by the JDBC drivers. I had the hope (silly me) that the different RDBMSs would follow some sort of standard at least on this, but no, each one of them returns a different SQLStatus & SQLCode for the same error, so it was very frustrating and I didn't want to waste my time researching for the correct codes and their meaning for every different system. The solution?
<response>
<success>false</success>
<message>data exception: invalid character value for cast Query: SELECT * FROM user WHERE id = ? ORDER BY id ASC LIMIT 25 OFFSET 0 Parameters: [1*]</message>
<sqlState>22018</sqlState>
<sqlCode>-3438</sqlCode>
</response>
More than a solution, it's a workaround: return the error message and codes to the client and let it handle it as it sees fit. Remember, embrace your database!
Another feature gone is the "apps" folder, so by default, you won't be able to use Jongo as a JavaScript application server, although, there's a way to serve static content which I'll explain in the future.
Finally, I separated the project in three repositories:
- jongo (common files)
- jongo-jetty (standalone)
- jongo-as (war)
I tried to get a version of this WAR working with Google's GAE but it was very frustrating as a PaaS. What I believe is a better service is the one provided by Jelastic and I'll document a guide on how to prepare Jongo's WAR to work with it.
That's it for now, I hope the few users of Jongo don't get pissed because of this changes.
» Leer más, comentarios, etc...
Koalite's blog
Sopa de Siglas: AJAX, JSON, JSONP y CORS
Marzo 29th, 2012
Al jugar con PhoneGap/Cordova he acabado por tocar un punto que puede ser un tanto escabroso en según que casos: el acceso a servidores externos. Hacer esto desde Javascript supone enfrentarse a un mar de siglas que pueden llegar a ser confusas.
AJAX y JSON
AJAX son las siglas de Asynchronous Javascript And Xml (Javascript Asíncrono y Xml) y es una forma de poder ejecutar código javascript de manera asíncrona para obtener información.
Empezó a cobrar importancia al extenderse XMLHttpRequest, un interface creado por Microsoft que permite realizar peticiones HTTP/HTTPS mediante Javascript e intercambiar información en cualquier formato de texto plano (HTML, XML o JSON).
La X de AJAX se refiere a XML porque al principio el formato más usado para intercambiar datos era XML, pero hoy en día el formato más frecuente seguramente sea JSON, JavaScript Object Notation (Notación de objetos en JavaScript).
JSON es un formato mucho más ligero que XML y, además, tiene la ventaja de ser “nativo” para Javascript, el lenguaje por excelencia para usar XMLHttpRequest desde una página web.
JSONP
Por motivos de seguridad, usando XMLHttpRequest sólo pueden realizarse peticiones al mismo dominio desde el que se ha cargado la página que origina la petición. Es decir, si cargamos una página desde www.domain.com, sólo se podrán hacer peticiones a URLs de la forma www.domain.com/lo-que-sea.
La idea es que si navegas a una página web con código “malicioso” y tienes una sesión abierta a, por ejemplo, la página de tu banco, esa página web maliciosa no pueda lanzar una petición http para ordenar una transferencia.
El problema es que a veces este tipo de peticiones son legítimas y necesarias. Por ejemplo, podemos tener una página que está agregando información de varias fuentes y, para ello, tenemos que lanzar peticiones a los dominios de esas fuentes.
Para solucionar este problema surge JSONP, JSON with Padding (JSON con almohadillas/relleno). JSONP se basa en inyectar un script en la página actual usando al etiqueta , que sí permite acceder a recursos situados en otros dominios.
Como inyectar un fragmento de JSON tal cual es poco útil, se emplea el padding, que no es más que una función definida por el cliente y que el servidor usa para “rodear” el fragmento de JSON devuelto.
Por ejemplo, podríamos tener un API que devuelve el tiempo en Madrid usando JSONP y que funcionaría así:
// Una llamada a la url http://weather.com/?location=Madrid
// Devuelve este fragmento JSON
{
"location": "Madrid",
"temperature": "20"
}
Para invocarlo con JSONP, se añadiría un nuevo parámetro con la función callback que queremos que se ejecute con la respuesta:
// La llamada a http//weather.com/?location=Madrid&callback=processResult
// Devolvería este script
processResult({"location": "Madrid", "temperature": "20"});
De esta forma, cuando se carga en la página el script con el resultado, está incluyendo el código necesario para invocar la función que queremos usar para procesarlo. Las librerías modernas de Javascript como jQuery son capaces de tratar esto de forma bastante automática.
JSONP tiene varios inconvenientes, como que sólo admite peticiones GET (olvídate de POST y similares) y no permite controlar el proceso de la petición, ya que se delega por completo a la forma en que procese el navegador las etiquetas .
CORS
Dadas las limitaciones de JSONP, y que no deja de ser un hack, recientemente aparece un protocolo nuevo, CORS, Cross-Origin Resource Sharing (Compartición de recursos de distintos orígenes).
CORS permite realizar peticiones a otros dominios siempre y cuando el dominio de destino esté de acuerdo en recibir peticiones del dominio de origen. Es una tecnología implementada a nivel de navegador, que intercambia ciertas cabeceras HTTP con el servidor de destino para saber si debe permitir o no el intercambio de datos.
En principio el código Javascript que realiza la petición a través de XMLHttpRequest no tiene que saber nada de CORS, pero el navegador donde se ejecuta y el servidor al que se conecta sí tienen que haber implementado el protocolo. Si queréis ver un ejemplo de cómo se implementa CORS en el servidor, aquí tenéis cómo implementar CORS en ASP.NET Web API.
En su forma más básica, cuando un servidor que implementa CORS recibe una petición añade a la respuesta una cabecera HTTP con el siguiente aspecto:
Access-Control-Allow-Origin: http://dominio-permitido.com
La cabecera incluye el/los dominios desde los que se permite acceder a este recurso y es responsabilidad del navegador decidir si la página que hizo la petición ha sido cargada desde uno de esos dominio o no, y devolverle los datos a la página o no.
¿Cómo afecta todo esto a PhoneGap/Cordova?
Todo este rollo viene a cuento porque las aplicaciones que empaquetamos con PhoneGap/Cordova son cargadas desde el sistema local de archivos, con lo que cualquier petición que realicemos a internet se convierte en una petición cross-domain.
Ahora que ya conocemos las bases de todo esto (y ya sabéis que conocer la teoría es algo que me importa), estamos en condiciones de analizar las alternativas para realizar peticiones cross-domain, aunque eso lo dejaremos para futuros posts.
PD: Para los puristas, sí, el título está mal. Algunos no son siglas, son acrónimos
No hay posts relacionados.
» Leer más, comentarios, etc...
Arragonán
Tip: Arrancando RabbitMQ en Mac OS
Marzo 28th, 2012
He empezado a trastear con RabbitMQ, que hacía mucho que lo tenía entre ceja y ceja. La instalación en un servidor con ubuntu fue trivial, en unos minutos estaba instalado y en marcha, pero no fue así en mi Mac.
Tras instalarlo con homebrew no conseguía arrancarlo, me daba el siguiente error:
ERROR: epmd error for host "vodkalimon": address (unable to establish tcp connection)
Al parecer se intentaba conectar con mi máquina por su nombre (efectivamente se llama vodkalimon
), no por localhost o la ip de loopback.
La solución es muy simple, aunque a mi me costó un buen rato darme cuenta, que uno es un poco torpe para los sistemas.
Simplemente añadir en /private/etc/hosts el nombre de la máquina apuntando a la ip de loopback. Lo que a mi me ha quedado como algo así:
...
127.0.0.1 localhost
127.0.0.1 vodkalimon
255.255.255.255 broadcasthost
...
Y con esto, ya podemos arrancar normalmente RabbitMQ.
» Leer más, comentarios, etc...
Variable not found
ASP.NET MVC, WebAPI y Razor, ahora mucho más open source
Marzo 28th, 2012
¿Ein? ¿Pero no lo eran ya? Bueno, sí… pero no en toda la amplitud que puede ofrecer este término.
El progresivo acercamiento de ASP.NET al mundo del open source es algo que llevamos observando bastante tiempo. Desde hace unos años es posible acceder al código fuente de muchos productos, y también hemos visto cómo determinados proyectos puramente libres como jQuery eran incluidos con todos los honores en el conjunto de tecnologías de desarrollo oficiales de Microsoft. Ahora vamos un paso más allá.
El código fuente de la primera versión de ASP.NET MVC fue publicado en 2009, poco después de su lanzamiento, bajo licencia MS-PL, un modelo de licencia open source aprobado por la OSI (Open Source Initiative). Desde ese momento, cada lanzamiento del framework iba acompañado de la publicación del código fuente en CodePlex, lo que nos permitía descargarlo, estudiar su funcionamiento, compilarlo, y retocarlo libremente. Lo mismo ocurría con la primera versión de WebPages, y previsiblemente lo mismo iba a ocurrir con las nuevas versiones de MVC, WebPages y Web API.
Sin embargo, el desarrollo de estos productos seguía estando totalmente en manos de Microsoft. Es cierto que podíamos reportar bugs y sugerir cambios, pero en ningún momento participar de forma activa en los proyectos, ni ver lo que iba ocurriendo entre una RTM y otra.
Y de pronto, hoy nos levantamos con la noticia de que ASP.NET MVC, Web API y Web Pages (Razor) van a ser distribuidos como open source (licencia Apache 2.0). Pero si ya podíamos acceder al código fuente, ¿cuál es la novedad?
Pues, en primer lugar, que ahora los proyectos se han abierto totalmente de cara a la comunidad. No se trata de dejar que se vean las tripas de estos productos una vez terminados, sino de adoptar un modelo de desarrollo abierto y transparente al cien por cien.
Para empezar, ya no tendremos que esperar a las versiones RTM para acceder al código fuente, como ocurría hasta ahora; tendremos total transparencia durante el proceso de desarrollo, puesto que el fuente está ya disponible en un repositorio público accesible con Git. Podemos descargarlo, clonarlo, hacer forks, sugerir ideas, ver en cualquier momento el estado de los trabajos, las características pendientes de desarrollo, los bugs subsanados y las modificaciones que se están realizando por parte de los contribuyentes en tiempo real.
Y recalco aquí la palabra “contribuyentes”, que es el segundo aspecto importante de la noticia a la que hacía referencia. No hablamos ya exclusivamente de los equipos de Microsoft que hasta ahora han llevado las riendas: a partir de ahora, los desarrolladores de la comunidad podemos contribuir con parches e implementando funcionalidades de estos tres productos.
De hecho, el primero en estrenarse ha sido Miguel de Icaza, que había sido avisado previamente del movimiento, y ha contribuido añadiendo modificaciones a las plantillas de edición para que tengan en cuenta el DataType (Email, Url, DateTime, Date, Time, Number, etc.) a la hora de generar los controles en la página, de forma que éstos ya aparezcan con el atributo type establecidos de forma correcta para aprovechar las ventajas de HTML5.
Pero ojo, que esto no significa que MVC, Web API o Razor vayan a ser abandonados a su suerte. Microsoft va a seguir incluyéndolos con Visual Studio y trabajando en ellos como hasta ahora, desarrollándolos con la misma gente, dándoles soporte oficial, y asegurando su calidad. Cada contribución será minuciosamente revisada y comprobada por el equipo de ASP.NET y sólo serán aprobadas aquellas que cumplan estrictos criterios de calidad y adhesión al Roadmap de cada producto.
En palabras de Hanselman, nada cambia salvo una cosa: “Es ASP.NET, pero ahora puedes involucrarte”.
Y las ventajas están claras: estas tecnologías se verán enriquecidas e impulsadas por la comunidad de desarrolladores, y, si no se ponen trabas, esto seguro que se traduce en un crecimiento mucho mayor que el que hemos vivido hasta ahora, una respuesta más rápida ante problemas, una mejor y más eficiente adaptación a los cambios tecnológicos del entorno, y sobre todo, una mayor cercanía de los productos a sus usuarios y a la realidad de nuestro trabajo.
En fin, se trata de un importante movimiento por parte de Microsoft cuyas consecuencias y resultado iremos viendo con el tiempo, pero si todas las premisas se cumplen sin duda es una gran noticia para los desarrolladores ASP.NET.
Enlaces:
- Anuncio oficial de Scott Guthrie: ASP.NET MVC, Web API, Razor and Open Source
- Anuncio de Hanselman: ASP.NET MVC 4, ASP.NET Web API and ASP.NET Web Pages v2 (Razor) now all open source with contributions
- Sitio en codeplex: http://aspnetwebstack.codeplex.com/
- Sitio oficial de ASP.NET: http://asp.net











