Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
domingo, 10 de junio de 2007
Este post es el tercero (y último) de la serie sobre selectores CSS definidos en la versión 2.1 del estándar publicado por la W3C.

Las dos entradas anteriores puedes encontrarlas aquí: Etiquetas CSS 2.1 (I) y Etiquetas CSS 2.1 (II).

En la primera de ellas fueron incluidos selectores básicos, de uso muy frecuente y compatibles con todos los navegadores actuales; en la segunda se complicó un poco el tema, introduciendo otros menos conocidos y de aceptación desigual por parte de los browsers más difundidos.

A continuación seguimos describiendo el resto de selectores, muy interesantes todos ellos, pero hay que tener cuidado a la hora de utilizar, sobre todo si lo que se pretende es llegar al mayor número posible de usuarios, puesto que no son contemplados por todos los navegadores, especialmente los que salen de las fábricas de Microsoft.

Selector de hijos (>)

Permiten indicar los atributos de aquellos elementos que sean hijos de su padre. Digamos que es como un selector descendente (descrito en la primera entrega de la serie) pero exclusivamente aplicado al primer nivel de descendencia. Funciona en casi todos los navegadores excepto, como de costumbre, en Internet Explorer 6.

body > p
{
/* Los párrafos de primer */
color: red; /* nivel por debajo de body */
/* se pintan en rojo */
}


Subselectores de primogénitos

Permite seleccionar un elemento, siempre que éste sea el primogénito de su padre. ¿Utilidad? Mucha. Por ejemplo, permite decirle a los <li> de una lista que el primero se pinte de forma diferente a los demás sin necesidad de marcarlo con un class="primero" o similar, como se hace normalmente.

li
{
/* Los elementos de lista, */
color: red; /* siempre en rojo */
}
li:first-child
{
/* pero el primero, irá */
color: blue; /* en azul. */
}

Este subselector funciona en Firefox 1.5 o superior, IE7, Safari, Opera y Konqueror. Como casi siempre, se queda por detrás Internet Explorer 6.

Es interesante comentar que CSS nivel 3 permitirá, además, la utilización del subselector de "benjamines", :last-child, que selecciona los elementos siempre que sean el último hijo de su padre. De momento el soporte en los
navegadores es incluso menor que el anterior.

Selector de precedencia (+)

Resulta útil para seleccionar un elemento que se encuentre en el código (X)HTML codificado justo después de otro. Ojo, que cuando digo después de un elemento me refiero a seguir a un elemento completo (con su correspondiente etiqueta de apertura y cierre), no a ser descendiente suyo (que ocurriría al encontrarse tras su etiqueta de apertura); es bastante fácil confundirse en esto.

p + a
{
/* Los enlaces que sigan */
color: red; /* a un párrafo, en rojo */
}
/* No afectará a: */
/* <p>Saltar a <a href="#">enlace</a></p> */
/* Sí afectará a: */
/* <p>Saltar a </p><a href="#">enlace</a> */


Subselector de atributos ([ ])

A veces los atributos de los elementos son indicativos del formato que éstos deben tomar. Para estos casos, el subselector de atributos permite:

  • Seleccionar elementos que tengan declarado un atributo, independientemente de su valor. Esto se consigue utilizando el selector [atributo].

    img[alt]
    {
    /* Las imágenes con atributo */
    /* alt='texto', borde rojo */
    border: 4px solid red;
    }

  • Seleccionar elementos que presenten un atributo con un valor determinado. La forma de hacerlo es utilizando la expresión [atributo="valor"]:

    p[dir='rtl']
    { /* Los párrafos que se lean */
    color: red; /* de derecha a izquierda */
    } /* irán en rojo */

  • Seleccionar elementos que presenten un atributo con un valor consistente en una lista de palabras separadas por espacios y una de ellas coincide con el valor a buscar. La forma de hacerlo es utilizando la expresión [atributo~="valor"]:

    p[lang~='en']
    { /* Los párrafos en inglés */
    color: red; /* se pintan en rojo */
    } /* aunque el inglés no */
    /* sea el único idioma */
    /* Ej: lang="fr en" */


  • Seleccionar elementos que presenten un atributo con un valor consistente en una lista de palabras separadas por guiones y comiencen con el valor a buscar. La forma de hacerlo es utilizando la expresión [atributo="valor"]:

    p[lang='en']
    { /* Los párrafos en inglés */
    color: red; /* se pintan en rojo */
    } /* independientemente */
    /* de su localización */
    /* Ej: lang="en-US" */



Sé que casi no hace falta decirlo, pero de nuevo es IE6 el único que no interpreta estos interesantes subselectores.

¡Y esto es todo, amigos! Recapitulando, esta serie de tres posts recoge todos los selectores definidos por la W3C (salvo error u omisión por mi parte, claro) en su especificación CSS 2.1.

Sin embargo, como hemos podido ver, la terrible lamentable implementación del estándar en los navegadores, sobre todo Internet Explorer 6, hace que sea realmente complejo crear una web que pinte bien en todos ellos. Y por desgracia, hay que recordar que IE6 sigue siendo el navegador más utilizado del mundo; esperemos que esto cambie pronto gracias a su hermano mayor IE7, que sin ser prodigioso sí está bastante mejor situado respecto a la aceptación de CSS 2.1, y al magnífico Firefox, un auténtico fiera a la hora de respetar los estándares.
jueves, 7 de junio de 2007
En el post anterior recogía selectores CSS
básicos
, aquellos que pueden usarse con cualquier navegador sin llevarse sorpresas. En esta entrega vamos a continuar con ellos e introduciremos algunos más avanzados que no funcionan con todos los browsers pero que resulta altamente interesante conocer.


Subselectores de estado

Utilizados principalmente en los enlaces (etiquetas
<a>), permiten indicar distinta presentación dependiendo del estado en el que se encuentren los mismos. Se indican siempre acompañando al selector principal al que se aplican, seguido por dos puntos y el subselector a aplicar. Tenemos los siguientes:


  • Enlaces no visitados (a:link)

  • Enlaces visitados previamente (a:visited)

  • Enlaces activos, al pulsar sobre ellos (a:active)

  • Enlaces bajo el puntero del ratón (a:hover)

  • Enlaces con el foco activo (a:focus)



a:hover
{
/* Al pasear el ratón ... */
color: red; /* por encima, se pone rojo */
}
a:active
{
color: blue; /* Al pulsarlo, pasa a azul */
}

La verdad es que algunos de ellos no tienen sentido fuera de enlaces, pero otros sí.
De hecho, es perfectamente posible utilizar un selector p:hover e indicar los atributos a aplicar a todo el párrafo cuando se pasee el ratón por encima. Lo mismo ocurre para el foco, que podría aplicarse a elementos de tipo <input>. Sin embargo, la terrible implementación de CSS en Internet Explorer 6 no los contempla, por lo que no están demasiado difundidos estos usos. Menos mal que IE7, aunque esté lejos de ser un virtuoso, ha mejorado esta compatibilidad.


Subselector de idioma

Permite seleccionar aquellos elementos cuyo contenido está en un idioma determinado, y, eso sí, hayan sido marcados convenientemente para identificarlo con el atributo lang. Sin embargo, su dispar aceptación por los navegadores e incluso las distintas formas de expresar el idioma en una etiqueta (lang o xml:lang) hace que no sea fácil ponerlo en práctica. El siguiente ejemplo funciona en Firefox, pero no en IE6-7:

p:lang(en)
{
/* Los párrafos en inglés, */
color: red; /* siempre en rojo */
}


Subselector de primer carácter

Selecciona el primer carácter del contenido de los elementos apuntados por el selector principal. No funciona bien en IE6, pero sí en el resto de navegadores medio decentes (Firefox, Safari, Opera, Konqueror e incluso IE7).

p:first-letter
{
/* La primera letra, como */
color: red; /* siempre, en rojo */
}


Subselector de primera línea

Todo lo dicho con el anterior resulta igualmente válido, a diferencia de que los estilos indicados se aplican a la primera línea del contenido.

p:first-line
{
/* La primera línea del */
color: blue; /* párrafo, color azul, */
/* por cambiar un poco. */
}


Subselectores de contenido previo y posterior

Estos interesantísimos selectores permiten modificar el contenido de la página justo antes del elemento apuntado por el selector principal o justo después de éste. ¿Qué quiere decir esto? Pues que podemos modificar el contenido de la página desde la hoja de estilos CSS, aunque pueda poner un poco los pelos de punta. La pena es que los hermanos IE no lo reconocen :-/.

p.ojo:before
{
/* Todos los párrafos */
/* de clase "ojo" */
content: "OJO: "; /* irán precedidos por */
/* el texto "OJO:" */
}
p.ojo:after
{
/* Todos los párrafos */
/* de clase "ojo" */
content: "FIN"; /* irán seguidos de */
/* el texto "FIN" */
}


Creo que con esto tenemos suficiente por hoy.
En el próximo post seguiremos profundizando en el escalofriante mundo de los selectores avanzados... la diversión está asegurada.
domingo, 3 de junio de 2007
Hace tiempo que tenía ganas de escribir algo sobre los selectores CSS 2.1, esos grandes desconocidos, al menos para mí. Cierto es que desde hace años uso estilos para decorar páginas, pero por una razón u otra no había dedicado el tiempo suficiente para conocer todos los selectores que define el estándar, por lo que me limitaba a utilizar los más básicos. Y como supongo que no soy el único, dedicaré algunos posts a enumerarlos y comentarlos, a ver si podemos aprovechar mejor toda la potencia que esta técnica ofrece, y evitar dolores de cabeza a la hora de maquetar y decorar una página.

Como sabemos, CSS permite indicar cómo se verá el contenido de páginas web que componemos utilizando (X)HTML. Un ejemplo de declaración de estilo es la siguiente, que indica que todo lo que se encuentre entre <p> y </p> se dibuje negro y con fuente gruesa (negrilla):
p { color: black; font-weight: bold; }

Existen dos partes importantes en esta regla: qué atributos hay que aplicar (negrilla y color negro en este caso) y a qué debemos aplicárselo (al contenido de las etiquetas <p>) de la página a la que se aplique este estilo. Los selectores son precisamente el segundo grupo, la parte de la declaración que indica qué elementos del contenido se verán afectados por los atributos especificados. De ahí su nombre "selectores".

A continuación se recogen los selectores recogidos en el estándar CSS 2.1 de la W3C. Sin embargo, dado que son bastantes y voy a incluir algunos ejemplos, incluiré en este post únicamente los más habituales y utilizados. En un post posterior (valga la redundancia) añadiré el resto.

Selector universal (*)

Los atributos especificados se aplicarán a todos los elementos del documento. Sin compasión. Un ejemplo:
*
{
color: red; /* Todo en rojo */
}

Selector de elemento

Permite indicar el elemento, o etiqueta, a la que se aplicará el estilo especificado. Es el más habitual, ¿a quién no le suena lo siguiente? (ojo, cuando el mismo estilo se aplica a varios elementos se pueden separar sus selectores con comas, como en el ejemplo):
h1, h2           /* Afectará a las etiquetas h1 y h2... */
{
color: red; /* El rojo es bello */
}

Selector de clase

Permite indicar la clase CSS a la que se aplicarán los estilos indicados. La clase deberá incluirse en el código (X)HTML de forma explícita utilizando el atributo class='[clase]' de las etiquetas implicadas.

p.textoNormal /* Afectará a las etiquetas */
{ /* <p class='textoNormal' > */
color: red; /* Rojo forever */
}


.muyGrande /* Afectará a cualquier etiqueta */
{ /* con class='muyGrande' */
font-size: 10em;
}

Selector directo

Es más específico que el anterior, puesto que únicamente afecta a la etiqueta con el ID indicado, es decir, aquella en cuya declaración se haya incluido el atributo "id" (minúsculas) y se le haya asignado un valor único en la página.
p#main   /* Afectará a la etiqueta <p id='main'> */
{
color: red; /* Rojo again */
}


#main /* Es igual que la anterior, */
{ /* pues sólo hay una etiqueta */
color: red; /* con id='main' en una página */
/* correcta (X)HTML. */
}

Selector descendente

Permite aumentar la especificidad de un selector, indicando tanto la etiqueta afectada como una de sus ascesoras, o en otras palabras, un elemento donde se encuentra. La profundidad con que se puede definir es ilimitada, aunque por motivos de legibilidad no creo que sea muy conveniente alargarla en exceso. Unos ejemplos:

p a /* Afecta a todos los enlaces <a> */
{ /* incluidos en párrafos <p> */
color: red;
}


ul.menu li
{ /* Los <li> pertenecientes a */
background-color: red; /* los <ul> de clase "menu" */
} /* tendrán el fondo rojo. */


ul.menu li ul li a /* Ejemplo difícil de leer:*/
{ /* Los enlaces de un <li> */
/* pertenecientes a */
background-color: blue; /* una lista incluida en un */
/* <ul> de clase "menu" */
} /* tendrán fondo azul (uuf!). */


Es importante destacar que este selector no restringe el grado de profundidad del antecesor. Es decir, "p a { color: red; }" indica que todos los <a> que tengan un antecesor <p> se verán afectados, aunque no sean hijos directos de éste. Por ejemplo, si dentro del <p> hay un <span> y dentro de éste está el enlace <a>, también se verá afectado por la regla. En resumen, pueden ser descendientes de cualquier grado.

Bueno, vale ya por hoy. El próximo día, más.
miércoles, 30 de mayo de 2007
Hace un par de semanas Microsoft publicó la versión definitiva del complemento Internet Explorer Developer Toolbar, un plugin para IE indispensable para todos los que jugamos con XHTML y CSS y nos volvemos locos cada día intentando que los elementos aparezcan donde deben.

Las principales características de esta herramienta son:
  • Permite identificar zonas de la página paseando por encima con el ratón, permitiéndonos visualizar en todo momento de qué elemento se trata, sus atributos y las reglas de estilo CSS aplicadas a cada uno. Los elementos también pueden seleccionarse desde la estructura (DOM) de la página.

  • Activación o desactivación directa de características como estilos o scripts.

  • Asimismo, se pueden ver de forma rápida los atajos de teclado o el orden de tabulación, importante para cumplir las normas de accesibilidad.

  • Es posible indicarle que "bordee" elementos concretos, como divs, tablas, elementos posicionados u otros.

  • Permite mostrar u ocultar imágenes o propiedades de éstas como el archivo de origen (src), el tamaño o el peso.

  • Permite validar HTML, CSS, WAI y feeds RSS de forma directa.

  • Dispone de reglas para medir zonas de la página a nuestro antojo.

  • Formatea y colorea el código fuente de las páginas para facilitar su lectura.

  • Nos permite eliminar la caché del navegador, así como visualizar o eliminar las cookies asociadas a la página consultada, o incluso deshabilitar su uso.

La siguiente captura de pantalla muestra la herramienta en funcionamiento sobre Internet Explorer 6:

Internet Explorer Developer Toolbar en funcionamiento
Funciona con IE6 e IE7. En el primero se activa pulsando el icono con una flechilla que aparece en la barra de herramientas; en el segundo también, pero ojo, este icono no está visible por defecto. De momento está disponible sólo en inglés, y se puede descargar en esta dirección.

Ah, aunque supongo que ya lo conoceréis a estas alturas, el equivalente para Mozilla Firefox es la extensión Firebug, toda una maravilla, también indispensable para cualquier desarrollador web.
viernes, 25 de mayo de 2007
El pasado 22 de mayo, la IETF aprobó y publicó la propuesta del estándar DKIM en la RFC 4871. ¡Diantres, ahora que se había puesto de acuerdo mucha gente para usar SPF!

DKIM pretende controlar los mensajes haciendo que el servidor de correo del que proceden firme digitalmente los envíos. De esta forma se consigue, en primer lugar, poder verificar el dominio al que pertenece el remitente de un mensaje y, en segundo lugar, asegurar la integridad del mismo permitiendo detectar si el contenido de éste ha sido alterado durante su tiempo de tránsito por el ciberespacio.

Según proponen, para echar a andar DKIM en un servidor de mensajes SMTP, deberían generarse un par de claves, pública y privada. La primera de ellas sería publicada a través del servicio estándar DNS, mientras que la segunda sería utilizada internamente para firmar digitalmente los mensajes.

Cuando un usuario autorizado envía un correo, el servidor generaría la firma del contenido en tiempo real y la añadiría a los encabezados del mensaje. El servidor del destinatario extraería la firma del mensaje y, mediante una consulta al DNS del origen, obtendría su clave pública, con lo que podría verificar la validez de la firma.

De esta forma, en función del resultado de la comprobación, el destinatario podría aplicar políticas locales de filtrado. Por ejemplo, si el dominio origen del mensaje existe y la firma es válida, es probable que se trate de un mensaje que debe ser entregado al destinatario, pero se le podrían pasar filtros basados en contenido para una mayor seguridad. Si la firma no es correcta o no aparece, podrían tomarse medidas de descarte o marcado del mensaje.
El siguiente diagrama muestra esquemáticamente el funcionamiento de DKIM:



¿Y quién anda detrás de este invento? Pues ni más ni menos que Yahoo! (iniciadores del proyecto), Cisco, PGP y Sendmail, y según comenta su inventor, Mark Delany, también han contado con la colaboración de IBM, Earthlink, Microsoft, Spamhaus, Google, PayPal y Alt-N, entre otros.

En resumen, se trata de un nuevo intento para acabar con el envío de mensajes desde destinatarios incorrectos o servidores "no creíbles", basándose esta vez en la utilización de criptografía de clave pública. Si bien no es de por sí una tecnología que resuelva el problema al 100%, sí que podría colaborar mucho. Además, lo más probable es que la solución final sea una combinación de distintas técnicas, así que bienvenida sea.

Particularmente me convence la idea de aplicar técnicas criptográficas para asegurar el correo, así como la utilización de estándares y soluciones colaborativas consensuada entre proveedores. Sin embargo, este último aspecto es su punto más débil: necesita una adopción global para que su efectividad pueda ser razonable.

En cualquier caso, todo esto forma parte de la lógica y necesaria evolución de tecnologías que tiene que acontecer hasta que la humanidad consiga dar con la forma para la eliminación definitiva del spam, phishing, spoofing y otras lindezas virtuales.
domingo, 20 de mayo de 2007
Hace unos días publicaba un paso a paso donde mostraba cómo invocar servicios web desde el cliente utilizando Javascript y las magníficas extensiones ASP.NET 2.0 AJAX, y pudimos ver lo sencillo que resultaba introducir en nuestras páginas web interacciones con el servidor impensables utilizando el modelo tradicional petición-respuesta de página completa.

Sin embargo, la infraestructura Ajax nos brinda otra forma de invocar funcionalidades de servidor sin necesidad de crear servicios web de forma explícita: los métodos de página (Page Methods). El objetivo: permitirnos llamar a métodos estáticos de cualquier página (.aspx) desde el cliente utilizando Javascript y, por supuesto, sin complicarnos mucho la vida. Impresionante, ¿no?

En este post vamos a desarrollar un ejemplo parecido al anterior, en el que tendremos una página web con un cuadro de edición para introducir nuestro nombre y un botón, cuya pulsación mostrará por pantalla el resultado de la invocación de un método del servidor, y todo ello, por supuesto, sin provocar recargas de página completa. El resultado vendrá a ser algo así:


Ah, para que no se diga que soy partidista ;-) esta vez vamos a desarrollarlo en Visual Basic .NET (aunque la traducción a C# de la porción de servidor es directa), y de nuevo con Visual Studio 2005.

En primer lugar, hemos de crear la solución (Visual Studio 2005) basándonos en la plantilla "ASP.NET Ajax-Enabled web application" que habrá aparecido en nuestro entorno tras descargar e instalar las extensiones AJAX. Una vez elegido el nombre, se creará un proyecto con todas las referencias necesarias, el web.config adaptado, y una página (Default.aspx) que viene ya preparada con el ScriptManager listo para su uso.

En el archivo code-behind (Default.aspx.vb) añadimos el siguiente código, que será la función de servidor a la que invocaremos desde el cliente:


<WebMethod()> _
Public Shared Function Saludame(ByVal Nombre As String) As String
Return "Hola a " + Nombre _
+ " desde el servidor, son las " _
+ DateTime.Now.ToString("hh:mm:ss")
End Function


Obsérvese que:
  • El método es público y estático. Lo primero es obvio, puesto que el ScriptManager necesitará mapearlo al cliente y para ello deberá acceder mediante reflexión a sus propiedades, y lo segundo también, puesto que las invocaciones al mismo no se efectuarán desde instancias de la clase, imposibles de conseguir en cliente.

  • Está adornado con un atributo WebMethod, que indica al ScriptManager que el cliente podrá invocarlo utilizando Javascript.

Sólo falta un detalle. Hay que indicar al ScriptManager de la página que se encargue de procesar todos los métodos públicos estáticos de la clase, que además estén marcados con el atributo anteriormente citado, y genere la infraestructura que necesitamos para utilizar de forma directa esta funcionalidad. Esto se consigue estableciendo la propiedad EnablePageMethods a true desde el diseñador.

Estableciendo EnablePageMethods a true
Una vez hecho esto, introducimos en el aspx de la página los elementos de interfaz (el cuadro de texto, el botón y un label para mostrar los resultados). El código del formulario completo queda así:


<form id="form1" runat="server">
<input type="text" id="nombre" />
<input id="Button1" type="button"
value="¡Pulsa!" onclick="llamar();" />
<br />
<strong>Mensajes obtenidos:</strong>
<br />
<label id="lblMensajes" />
<asp:ScriptManager ID="ScriptManager1"
runat="server" EnablePageMethods="True" />
</form>


Podemos ver, como en el post anterior, que todos los controles salvo el ScriptManager son de cliente, no tenemos el runat="server" en ninguno de ellos puesto que no realizaremos un envío de la página completa (postback) en ningún momento, todo se procesará en cliente y actualizaremos únicamente el contenido del label.

Por último, añadimos el script que realizará las llamadas y mostrará los resultados. La función llamar(), invocada a partir de la pulsación del botón y la de notificación de respuesta. El código es el siguiente:

<script type="text/javascript">
function llamar()
{
PageMethods.Saludame($get("nombre").value , OnOK);
}
function OnOK(msg)
{
var etiqueta = $get("lblMensajes");
etiqueta.innerHTML += msg + "<br />";
}
</script>

Primero, fijaos en la forma de llamar a Saludame(). El ScriptManager ha creado una clase llamada PageMethods a través de la cual podemos invocar a todos los métodos de la página de forma directa.

El primer parámetro de la función es $get("nombre").value. Ya vimos el otro día que $get("controlID") es un atajo para obtener una referencia hacia el control cuyo identificador se envía como parámetro. Por tanto, $get("nombre").value obtendrá el texto introducido en el cuadro de edición.

Después de los parámetros propios del método llamado, se indica la función a la que se pasará el control cuando obtenga el resultado desde el servidor. OnOK recibirá como parámetro la respuesta de éste, el string con el mensaje de saludo personalizado, y actualizará el contenido de la etiqueta para mostrarlo.

En resumen, los PageMethods son una interesantísima característica del framework AJAX de Microsoft, y nos permiten llamar a funciones estáticas definidas directamente sobre las páginas aspx, evitando el engorro de definir servicios web (asmx) de forma independiente, y sobre todo, ayudando a mantener en un único punto el código relativo a una página concreta ¡y qué mejor sitio que la propia página!

(Puedes descargar el proyecto completo.)