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, 30 de septiembre de 2007
El otro día comentábamos en mi empresa que podría ser el momento de incorporar un nuevo desarrollador software en el equipo, de contratar a alguien. Esto, que puede resultar rutinario en grandes compañías, es para los que somos pequeños, un auténtico suplicio.

Experiencias anteriores nos han demostrado que los portales de empleo son útiles cuando se trata de ofertas muy específicas a la que acudirán pocos candidatos. Casos más genéricos, como podría ser la contratación de un desarrollador con cierta experiencia bajo unas condiciones aceptables, provocan una entrada masiva de candidatos que hacen de la selección un proceso imposible... ¿qué pequeña empresa puede preseleccionar con tino de entre una lista de cientos de personas, entrevistar físicamente a decenas de personas y encontrar a su candidato ideal?

Esta masificación es la que hace que tengan mayores probabilidades de éxito aquellos candidatos que destacan de alguna forma sobre el resto. Conocimientos técnicos, habilidades, actitudes... son muchas las características interesantes para las empresas, y algunas de ellas son difíciles de demostrar a priori, y más aún usando el habitual curriculum.

Y es justo aquí donde los blogs pueden jugar un papel fundamental. Si estás buscando empleo, se me ocurren al menos diez razones por las que deberías tener tu propio blog e incluirlo en tu currículum como un activo de alto interés:

1. Demuestras tus conocimientos.
Sí, es cierto que tu título debería hacerlo o al menos ser una pista, pero por desgracia no es así. El mero hecho de poseer una ingeniería, titulación técnica o haber realizado cursos específicos no implica un nivel de conocimientos determinado, pues la mayoría de las veces éste se adquiere con la experiencia o de forma autodidacta.

En un blog puedes demostrar tu nivel de conocimientos en los temas que tratas, tus especialidades, preferencias e inquietudes de forma mucho más directa, detallada y creíble de lo que puedes hacer con un currículum tradicional.

2. Demuestras tu facilidad de aprendizaje
Respecto a esto, siempre digo lo mismo: si piensas que vales lo que sabes, estás muy equivocado. Tus conocimientos de hoy no tienen mucho valor más allá de un par de años. Lo que vales es lo que puedes llegar a aprender, la facilidad con la que te adaptas a los cambios que esta profesión nos regala tan frecuentemente.

Tu blog puede demostrar que tienes una actitud positiva frente al aprendizaje.

3. Demuestras pasión por tu profesión
La pasión por tu profesión, por tu trabajo, esa característica tan demandada en el mundo empresarial, viene incluida casi de serie en el blogger. Resulta imposible imaginar a alguien al que no le guste el mundo del desarrollo de software escribiendo varios posts mensuales comentando las nuevas tecnologías que va descubriendo, trucos o cualquier tema relacionado con ello.

El simple hecho de tener un blog ya es un punto a tu favor.

4. Demuestras tu capacidad de trabajo
Un blogger, salvo excepciones (que seguro que hay), es un trabajador nato. Es importante tener en cuenta que cada post requiere un trabajo considerable, sobre todo cuando se genera contenido propio. Existen asimismo otras tareas, como la lectura de fuentes o la gestión de comentarios que pueden llegar a consumir mucho tiempo y esfuerzo. Esto, además, tiene mucho más mérito cuando se hace por gusto (véase el punto 3).

Obviamente, ser trabajador es una característica muy apreciada por la empresa, y tu blog te ayudará a demostrar que lo eres. ;-D

5. Demuestras rasgos importantes de tu personalidad
En cada post que escribes vas dejando un poco de tí mismo; consecuentemente, si sumas muchos de ellos seguro que podríamos unir tantos trocitos que habría información suficiente para psicoanalizarte en profundidad.

Las características personales de los candidatos son aspectos vitales en un proceso de selección. En el mundo del desarrollo, nadie va a contratar a personas conflictivas, violentas, de posturas radicales o de difícil encaje para el trabajo en equipo.

La imagen que transmites en tu blog puede ayudar a las empresas a hacerse una idea de cómo eres y de cómo no.

6. Demuestras tus habilidades literarias
Aunque a veces sea injustamente considerada la parte más tediosa y poco creativa de nuestra profesión, no olvidemos que una buena parte del trabajo de desarrollador consiste, a distintos niveles, en escribir textos. Pantallas, mensajes, ayudas, documentación de código, documentos técnicos, de diseño, análisis o propuestas son sólo algunos ejemplos de las tareas para las que hay que saber redactar apropiadamente. Las faltas de ortografía, o simplemente una redacción pobre en cualquier entregable, dan muy mala imagen de la persona y empresa que los generan.

Tu blog, aparte de ayudarte a cultivar estas virtudes, demuestra cómo podrías hacerlo en el desempeño de tus tareas como profesional, aportando un plus respecto al resto de candidatos que simplemente presentan un currículum.

7. Fortaleces y demuestras tu capacidad de comunicación
Un blog, aunque pueda parecer lo contrario, no es una herramienta de comunicación unidireccional, una palestra donde recitar monólogos: se escribe, se escucha, se debate, se critica, se comparten conocimientos y experiencia.

Ya en su momento, en el post "Entre 10 y 28 desarrolladores por el precio de uno" comenté que una de las características imprescindibles de un buen desarrollador es la capacidad comunicación bidireccional, pues repercute de forma muy positiva en la productividad del equipo de trabajo donde se ubique. Y, ¿qué es un blog sino un potente medio de comunicación?

Tu blog hace que te comuniques, y demuestra la facilidad que tienes para ello.

8. Demuestras tu experiencia, incluso si no la tienes
Está claro que nadie que busque su primer trabajo tiene experiencia; también es cierto que la experiencia es vital para encontrar empleo... ¿cómo salimos de este círculo sin fin?

Hay personas que sin haber salido todavía al mercado laboral, acumulan ya centenares de horas de vuelo. Suelen ocupar sus ratos libres en investigar, probar, aprender, y a veces pueden llegar a alcanzar niveles de dominio de una tecnología increíbles, y que serían muy valiosos en el mundo empresarial. El problema casi siempre es demostrarlo.

Tu blog puede demostrar la experiencia que tienes como desarrollador, independientemente de si has comenzado o no tu carrera profesional. Y si además participas en proyectos de software libre, mucho mejor.

9. Ganas prestigio
Lo mejor para conseguir un puesto de trabajo son, sin duda, las referencias y recomendaciones facilitadas por personas o entidades de confianza. Sin embargo, en un mundo 2.0 como éste, donde somos los usuarios de la red los que vamos aportando nuestro granito de arena a la inteligencia colectiva, no hay mejor aval que la credibilidad y fidelidad de cientos o miles de individuos repartidos por todo el mundo que, día a día, leen, comentan y citan nuestros posts.

Un blog con contenidos medianamente decentes se va haciendo, a la larga, un hueco en la red, aumentando el prestigio y autoridad de su autor.


10. Y sobre todo, destacar
Destacar sobre el resto de candidatos que, como tú, son ingenieros, técnicos, programadores estupendos o grandes expertos en lenguajes de última generación. Es la distinción lo que puede hacer que triunfes, y especialmente si acabas de terminar tus estudios, momento en el que se lanzan al mercado laboral decenas de jóvenes con currículums prácticamente idénticos.

Incluir el blog en tu currículum provocará, como mínimo, la curiosidad de los responsables de las primeras fases de una selección de personal, que probablemente acudirán a comprobar si eres el candidato apropiado.

En fin, espero que estas reflexiones puedan servir para algo; por un lado, motivar a aquellos que todavía no tienen blog para que se atrevan a empezar, y por otro, para animar a los que ya lo tienen y trabajan duro en él. En cualquier caso, tened por seguro que va a valer la pena.
jueves, 27 de septiembre de 2007
Los que vamos evolucionando a la vez que lo hace la plataforma .Net (bueno, unos cuantos pasos por detrás ;-)), a veces se nos hace difícil superar nuestras costumbres y adaptarnos a nuevos métodos o utilidades que, sin duda, vienen para facilitarnos la vida y ofrecen mejores soluciones a problemas comunes que las que utilizamos de forma habitual.

Un ejemplo lo tenemos con los métodos estáticos xxx.Parse(), útiles para convertir de un string a un tipo valor, como puede ser int32 o boolean. Desde el principio de los tiempos usamos, para obtener un entero desde su representación como cadena, construcciones de tipo:
string num = "123";
int i = 0;
try
{
i = int.Parse(num);
}
catch (Exception ex)
{
// TODO: hacer algo...
}

Sin embargo, la llegada de .NET Framework 2.0 supuso la inclusión del método estático TryParse() en la práctica totalidad de tipos primitivos numéricos (en la versión 1.1 sólo existe en el tipo double), cuya forma más simple de utilización (y también más usual) dejaría el bloque try/catch anterior en uno más compacto y legible:

if (!int.TryParse(num, out i))
// TODO: hacer algo...
 
El método TryParse devuelve true si se ha podido realizar la transformación con éxito, dejando en la variable de salida que le indiquemos el valor parseado, en este caso un int.

Sin embargo, además de para evitarnos dolores en las articulaciones de los dedos, existen otros motivos para utilizar xxx.TryParse() en vez de xxx.Parse(): el rendimiento, sobre todo si se prevé que el número de fallos de conversión será relativamente alto en un proceso. De hecho es el método recomendado en la actualidad para realizar estas conversiones.

Según la prueba de rendimiento de TryParse publicada Microsoft, ejecutada sobre su propia plataforma, la utilización de este método aventaja de forma considerable al modelo try-parse-catch. Por ejemplo, realizando varias simulaciones de parsing de enteros sobre un conjunto de 100 cadenas de las cuales 5 son erróneas, el tiempo de proceso llegar a ser mil veces superior usando este último patrón; si asumimos 20 incorrectas (80% de cadenas correctas), el modelo tradicional puede tardar 4.000 veces más que usando TryParse.

Aunque lo normal no es efectuar un gran número de transformaciones de este tipo y esta diferencia de rendimiento podría entenderse despreciable, podría ser un factor a tener en cuenta cuando estas operaciones se realicen en contextos de gran carga de usuarios o concurrencia, como en sitios web de alto tráfico. Ojo pues a esas aplicaciones (o componentes) que hemos tomado de .NET 1.x y estamos reutilizando en las versiones superiores.

Por cierto, todo lo dicho, aunque los ejemplos están codificados en C#, es válido para Visual Basic .NET y cualquier otro lenguaje que compile sobre la plaforma .NET de Microsoft. A ver si un día tengo un rato y compruebo si el comportamiento en Mono es el mismo.
lunes, 24 de septiembre de 2007
Hace unas semanas Miguel de Icaza publicaba en su blog personal un par de ejemplos del tipo de pruebas técnicas que realizan cuando contratan personal, en este caso para el proyecto Mono.

La filosofía es bastante simple, y la verdad es que no carece de sentido: los aspirantes reciben por correo electrónico el "enunciado" de la prueba, y disponen de dos semanas para responder. Aunque el tiempo de respuesta puede parecer excesivo, está pensado para ser realizado por los aspirantes cuando vuelven a casa tras sus jornadas de trabajo o estudio.

Según Miguel, esta técnica le da mejores resultados que las tradicionales entrevistas cara a cara, donde una lectura del currículum y varias preguntas rápidas no permiten conocer en profundidad al candidato. No hay nada como ver planteamientos y código para saber el tipo de desarrollador que tenemos delante.

La prueba para trabajar en el ámbito de Windows.Forms consistía en desarrollar un Control (Widget) y responder una pregunta, y decía más o menos esto (traducción libre):


Desarrollo de un control

Debes implementar un pequeño motor de renderizado para un lenguaje de marcas basado en XML. Este lenguaje acepta las siguientes etiquetas:

<p>...</p>, para definir el inicio y fin de párrafos.

Los párrafos pueden contener en su interior los siguientes tags:

  • <b>...</b>, para poner en negrita el texto
  • <i>...</i>, para poner el texto en cursiva

  • <link>...</link>, para que el texto sea renderizado como un hiperenlace.
  • <blink>...</blink> para que el texto parpadee
El control debe exponer la siguiente propiedad, que permitirá al desarrollador modificar el contenido (en este lenguaje de marcas) de forma programática.

  string Markup { get; set; }
 
Por ejemplo:

  m = new MarkupControl ();
m.Markup = "<p>Hello <b>World</b>!</p>";
 
El control también debe exponer un evento que permita notificar de los clicks del usuario sobre los enlaces (etiqueta <link>), algo así como:

  delegate void LinkClicked (object sender, string link_text);
 
De esta forma, será posible suscribirse al evento usando un código como el siguiente:

  m.LinkClicked += my_clicked;
...

void my_clicked (object sender, string link_text)
{
Console.WriteLine
("The link {0} was clicked", link_text);
}
 
Debes enviar una aplicación completa que se ejecute correctamente en Linux, y debe hacerse uso del evento y la propiedad citados con anterioridad. Por ejemplo, estaría bien tener algo como:

void my_clicked (object sender, string link_text)
{
Console.WriteLine ("Link {0} pulsado", link_text);
((MarkupControl) sender).Markup = "<p>Nuevo <b>texto</b></p>";
}
 
Puntos extra: al usar <blink> será necesario actualizar la vista, se valorará si se evita el parpadeo usando buffers dobles o repintando sólo el área modificada.

Quiero una pequeña y sucinta implementación, pero es tu oportunidad para demostrar que puedes escribir código robusto, así que impresióname.

Pregunta

En nuestra implementación de corlib, en System/DateTime.cs tenemos una implementación no óptima del método TryParse, básicamente invocamos a Parse dentro de un bloque try/catch.

Explica:
  • ¿Por qué digo que nuestra solución no es óptima?

  • ¿Qué debería tener para hacerla más eficiente?

  • ¿Por qué el desarrollador que escribió el código no realizó lo más eficiente?

La trick-question es: ¿por qué el proceso más rápido no se realizó en primer lugar? Explícalo.

¿Que os parece? ¿Podríais entrar a trabajar en el equipo de Mono?
jueves, 20 de septiembre de 2007
Si eres de los que, como yo, piensan que la moda de los bordes redondeados la ha impuesto gente que odia a los programadores y diseñadores de webs, nunca te ha convencido introducir (X)HTML sin carga semántica sólo para poder incluir estas filigranas en las esquinas de los DIVS o elementos de bloque similares, o no soportas crear imágenes redondeadas para las esquinas, es posible que te interese Nifty Corners Cube.

Se trata de una librería Javascript para redondear los bordes de elementos de bloque sin necesidad de crear imágenes ni nada parecido, sólo usando CSS y scripting. Además, no es intrusiva: si un navegador no soporta scripts o se trata de una versión no contemplada, el usuario simplemente verá sus bordes como siempre. Buena pinta, eh?

Y la forma de usarlo, fácil. En primer lugar, una vez descargado el archivo .zip y extraído en un directorio de la web, se coloca la referencia al script sobre la página (X)HTML como siempre:

<script type="text/javascript" src="niftycube.js"></script>


Desde ese momento ya podemos invocar desde Javascript a las funciones de la librería para que actúen sobre los elementos cuya presentación queremos modificar, por ejemplo así:

// Esto hace que al div con id="box"
// se le redondeen los bordes con
// esquinas grandes (10px):

Nifty("div#box","big");



Esta llamada, o mejor dicho, todas las llamadas que necesitemos para ajustar los efectos de nuestra página, pueden situarse en el evento onload de la misma, como se muestra a continuación. De todas formas, la propia librería ofrece un método alternativo, a través de la función NiftyLoad(), para cuando esto no sea posible.


<script type="text/javascript">
window.onload=function(){
Nifty("div.redondeadoGrande","big");
Nifty("div.redondeadoPeque","small");
}
</script>


En la función Nifty, el primer parámetro es el selector CSS al que se aplicará el borde (o efecto) deseado. Si no tienes claro qué es un selector, podrías echarle un vistazo a este post (selectores CSS), este (selectores CSS-II-), y este otro (selectores CSS-III).

Así, si indicamos el selector "div.redondeado" estaremos aplicando el efecto a todos aquellos divs cuya clase sea la indicada (class="redondeado").

El segundo parámetro es una palabra clave, a elegir entre una larga lista de opciones, algunas de ellas combinables. Aunque en la web del autor viene muy bien explicado con ejemplos, :


PalabraSignificado
tlesquina superior izquierda
tresquina superior derecha
blesquina inferior izquierda
bresquina inferior derecha
topesquinas superiores
bottomesquinas inferiores
leftesquinas izquierdas
rightesquinas derechas
all (default)las cuatro esquinas
noneno redondear las esquinas (útil para usar las nifty columns
smallesquinas pequeñas (2px)
normal (default)esquinas normales (5px)
bigesquinas grandes (10px)
transparentpermite crear esquinas transparentes con alias. Se aplica automáticamente cuando el elemento no tiene un color de fondo especificado.
fixed-heightse aplica cuando el elemento tiene un alto fijo especificado en su CSS
same-heightParámetro para nifty columns: todos los elementos identificados por el selector CSS tienen el mismo alto. Si el efecto se utiliza sin bordes redondeados, este parámetro se puede usar en conjunción con la palabra clave none.


En la web del autor hay multitud de ejemplos de uso que demuestran lo fácil que puede llegar a hacernos la vida. Por cierto, también he encontrado una versión en español.

Por último, comentar que la librería se distribuye bajo licencia GNU GPL, y lo podéis descargar en esta dirección.

Hala, a disfrutarlo.



Editado [2/11/07]: Si usas ASP.NET, es posible que te interese NiftyDotNet, un componente que encapsula Nifty Corners Cube para hacer aún más sencillo su uso.
martes, 18 de septiembre de 2007
A raíz de los posts sobre los tipos anulables en .NET (introducción a los nullables y uso tipos anulables con enumeraciones), mi amigo Javi me hizo una pregunta que sólo un friki como él sería capaz de formular ;-): ¿cómo afecta el uso de tipos anulables a la serialización de clases?

Aunque sospechaba la respuesta, he hecho un par de pruebas a través de las cuales, ahora sí, puedo asegurar que no afectan en nada, es decir, el sistema controla perfectamente la forma en que se serializan y deserializan este tipo de valores.

El comportamiento es el siguiente: cuando el tipo anulable contiene un valor no nulo, la serialización la delega en el tipo subyacente. Si es un int?, se realizará la serialización por defecto para el int. Usando un serializador XML, un ejemplo de salida sería:


<?xml version="1.0" encoding="utf-16"?>
<int>10</int>

 

En cambio, cuando se trata de serializar el valor null, el sistema genera una etiqueta que indica este hecho, de la misma forma que lo haría si estuviéramos haciéndolo para un tipo referencia. Un ejemplo de salida XML sería:


<?xml version="1.0" encoding="utf-16"?>
<int xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:nil="true" />

 

En fin, que hoy hemos aprendido una cosa más. Y que no falte. :-)
domingo, 16 de septiembre de 2007
Vía The Server Side acabo de enterarme de la existencia de Quaere, una implementación para Java del proyecto LINQ de Microsoft, creada por Anders Norås.

Se trata de un DSL (Domain Specific Language, lenguaje específico de dominio) que permite integrar dentro de código Java sentencias muy parecidas a SQL para extraer información de arrays, colecciones y otros almacenes de información, de forma muy sencilla y potente. Gracias a la utilización de static imports y fluent interfaces, no es necesario usar preprocesadores o generadores de código intermedios, el código se compila directamente sobre javac importando las librerías de Quaere.

Y para que se entienda mejor el alcance del proyecto y cómo puede ayudarnos a desarrollar, unos ejemplos básicos tomados del blog del autor, que demuestran la potencia de esta extensión para gestión de datos:


// Obtiene los números menores de
// cinco del array:
Integer[] numbers =
{5, 4, 1, 3, 9, 8, 6, 7, 2, 0};

Iterable<integer> lowNums =
from("n").in(numbers).
where(lt("n", 5)).
select("n");



// Obtiene una colección
// de strings con los nombres de
// los productos:
List products =
Arrays.asList(Product.getAllProducts());

Iterable<String> productNames =
from("p").in(products).
select("p.getProductName()");

 
viernes, 14 de septiembre de 2007
De todos es sabido que las enumeraciones son un tipo valor, y se representan internamente como Byte, Int32 u otros tipos primitivos de la plataforma, lo que hace imposible la asignación de valores como null, concebido para los tipos referencia.

Así, en el siguiente ejemplo en C#:

Estado estado1 = Estado.Correcto;
Estado estado2 = null;

La segunda línea provoca el error en compilación "No se puede convertir null en 'ConsoleApplication1.Program.Estado' porque es un tipo de valor". Lógico, es igual que que si intentáramos asignar el maldito valor nulo a un integer.

Esto puede causar ligeras molestias para la gestión de valores "indeterminados", puesto que estaríamos obligados, por ejemplo, a utilizar otro miembro de la enumeración para representar este valor, como en el siguiente código en Visual Basic .Net:

Public Enum Estado
Indeterminado = 0
Correcto = 1
Incorrecto = 2
End Enum

Sin embargo, hay ocasiones en la que resulta más interesante poder disponer del valor nulo como una opción para las variables del tipo de nuestra enumeración. Por ejemplo, si estamos desarrollando componentes que leen de una base de datos donde la indeterminación se representa por un nulo, sería más natural poder trasladar esta particularidad al modelo de objetos.

Y para esto inventaros los tipos anulables, de los que ya publiqué un post hace tiempo (Nullable Types, o cómo convivir con los nulos). Dado que las enumeraciones son tipos valor, nada impide crear tipos anulables de enumeraciones:

' VB.NET
Dim estado1 As Nullable(Of Estado)
Dim estado2 As Nullable(Of Estado)
estado1 = Estado.Correcto
estado2 = Nothing

// C#
Estado? estado1 = Estado.Correcto;
Estado? estado2 = null;

 
miércoles, 12 de septiembre de 2007
Javascript, ese lenguaje tan de moda, nos permite manipular en cliente algunas propiedades de los utilísimos validadores de ASP.Net.

La función ValidatorEnable, proporcionada por la plataforma .Net en cliente y utilizable mediante scripting, nos permite habilitar o deshabilitar validadores de nuestros Webforms sin necesidad de hacer un postback. Un ejemplo de uso sería el siguiente:

function onOff(validatorId, activar)
{
var validator =
document.getElementById(validatorId);
ValidatorEnable(validator, activar);
}

El segundo parámetro sería el booleano (true o false) que indica si se desea activar o desactivar el validador. El primer parámetro es el ID en cliente del mismo, y podemos obtenerlo usando la propiedad ClientID del control; por ejemplo, imaginando que tenemos un validador de tipo RequiredFieldValidator llamado Rfv en nuestro Webform, una llamada a la función anterior sería algo así como:

function algo( )
{
onOff("<%= Rfv.ClientID %>", true);
}

 
lunes, 10 de septiembre de 2007
Hoy seguiremos jugado un poco más con las plantillas de Blogger, y estudiaremos cómo modificar la forma en que este gestor de blogs, sobre el que está montado Variable not found, muestra el mensaje al pie de los posts indicando el número de comentarios de cada entrada, que es bastante soso (al menos en las plantillas por defecto).

Por defecto Blogger nos deja configurar exclusivamente qué texto aparecerá detrás del número de comentarios, es decir, a lo más podríamos hacer que apareciera "3 comentarios, ¡comenta ya!" o mensajes así, pero nunca con lógica dependiente del número, lo cual resulta demasiado lineal y cutre para un blog de renombre como el nuestro ;-)

A lo largo de este post vamos a modificar la plantilla para hacer que se muestre un mensaje cuando no hay ningún comentario, otro distinto cuando hay sólo uno, y otro para el resto de los casos. Esto podríais después complicarlo todo lo que queráis, pero de momento con lo que vamos a ver será suficiente para que podáis empezar a jugar.

En primer lugar he de decir que, al igual que ocurría el otro día cuando tratamos el tema de modificar la forma de aparecer la lista de categorías en Blogger, lo más prudente es hacer una copia de seguridad de la plantilla, pues cualquier paso en falso puede tumbar nuestra bitácora. Por si no viste el post anterior, la forma de hacerlo era accediendo al panel de administración de la herramienta y pulsando el enlace "Descargar plantilla completa" que encontrarás en la pestaña "Plantilla", opción "Edición de HTML".

Una vez realizado el backup, podemos continuar sin peligro.

A continuación, marcamos la casilla "Expandir plantillas de artilugios", que nos permitirá acceder al código fuente completo de los Widgets, que son los elementos, bloques o controles que componen la interfaz de Blogger.

Una vez marcada esta casilla, podemos desplazarnos sobre el texto y buscar una porción de código similar a este, donde se ve claramente el comportamiento por defecto del gestor a la hora de mostrar el número de comentarios de una entrada:
  <b:if cond='data:post.numComments == 1'>
1 <data:commentLabel/>:
<b:else/>
<data:post.numComments/> <data:commentLabelPlural/>:
</b:if>


A simple vista se entiende el comportamiento por defecto del sistema, ¿no? Fijaos que se distingue cuando hay un único comentario para poner la etiqueta en singular, mientras que en resto de casos es en plural.

Si escudriñáis en el código de la plantilla, detectaréis que hay dos puntos donde aparece una porción similar. Uno de ellos es para indicar la presentación en la página principal de vuestro Blog, donde aparece la lista de los últimos posts; el otro es para la página individual de cada post. A efectos prácticos, lo que quiere decir es que podemos establecer reglas diferentes para cada caso, aunque por simplificar un poco el ejemplo no lo haremos aquí.

Pues bien, vamos a modificarlo ligeramente para animar al lector a participar en el blog con sus comentarios. Por cierto, no me gusta mucho moverme en el interior del textarea de Blogger. Prefiero llevarme el código a un editor de texto de mi equipo, y desde ahí manipularlo todo lo que quiera. Una vez he acabado de hacer los cambios, copio y pego sobre el cuadro de edición y listo; o si lo he salvado a mi disco, también podría subirse usando la opción de cargar o subir la plantilla disponible en la parte superior de la pantalla.

En cualquier caso, el nuevo código a incluir sería:
<b:if cond='data:post.numComments == 1'>
Ya hay 1 comentario, ¡participa!
<b:else />
<b:if cond='data:post.numComments == 0'>
No hay comentarios. ¡Sé el primero!
<b:else />
<data:post.numComments/> <data:commentLabelPlural/>:
</b:if>
</b:if>

Como se puede comprobar, si sólo hay un comentario lo indicamos y hacemos un llamamiento directo a la participación del usuario. Si no hay comentario alguno, animamos a ser el primero en comentar, y en el resto de los casos, hacemos como siempre.

Vamos, que ya no hay excusa para que en tu blog no haya participación. ;-D
jueves, 6 de septiembre de 2007
Visitando algunos blogs, me he fijado que aquellos que usamos Blogger sufrimos un pequeño problemilla a la hora de presentar la lista con las etiquetas principales de nuestros posts: mostramos todos los tags, por insignificantes que hayan sido, aunque sólo los hayamos tocado de refilón.

Personalmente, creo que la lista de etiquetas aportan una forma rápida y clara de ver de qué trata principalmente nuestro blog, y no es muy positivo tener una lista interminable de tags, la mayoría de ellos con una única entrada asociada.

Aunque Blogger permite dos formas de verlas, en orden alfabético o según su frecuencia, el resultado es igual de terrible. En el primer caso se entremezclan los tags significativos con los que no lo son; en el segundo, la lista de etiquetas importantes vendría seguida de la lista de tags sin peso, que alargan y hacen más pesada la página innecesariamente.

Sin embargo, el potente sistema de plantilla de Blogger permite "retocar" de forma sencilla este comportamiento. En este caso, vamos a hacer que sólo aparezcan en esta lista los tags que tengan más de una entrada, aunque de la misma manera podríamos hacerlo para incorporar otras lógicas más o menos complejas.

Vamos a ver cómo se hace.

En primer lugar, debemos acceder, desde el panel de Blogger a la opción "Plantilla", seleccionando la subopción "Edición HTML".

Importante antes de seguir: si no lo has hecho ya, no vendría mal realizar una copia de seguridad de tu plantilla actual. Puedes hacerlo simplemente pulsando el enlace "Descargar plantilla completa" que encontrarás en la zona superior de la página. De esta forma, si metes la pata podrás volver a dejarlo todo como estaba. :-)

Ahora, fíjate que aparece un cuadro de edición con el código fuente de la plantilla, aunque debes marcar la casilla "Expandir plantillas de artilugios" para tener acceso a las zonas que necesitamos retocar.

Como ayuda, si os es incómodo manipular el texto sobre el cuadro de edición de la web, podéis copiarlo y pegarlo en vuestro editor favorito. Una vez hechas las modificaciones en el código, se vuelve a pegar sobre Blogger y listo.

El siguiente paso es buscar un texto parecido al siguiente (en mi caso está casi al final del código fuente). Puede no ser igual, pero sí que debe ser muy parecido a:


<b:widget id='Label1' locked='false' title='Categorías' type='Label'>
<b:includable id='main'>
<b:if cond='data:title'>
<h2><data:title/></h2>
</b:if>
<div class='widget-content'>
<ul>
<b:loop values='data:labels' var='label'>
<li>
<b:if cond='data:blog.url == data:label.url'>
<data:label.name/>
<b:else/>
<a expr:href='data:label.url'><data:label.name/></a>
</b:if>
(<data:label.count/>)
</li>
</b:loop>
</ul>
<b:include name='quickedit'/>
</div>
</b:includable>
</b:widget>


A simple vista, se entiende que se trata del Widget (en mi caso su título es "Categorías") que muestra las etiquetas de los posts del blog, iterando sobre el conjunto de labels registrados (loop sobre data:labels), y montando una lista (ul) donde en cada elemento (li) se dibuja la etiqueta (label.name) y el número de veces que aparece (label.count).

Por tanto, lo que queremos hacer es realmente sencillo. Vamos a incluir en el interior del bucle un condicional que realice estas tareas sólo si el número de veces que se utiliza una etiqueta (label.count) es mayor de uno. El resultado, con el nuevo código resaltado es el siguiente:


<b:widget id='Label1' locked='false' title='Categorías' type='Label'>
<b:includable id='main'>
<b:if cond='data:title'>
<h2><data:title/></h2>
</b:if>
<div class='widget-content'>
<ul>
<b:loop values='data:labels' var='label'>
<b:if cond='data:label.count > 1'>
<li>
<b:if cond='data:blog.url == data:label.url'>
<data:label.name/>
<b:else/>
<a expr:href='data:label.url'><data:label.name/></a>
</b:if>
(<data:label.count/>)
</li>
</b:if>
</b:loop>
</ul>
<b:include name='quickedit'/>
</div>
</b:includable>
</b:widget>


Una vez realizado este cambio, podéis previsualizar el resultado usando el botón de "vista previa", y una vez esté todo a vuestro gusto podéis guardarla, pasando desde ese momento a estar activa. Si os aparece algún problema a la hora de previsualizar es posible que hayáis olvidado algún carácter a la hora de copiar y pegar el código: revisadlo detalladamente y seguro que solucionáis el problema. Si, a pesar de todo la cosa se os pone fea, volved a cargar la plantilla que habéis salvado previamente y todo volverá a su estado inicial.

El resultado podéis verlo a la derecha: mi lista de categorías sólo muestra aquellas que tienen más de una entrada. :-)

Espero que os sea de utilidad, o al menos de inspiración para hacer vuestros propios ajustes de Blogger.
miércoles, 5 de septiembre de 2007
Me acabo de encontrar en The Inquirer la siguiente noticia:


Microsoft anuncia Silverlight 1.0 ¡compatible con Linux!
La tecnología pretende competir con Adobe Flash ya ha llegado a su versión 1.0 y está disponible para su descarga y utilización en todo tipo de navegadores. Incluidos los de Linux a través del proyecto Moonlight y del acuerdo entre MS y Novell.

(Seguir leyendo...)



Parece que los chicos de Microsoft y los de Novell (desarrolladores principales de Mono) no se llevan nada mal.
martes, 4 de septiembre de 2007
Esto de que cada navegador utilice su propio dialecto derivado del CSS para indicar atributos, como la transparencia u opacidad de los elementos de una página, tiene su gracia... o mejor pensado, no tiene ninguna gracia.

Menos mal que en CSS-Tricks nos enseñan cómo definirla para que funcionen con prácticamente todos los browsers del universo conocido:
.transparente
{
filter:alpha(opacity=50);
-moz-opacity:0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
}


De esta forma, para hacer que un bloque div (por ejemplo) se convierta en semitransparente (al 50% según el ejemplo anterior), sólo habría que poner:

<div class='transparente'>
... lo que sea
</div>


Obviamente, el nivel de opacidad puede modificarse al valor deseado, siendo el 100% el máximo (totalmente opaco) y 0% el mínimo (totalmente transparente). Ojo, que en la primera línea (filter:alpha...) se usa el rango 0-100 y en las restantes este valor dividido entre cien, es decir, en un rango del 0 al 1.

Eso sí, supongo que los validadores CSS igual se quejan un poco. ;-)
domingo, 2 de septiembre de 2007
Hace unos días Miguel de Icaza hablaba en su blog de la inminente posibilidad de hacer funcionar ASP.Net Ajax sobre Mono, incluso comenta un mensaje de Onur Gumus a la lista de programadores de la plataforma explicando cómo hacerlo en la actualidad con versiones internas.

Todavía tendremos que esperar un poco para poder incorporarlo en producción, pero sin duda es una buena noticia para los que ya disfrutábamos de estas librerías en el framework de Microsoft y esperábamos ansiosamente su implementación en Mono.
¡Y ya estamos de vuelta! Parece que fue ayer cuando me despedía con la alegría de ver un mes de descanso por delante, y casi sin darnos cuenta ha llegado Septiembre, con todo lo que ello implica.

Pero no me refiero exclusivamente a cosas malas, que para recordarlas están los telediarios; también vienen nuevos proyectos, expectativas, ilusiones... todo un año por delante para seguir haciendo lo que nos gusta.

En cuanto a Variable not found, ¡queda oficialmente inaugurada la temporada 07-08!

Nos leemos.