Internet y la Web desde 1993
Si no recuerdo mal, este año fue en el que por primera vez empecé a oir el témino World Wide Web (para los rezagados en el inglés, se puede traducir como “telaraña mundial”). La citada criatura empezó, como nos dicen (¿ o dirán ?) las clases de historia, cuando un discípulo de Jehová TCP/IP creó a su Adán HTTP/HTML en el CERN.
En un principio, esta herramienta estaba pensada para mantener un repositorio de documentos, y poder formatear éstos de una forma sencilla mediante marcas especiales dentro del documento, y el soporte para la maravillosa etiqueta <img>, lo que comportaba que el Protocolo de Transferencia de HiperTexto tuviera soporte para MIME, y su idoneidad para transportar cualquier tipo de información de forma sencilla.
Aún recuerdo a las ratas de laboratorio (el equivalente veintesiglero de un geek) creando páginas de enlaces que sólo te invitaban a abandonar su web, esos fondos verde doloroso y la revolución de los frames. Nunca lo entendí. Confundían un medio con un fin.
Fui de los pocos que me matriculé en una asignatura relacionada con la www (era algo así como administración de servidores web). Aprendimos Apache (A PAtCHEd Server), como se configuraba, a construir macarrónicas páginas html, a programar CGI’s en C, y las tendencias del sector (el contenido gratuito iba a ir menguando, y si querías servicios de calidad, a rascarte el bolsillo). Ya salió el dinero a escena. Lo echábamos de menos.
Después vino la revolución de los .com. La Web empezó a ser conocida por el gran público. Los medios de comunicación, haciendo gala de su ignorancia habitual, confundían a la gente, haciéndoles creer que Internet no existía, sólo la ubicua tripe uve doble. La bolsa vió en la red electrónica el reflejo del desde sus añorados años 20 capitalismo salvaje y su compañera la compraventa de valores de humo. Nunca entendí que se confundiera el medio con el fin.
Al terminar esta efervescencia, y una vez eliminados muchos indeseables actores, se empezó a vislumbrar poco a poco la madurez de la red, tanto en su vertiente pública (diarios digitales, foros, listas de distribución, comunidades de usuarios, etc), como en la profesional (TPVs, documentos XML, accesos remotos). Internet empezó a utilizarse por la sociedad como un medio.
La verdadera revolución está llegando en estos tiempos, donde las webs sociales se han impuesto y han barrido a todo tipo de sitios “de pago”, donde la información la genera la misma comunidad de usuarios que la consume de forma gratuita. Por fin la sociedad ha entendido que detrás de la red de redes hay algo más que estar cuatro horas dándole al click como un zombi.
¿ Cual es el futuro ? No lo preguntéis a nadie, sólo hay una cosa cierta: el Darwinismo funciona en la red, y será la interacción del pueblo llano la que vaya moldeando el aspecto y comportamiento de esta comunidad mundial.
martes, 19 de noviembre de 2013
Rescatando viejos tiempos
viernes, 18 de octubre de 2013
Tarjetas de contacto en ASP.Net MVC
A veces nos perdemos en cuestiones totalmente estéticas a la hora de realizar webs para entornos móviles, donde términos como "responsive" acaparan todo el protagonismo, olvidando que, a veces, podemos dotar de funcionalidades básicas que diferencien estas webs de los entornos de escritorio ya que nuestras páginas se van a mostrar en dispositivos que disponen de más funcionalidad que un navegador web de un computador de sobremesa o portátil.
Vamos a ver como integrar nuestra web con las funcionalidades primordiales de los teléfonos, es decir, realizar llamadas y guardar contactos en la agenda.
Llamadas Telefónicas
La realización de llamadas telefónicas desde la web se basa en una técnica ya utilizada para abrir el cliente de correo desde el explorador. Si para enviar un email utilizamos el esquema mailto:, para indicar que un enlace corresponde a un teléfono, usaremos tel:
<html>
<body>
<div>
<label>Telf:</label>
<a href="tel:96 000 00 00" class="tel">Llamar</a>
</div>
</body>
</html>
Esto nos generará un enlace al número telefónico especificado.
Como curiosidad, ¿ que ocurrirá si abrimos el enlace en un dispositivo sin posibilidad de realizar llamadas telefónicas ?
El dispositivo detecta que es un número telefónico y nos da la opción de guardarlo en contactos.
Gestión de contactos
La otra posibilidad es la de ofrecer tarjetas de contacto completas desde la web. Podremos dar oportunidad a los visitantes de nuestra web de obtener nuestros datos de contacto en nuestro curriculum online público, los de los clientes asignados a un vendedor desde nuestro programa de gestión, o nuestra tarjeta de visita de nuestro restaurante
El mecanismo necesario para la integración de los contactos se basa en:
- Tipo MIME para la tarjeta de contacto text/x-vcard
- Formato VCARD
Veamos la implementación de una descarga en ASP.Net MVC
Utilizaremos un controlador sin vista asociada para devolver el contenido. El primer paso es anunciar el tipo MIME anteriormente citado y sugerir al navegador un nombre de archivo en la descarga
Response.ContentType = "text/x-vcard";
Response.Headers.Add("Content-Disposition", String.Format(@"attachment; filename=""{0}.vcf""", "Contacto"));
Ahora sólo nos falta generar el cuerpo de la respuesta. El formato VCard es un sencillo formato de texto, por lo que para generarlo construiremos una cadena y la devolveremos con el ActionResult Content, que nos permite devolver un valor de texto como cuerpo del mensaje.
String result = String.Format(@"BEGIN:VCARD
VERSION:3.0
ORG:{0}
TEL;TYPE=WORK:{1}
EMAIL;TYPE=WORK:{2}
ADR;TYPE=WORK:;;{3};{4};;{5};{6}
END:VCARD", "Nombre", "96 000 00 00", "email@email.com", "Direccion", "Ciudad","46000", "ES");
return Content(result);
Es importante comentar que las líneas de la VCard han de estar alineadas a la izquierda sin espacios en blanco, ya que si no el dispositivo nos puede dar un error de formato incorrecto
El código completo de la acción es el siguiente:
public ActionResult VCard()
{
Response.ContentType = "text/x-vcard";
Response.Headers.Add("Content-Disposition", String.Format(@"attachment; filename=""{0}.vcf""", "Contacto"));
String result = String.Format(@"BEGIN:VCARD
VERSION:3.0
ORG:{0}
TEL;TYPE=WORK:{1}
EMAIL;TYPE=WORK:{2}
ADR;TYPE=WORK:;;{3};{4};;{5};{6}
END:VCARD", "Nombre", "96 000 00 00", "email@email.com", "Direccion", "Ciudad","46000", "ES");
return Content(result);
}
Si accedemos a la descarga, se procederá a guardar el archivo en el dispositivo y su posterior importación a la agenda de contactos.
jueves, 10 de octubre de 2013
Html Helpers en MVC con contenido
Los Helpers de HTML en MVC nos facilitan la creación de vistas al encapsular la creación del código de marcado. Desarrollar un Helper que cree un label o un input, es un caso trivial, pero podemos encontrarnos con que necesitemos utilizar la sintaxis de Razor para generar contenido entre la etiqueta de apertura y cierre, por ejemplo llamar a vistas parciales u obtener el resultado de pintar un Action
Como hemos comentado, generar un Helper para un input o un label es una tarea sencilla, con un método de extensión podemos resolver nuestro requerimiento:
public static MvcHtmlString MiLabel(this HtmlHelper htmlHelper, String NombreCampo, String Caption)
{
String formatresult = "<label for='{0}'>{1}</label>";
return new MvcHtmlString(String.Format(formatresult, NombreCampo, Caption));
}
Una llamada a este helper:
@MiLabel("NombreCampo", "Valor")
Nos generaría en el marcado resultante:
<label for="NombreCampo">Valor</label>
El asunto se complica si necesitamos marcado entre las etiquetas de apertura y cierre. Un enfoque para solucionar esto sería escribir los métodos correspondientes al inicio y al fin de la etiqueta, y llamarlos de la misma forma que en el ejemplo anterior.
PERO, somos personas curiosas y elegantes, por lo que decidimos que lo queremos hacer bien, de forma concisa. Nuestra curiosidad nos lleva a observar que todas las vistas de creación y edición que nos genera Visual Studio hay un elegante using que rodea entre llaves todo el marcado de los campos del formulario.
@using (Html.BeginForm("Accion", "Controlador", FormMethod.Post)) {
{
<h3>Titulo</h3>
}
¡Un momento! ¿ using ? ¿ No se utiliza la clausula using para crear un objeto que implementa la interfaz IDisposable, ejecutar código y destruirlo de forma ordenada ?
Efectivamente esa es la forma con la que podremos crear nuestros helpers, sólo necesitaremos:
- Una clase que implemente la interfaz
IDisposabley - un método que nos devuelva un objeto de esta clase
En resumidas cuentas, utilizaremos el método para crear un objeto y general el HTML del inicio del elemento, y el método Dispose del objeto creado para cerrarlo
Sin más dilación, vamos a ver un ejemplo de esta técnica
Creamos un método de extensión que devuelva una instancia de la clase que creemos después:
public static MvcContainer BeginContainer(this HtmlHelper htmlHelper, String tagname)
{
return new MvcContainer(htmlHelper.ViewContext.Writer, tagname);
}
Y veamos la definición de la clase MvcContainer generada en el paso anterior:
public class MvcContainer : IDisposable
{
private bool disposed;
private readonly TextWriter _writer;
private string _tagname;
public string tagname
{
get { return _tagname; }
set
{
_tagname = value;
_writer.Write(String.Format("<{0}>", _tagname));
}
}
public MvcContainer(TextWriter writer)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
this._writer = writer;
}
public MvcContainer(TextWriter writer, String tagname) : this(writer)
{
this.tagname = tagname;
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
this.disposed = true;
_writer.Write(String.Format("</{0}>", _tagname));
}
}
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
public void Dispose()
{
Dispose(true /* disposing */);
GC.SuppressFinalize(this);
}
public void EndContainer()
{
Dispose(true);
}
}
Sólo tenemos que fijarnos en el método Dispose requerido por la interfaz IDisposable en el que escribimos en la salida el elemento de cierre
Utilizamos el writer de la respuesta del contexto, ya que si escribimos con el método Response.Write, el marcado a generar nos aparecerá al principio del resultado, y no en la posición del template Razor utilizado.
Si llamamos al método de extensión creado anteriormente:
@using (Html.BeginContainer("p"))
{
<text>Contenido del párrafo</text>
}
Obtendremos la salida deseada:
<p>Contenido del párrafo</p>





