
Dos gadgets para Google Plus |
El único dato importante es el ID de nuestra cuenta que es el que se puede ver en la barra de direcciones al ingresar a Google Plus o en cualquiera página:
https://plus.google.com/00000000000000000000 https://plus.google.com/00000000000000000000/posts
Cualquier ajuste, puede hacerse directamente en ese código ya que los datos son evidentes:
<iframe frameborder="0" border="0" cellspacing="0" src="http://stream.pluswidget.com/google-plus-widget/iframe/106189723444098348646/?width=300&height=500&shell_bg=303941&shell_text=ABC&shell_links=4D90FE&post_bg=303941&post_text=CCC&post_links=ABC&scroll_bg=303941&scroll_handle_text=456" width="300" height="500"></iframe>
Al igual que con la anterior, basta agregar el ID de nuestra cuenta, definir colores, tamaños y tipos de fuente y luego, copair y pegar el código que nos dan:
<script type="text/javascript">mbgc='f5f5f5';ww='320';mbc='cecece';bbc='3F79D5';bmobc='3b71c6';bbgc='4889F0';bmoc='3F79D5';bfc='FFFFFF';bmofc='ffffff';tlc='cecece';tc='6a6a6a';nc='6a6a6a';bc='6a6a6a';l='y';fs='16';fsb='13';bw='100';ff='4';pc='4889F0';b='s'; pid='114786324472347150186';</script> <script type="text/javascript" src="http://widgetsplus.com/google_plus_widget.js"></script>
Selección de botones CSS |
| CSS3 Buttons es un conjunto de 18 estilos con varios colores y formas. | |
| Dolor lorem ipsum | Zardi es una serie de reglas de estilo creadas por Horacio Bella que pueden ser utilizadas parcial o totalmente. |
| Awesome Yellow Button » | Super Awesome Buttons son botones con sombras, aptos para fondos claros u oscuros. |
| Fancy Buttons es complicado pero es para verlo y mirar el código fuente y experimentar. | |
| Try to click me | 10 Nice CSS3 Buttons es interesant porque contiene explicaciones paso a paso |

- Pretty CSS3 Buttons
- GitHub-Style CSS3 Buttons
- We Love Buttons
- Sexy Buttons
- Realistic CSS3 Buttons
- Make CSS3 buttons that are extremely fancy
- Creating a Realistic Looking Button with CSS3
- How To Design A Sexy Button Using CSS
- Better Button and Nav Interactions
- CSS3 Buttons Without Any Images
- CSS3 Gradient Buttons
Youtube Instant Search: Un plugin para JQuery |

Es nuy sencillo de agregar y personalizar. primero, si no la tenemos, debemos agregar la librería jQuery cosa que hacemos colocando esto antes de </head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
<script type='text/javascript'>
//<![CDATA[
$(document).ready(function(){
$(".search_input").focus();
$(".search_input").keyup(function() {
var search_input = $(this).val();
var keyword= encodeURIComponent(search_input);
var yt_url='http://gdata.youtube.com/feeds/api/videos?q='+keyword+'&format=5&max-results=1&v=2&alt=jsonc';
$.ajax({
type: "GET",
url: yt_url,
dataType:"jsonp",
success: function(response){
if(response.data.items){
$.each(response.data.items, function(i,data){
var video_id=data.id;
var video_title=data.title;
var video_viewCount=data.viewCount;
var video_frame="<iframe width='500' height='300' src='http://www.youtube.com/embed/"+video_id+"' frameborder='0' type='text/html'></iframe>";
var final="<div id='title'>"+video_title+"</div><div>"+video_frame+"</div><div id='count'>"+video_viewCount+" Views</div>";
$("#result").html(final);
});
} else {
$("#result").html("<div id='no'>No Video</div>");
}
}
});
});
});
//]]>
</script>Para utilizar el plugin, basta que coloquemos dos DIVs; uno con el control para hacer la búsqueda y otro vacío donde se mostrarán los resultados; estos, los ponemos en cualquier parte donde quisiéramos verlos:
<div id="input_box"> <input type="text" class='search_input' /> </div> <div id="result"></div>
<style>
/* el DIV donde colocamos el buscador */
#input_box {
text-align: center;
width:500px;
}
/* el cuadro de búsqueda */
.search_input {
font-size: 20px;
padding: 5px;
text-align: center;
width: 400px;
}
/* el DIV donde se mostrarán los resultados */
#result {
background-color: #000;
margin-top:25px;
min-height:380px;
width:500px;
}
/* un texto, sólo visible cuando no hay resultados a mostrar */
#no { text-align: center; }
/* el título del video encontrado */
#title {
font-size: 18px;
height: 40px;
line-height: 1;
padding-bottom: 10px;
text-align: center;
}
/* el texto inferior con el contador de YouTube */
#count {
height: 20px;
padding-top: 10px;
text-align: right;
}
</style>
Actualización del botón Google+1 |
Hasta hace un rato, la herramienta sólo mostraba el nuevo código si ingresábamos a ella en idioma inglés.
De todos modos, el nuevo código sólo exige reemplazar el script que se mostraba en esta entrada:
<script src='http://apis.google.com/js/plusone.js' type='text/javascript'> {lang: 'es'} </script><script type="text/javascript">
window.___gcfg = {lang: 'es'};
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
Buzz. Una librería para manejar audio |
Buzz es una pequeña librería de Javascript que fue pensada para poder controlar fácilmente las posibilidades que da la etiqueta AUDIO en los navegadores que las soportan.Pese a su tamaño es muy poderosa porque permite ejecutar los archivos en distintos formatos de modo automático e incorpora una enorme variedad de funciones para controlar su ejecución; la documentación no es abundante pero se puede entender.
Como todas estas nuevas etiquetas, por ahora, nos vemos inmiscuidos en esa lucha de formatos soportados y no soportados, lo que hace que como usuarios, estemos limitados u obligados a, como mínimo, duplicar la información.
En este caso, el script soporta formatos AAC, MP3, OGG y WAV pero, no todos los navegadores soportan los cuatro y por lo tanto, no hay forma de tener un solo archivo de audio y que este se reproduzca siempre:
ACC | MP3 | OGG | WAV |
Una vez alojado el script en un servidor y agregado antes de </head>:
<script type="text/javascript" src="URL_buzz.js"></script><script type'text/javascript'> //<![CDATA[ ....... aquí colocamos el contenido del archivo buzz.js //]]> </script>
var unaudio = new buzz.sound( "URL_archivo.ext");var otroaudio = new buzz.sound( "URL_archivo", { formats: [ "ogg", "mp3" ] });Los formatos aceptados son cuatro así que si dispusiéramos de cuatro archivos, pondríamos: { formats: [ "ogg", "mp3", "aac", "wav" ] }
Por defecto, los audios son pre-cargados y no se ejecutan de modo automático. Llegado el caso, esto puede cambiarse, modificando los parámetros correspondientes, tanto globalmente como para cada archivo en particular.
Todo se maneja con JavaScript así que es simple de usar; siempre, usamos el nombre definido al crear el objeto; esta son algunas de las funciones:
- nombre.play(); comienza a ejecutar el audio
- nombre.pause() pausa la ejecución
- nombre.stop() detiene la ejecución
- nombre.togglePlay() permuta entre play y pause
- nombre.isPaused() devuelve TRUE si se ha pausado
- nombre.isEnded() devuelve TRUE si ha terminado
- nombre.loop() lo ejecuta repetidamente
- nombre.unloop() detiee el loop
- nombre.mute() silencia el audio
- nombre.unmute() vuelve a escucharse
- nombre.toggleMute() permuta entre esos dos estados
- nombre.isMuted() devuelve TRUE si se ha silenciado
- nombre.setVolume(valor) establece el volumen (0 a 100, 80 por defecto)
- nombre.getVolume() devuelve el valor del volumen actual
<script>
var ejemplo = new buzz.sound( "URL_archivo", { formats: [ "ogg", "mp3" ] });
</script><a href="javascript:void(0);" onclick="ejemplo.play();"> PLAY </a> <a href="javascript:void(0);" onclick="ejemplo.pause();"> PAUSE </a> <a href="javascript:void(0);" onclick="ejemplo.stop();"> STOP </a> <a href="javascript:void(0);" onclick="ejemplo.togglePlay();"> TOGGLE AUDIO </a>
nombre.play()nombre.pause()nombre.stop()
<script>
function togglesonido(obj) {
obj.togglePlay();
if (obj.isPaused()) {
document.getElementById("mostrar").innerHTML = "pausado";
} else {
document.getElementById("mostrar").innerHTML = "playing";
}
}
</script>
<a href="javascript:void(0);" onclick="togglesonido(ejemplo);"> FUNCION </a> <span id="mostrar"></span>
Cuando cambiar un color es una tarea imposible |
Obviamente, eso dependerá de cada caso pero, el error más común es no tener en cuenta que ese título también es un enlace y por lo tanto, lo que debe cambiarse no es el color del contenedor sino el color del contenido.
Si el HTML es algo así:
<h3 class="post-title"> <a href="UNA_URL">el texto del título</a> </h3>
En una página web, es común que se defina el estilo de los enlaces de manera genérica y eso, afectará a todos ellos, sin importar donde estén; en este ejemplo, todos serán de color rojo y al poner el cursor encima cambiarán a amarillo:
a, a:visited, a:link { color: red; }
a:hover { color: yellow; }h3 { color: green; }h3 a { color: green; }.post-body a { color: black; }
.sidebar a { color: brown; }
#footer-wrapper a { color: cyan; }.sidebar h2 a { color: green; }
.sidebar li a { color: green; }
.sidebar li a span { color: green; }
Amor Leon |
Un par de gadgets útiles para agregar a GMail |
Para agregar gadgets, lo primero que debemos tener es habilitada la función. Vamos a la Configuración de correo y en la pestaña Labs, buscamos Añadir cualquier gadget mediante URL y la habilitamos.


- Wikipedia permite hacer una búsqueda directa:
http://www.google.com/ig/modules/wikipedia.xml - Google Calculator añade un cuadro que podemos usar como calculadora elemental:
http://calebegg.com/calc.xml - Note permite agregar "notitas":
http://www.google.com/ig/modules/sticky.xml - bit.ly URL shortener es un acortador de direcciones:
http://hosting.gmodules.com/ig/gadgets/file/107368512201818821991/bitly-shortener.xml

Ejemplos de animaciones con CSS |
Ninguno de estos ejemplos utiliza imágenes ni JavaScript.
Meowww!
I'm forever blowing bubbles

CSS3 text shadow generator |

<link href="http://fonts.googleapis.com/css?family=Aclonica:regular" rel="stylesheet" type="text/css" />
<style>
h1{
font-family: 'Aclonica', serif;
color: rgba(0, 174, 239, 0.2);
text-shadow: rgba(0, 0, 30, 0.08) 0px 5px 2px;
}
</style>
La rebeldía del gadget de páginas estáticas |
Hace ya un mes, Ark dejaba un comentario: "¿te has dado cuenta que blogger ahora te añade automaticamente el widget de páginas estáticas cada vez que entras a modificar la plantilla?" y una queja: "Lo mejor no es eso ... Lo mejor es la "solución" que te dan en el foro oficial; te invitan a ocultar el codigo que te han agregado por que sí ..."Pués, aparentemente, el bug no sólo no se ha solucionado sino que se está extendiendo ya que ha llegado a este blog y a la fuerza, el gadget de páginas estáticas se ha adosado a esta plantilla, allá en fondo de la sidebar y cualquier intento de eliminarlo es inútil, se aferra como garrapata y no me quiere abandonar.
Así que, si se encuentran en esta situación, no queda más remedio que ocultarlo; para eso basta colocar lo siguiente antes de </b:skin>:
#PageList1 {display:none;}<b:widget id='PageList1' locked='false' title='Páginas' type='PageList'> <b:includable id='main'> </b:includable> </b:widget>
Optimizar las etiquetas META para Facebook |
Todas esas etiquetas extras son optativas y se basan en el protocolo Open Graph.
Lo primero que debemos hacer es verificar que la etiqueta HTML de nuestra plantilla, tenga agregado lo siguiente; en las plantillas comunes:
<html xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr' xmlns:fb='http://www.facebook.com/2008/fbml' xmlns:og='http://opengraphprotocol.org/schema/'><html b:version='2' class='v2' expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr' xmlns:og='http://opengraphprotocol.org/schema/'><meta content='EL NOMBRE DEL SITIO' property='og:site_name'/> <meta content='EL NOMBRE DEL AUTOR' property='og:author'/>
<meta content='ID_CUENTA_FACEBOOK' property='fb:admins'/> <meta content='ID_APLICACION' property='fb:app_id'/>
<meta expr:content='data:blog.url' property='og:url'/>
<b:if cond='data:blog.pageType == "item"'>
<!-- las entradas individuales -->
<meta expr:content='data:blog.pageName' property='og:title'/>
<meta property="og:type" content="article"/>
<!--
lamentablemente, no podemos acceder a un resumen de las entradas
así podemos poner una descripción cualquiera o repetir el título de la entrada o mezclar ambas cosas
-->
<meta expr:content='data:blog.pageName + ". una breve descripción del sitio"' property='og:description'/>
<!--
acá debería ir la imagen que nosotros decidimos mostrar para acompañar la entrada
pero, ese es otro dato al que no podemos acceder
-->
<b:else/>
<!-- cualquier otra página -->
<meta expr:content='data:blog.title' property='og:title'/>
<meta content='blog' property='og:type'/>
<meta content='acá ponemos una breve descipcion de nuestro sitio' property='og:description'/>
<meta content='URL_IMAGENxDEFECTO' property='og:image'/>
</b:if>
Acordeones y transiciones |
Un acordeón no es mucho más que una serie de enlaces que nos permiten mostrar y ocultar contenidos de tal manera que sólo uno de ellos es visible; cuando se muestra el seleccionado, los demás se ocultan y de ese modo, el espacio utilizado se optimiza.
Hay muchos métodos para crear esto y este sólo es una demostración del concepto básico.
<div id="demoA">
<a onclick="demoacordeon('primero');" href="javascript:void(0);">primero</a>
<div id="primero" class="visible">
<p> ....... el contenido ....... </p>
</div>
<a onclick="demoacordeon('segundo');" href="javascript:void(0);">segundo</a>
<div id="segundo" class="novisible">
<p> ....... el contenido ....... </p>
</div>
<a onclick="demoacordeon('tercero');" href="javascript:void(0);">tercero</a>
<div id="tercero" class="novisible">
<p> ....... el contenido ....... </p>
</div>
</div><script>
//<![CDATA[
var abierto = "primero"; // definimos el que estará abierto
function demoacordeon(cual) {
var mostrar = document.getElementById(cual); // el que vamos a mostrar
var actual = document.getElementById(abierto); // el que vamos a ocultar
if(mostrar==actual) {return false;} // si es el mismo no hacemos nada
// permutamos sus clases
actual.className="novisible";
mostrar.className="visible";
abierto = cual; // guardamos el que está abierto
}
//]]>
</script><style>
#demoA { /* al div contenedor lo dimensionamos y centramos */
margin: 0 auto;
width: 500px;
}
#demoA a { /* establecemos las propeidades de los enlaces o botones */
background-color: #456;
box-shadow: 0 0 4px #ABC inset;
display: block;
font-size: 16px;
height: 2em;
line-height: 2em;
margin: 1px 0;
padding-left: 20px;
}
#demoA a:hover {
box-shadow: 0 0 12px #ABC inset;
color: #EEE;
}
#demoA div { /* los contenidos */
overflow:hidden;
text-align: center;
/* cada cambio se realizará con un efecto animado ¨*/
-moz-transition: all 1s ease-in-out;
-webkit-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
#demoA div.visible {
/* el visible tiene borde y una cierta altura */
border: 1px solid #456;
height:100px;
}
#demoA div.novisible {
/* el oculto no tiene borde y su altura es cero */
border: 1px solid transparent;
height:0px;
}
</style>Proin consequat, justo quis ultrices vestibulum, lorem mi porttitor justo, et tristique magna ipsum sit amet ligula. Aliquam ante libero, imperdiet a sollicitudin commodo, iaculis at nunc? Proin luctus, diam nec semper ultrices, purus quam accumsan purus, ac sodales nunc odio in tellus.
Proin consequat, justo quis ultrices vestibulum, lorem mi porttitor justo, et tristique magna ipsum sit amet ligula. Aliquam ante libero, imperdiet a sollicitudin commodo, iaculis at nunc? Proin luctus, diam nec semper ultrices, purus quam accumsan purus, ac sodales nunc odio in tellus.
Suspendisse a ipsum nisi. Vestibulum a sapien sem, eu ultricies tellus. Vestibulum arcu diam, varius in malesuada ut, lacinia nec turpis. Aliquam erat volutpat. Duis vitae magna at nunc ornare facilisis quis eu augue. Curabitur ut urna nulla! Donec in enim ac ligula malesuada cursus.
In lovin' melody |
Funny Icons |
Blogger deja de soportar navegadores antigüos |
Esto es algo que afectará particularmente a quienes aún utilizan Internet Explorer 7 pero, incluye a Firefox 3.5 y Safari 3. No hay información respecto a Opera y offcourse, no hacen ninguna mención a Chrome.
De este modo, la empresa de Google se pone a tono con lo que ya viene haciendo con otros servicios como GMail y Google Docs.
La información agrega que, cada vez que salga una nueva versión de cualquier navegador, de manera automática, dejará de darse soporte a la versión más antigua:
"Each time a new version is released, we’ll begin supporting the update and stop supporting the third-oldest version."
Así que, quien esté en esas condiciones, que comience a pensar en instalar una nueva versión o tendrá serios problemas para acceder al escritorio Blogger.
Mostrar y ocultar gadgets con efectos |
Voy a usar el mismo esquema de la entrada anterior para crear ese efecto usando transiciones así que, desde ya, ese efecto no será visible en Internet Explorer pero, el sistema seguirá funcionando perfectamente así que no hay motivo para no intentarlo.
Lo que hacen las transiciones es animar el cambio de una propiedad; es decir, si algo es de color rojo y cambia a color azul, ese cambio no será instantáneo sino que durará cierto tiempo creándose estados intermedios y el color virará desde un rojo a un azul produciendo un efecto de animación. El problema a resolver en este caso es que si permutamos entre display:none y display:block no hay estados intermedios; algo se ve o no se ve y no hay otra posibilidad. Necesitamos usar alguna otra propiedad que podamos variar poco a poco y la única que sirve para eso es height. Esto sería sencillo si funcionaran los porcentajes pero, no es así, hay que saber la altura exacta y expresarla en pixeles.
Cualquier etiqueta de bloque a la que le ponemos la propiedad overflow:hidden y establecemos el valor de height, no se mostrará "completa" si su contenido supera ese valor:
Hay un dato que nos da JavaScript: el alto de cualquier elemento visible. Ese dato se lee con clientHeight pero, el elemento debe estar visible y si está visible se arruina el efecto así que lo que se me ocurre es cargarlo fuera de la ventana del navegador, guardar su altura y luego moverlo a su lugar pero dándole una altura de cero con lo cual, quedará oculto.
¿Complicado? Hay más. A esto le sumamos otro problema. Hay gadgets que varían de tamaño cuando interactuamos con ellos. Por ejemplo, el de Archivos que se expande y contrae mostrando más o menos resultados, Si no contemplamos eso, hay partes que quedarán ocultas así que, de alguna manera, hay que detectar esos cambios, permitirlos y volver a re-calcular la altura.
Todo eso, hay que dejárselo al script para que lo que nosotros debamos modificar en la plantilla sea lo mínimo posible.
Voy a hacer lo mismo que hice antes, voy a agregarle una clase a la etiqueta H2 del título y unac clase al DIV inferior de cualquier gadget:
<h2 class='expcon'><data:title/></h2> <div class='widget-temp'> .............. </div>
<style>
h2.expcon {cursor: pointer;}
.widget-con {
height: 0px;
width: 250px;
overflow: hidden;
-moz-transition: height 1s;
-webkit-transition: height 1s;
-o-transition: height 1s;
transition: height 1s;
}
.widget-temp {
position:absolute;
left: -5000px;
width: 250px;
}
</style>Aquí hay dos ejemplos simulaciones; el de la izquierda sería un gadget de altura estática y el de la derecha posee enlaces internos que pueden expandirse y colapsarse de manera independiente:
primer ejemplo
Aenean sed est sit amet dolor pellentesque ullamcorper. Mauris ac sapien vel nibh scelerisque tincidunt. In ac nisl quis leo dapibus gravida at id quam. Donec eget nisi nec purus accumsan gravida. Fusce imperdiet sem eu quam sagittis porta. Maecenas luctus porttitor sem in venenatis. Nullam fermentum euismod tristique. Sed massa lorem, pellentesque non malesuada eu; dignissim sed mauris. Etiam venenatis dictum dolor id vestibulum? Cras euismod; lacus a laoreet laoreet, justo magna porta ante, a lobortis nisi neque in lectus. Nam ultricies aliquet mauris at dictum. Proin dapibus velit quis nibh tristique dapibus.
segundo ejemplo
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.


Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
<script type='text/javascript'>
//<![CDATA[
// agrega un ID a la etiqueta si se usa Internet Explorer: http://www.codingforums.com/archive/index.php/t-125144.html
var IEelem={};
function IEaddID(fn,uniqueID) {
return function(event) {return fn.call(IEelem[uniqueID],event);}
}
// esta es la función que agregará el evento onclick
function agregarEVENTOtogglewidget() {
// creo una lista con todas las etiquetas H2
var el = document.getElementsByTagName("h2");
// leo la lista una por una
for (var i=0; i<el.length; i++) {
var c = el[i].className; // guardo el contenido del atributo class expcon
// si es una etiqueta H2 con la clase que definí, le agrego un evento que ejecute una función a la que llamo togglewidget
if (c=="expcon") {
if (el[i].addEventListener) {
// Firefox, Chrome, Opera, IE9
el[i].addEventListener("click", togglewidget, false);
} else if (el[i].attachEvent) {
// Internet Explore 8
var uniqueID = el[i].uniqueID;IEelem[uniqueID] = el[i];
el[i].attachEvent("onclick",IEaddID(togglewidget,uniqueID));
}
// busco la etiqueta DIV
var obj = el[i].nextElementSibling || el[i].nextSibling;
obj.altura = obj.clientHeight; // guardo su altura
obj.className = "widget-con"; // le cambio la clase
obj.style.height = "0px"; // la oculto
// y agrego otro evento a ese DIV de tal forma de poder recalcular su altura cuando cambie
if (obj.addEventListener) {
obj.addEventListener("click", recalcular, false);
} else if (el[i].attachEvent) {
var uniqueID = obj.uniqueID;IEelem[uniqueID] = obj;
obj.attachEvent("onclick",IEaddID(recalcular,uniqueID));
}
}
}
}
// esta es la función que permuta el contenido
function togglewidget() {
// hice click en la etiqueta H2 pero, debo ocultar la etiqueta DIV que es la siguiente; así que a busco:
var obj = this.nextElementSibling || this.nextSibling;
if(obj.style.height=="0px") {
// esta oculta así que la muestro
obj.style.height = obj.altura + "px";
} else {
// esta visible así que la oculto
obj.style.height = "0px";
}
}
// esta es la función que recalcula la altura
function recalcular() {
// se pone al 100% para permitir que se expanda verticalmente
this.style.height = "100%";
// se ejecuta una demora para que se efectivice ese cambio
// cambiar 200 por un número mayor si el contenido es "pesado"
var _this = this;
setTimeout(function() {
// y se guarda la nueva altura
_this.altura = _this.clientHeight;
_this.style.height = _this.altura + "px";
}, 200);
}
// una vez que la página web se carga, ejecuto la función
onload=function() { agregarEVENTOtogglewidget(); }
//]]>
</script>
Mostrar y ocultar gadgets de la sidebar de Blogger |
No es algo facil de responder, no porque sea difícil de hacer sino porque hay cientos de variantes; con y sin librerías, con y sin efectos y todas ellas requieren scripts de alguna clase y modificar o adaptar algo de nuestra plantilla; eso es inevitable; si alguien pretende implementar algo similar, deberá hacerlo con cuidado y tratando de entender lo que hace, aunque sea, minimamente.
En Blogger, todos los widgets o gadgets o cómo se los quiera llamar, tienen la misma estructura básica:
<b:widget id='ALGO' locked='false' title='Indice' type='TIPO'> <b:includable id='main'> <b:if cond='data:title'> <h2><data:title/></h2> </b:if> <div class='widget-content'> ....... </div> </b:includable> </b:widget>
Algunos widgets tienen un DIV distinto, con varias clases o con un ID pero para esto, esos detalles carecen de importancia:
<div expr:class='&Mquot;widget-content " + data:display + "-label-widget-content"'> <div class='widget-content' expr:id='data:widget.instanceId + "_feedItemListDisplay"'> <div class='widget-content popular-posts'>
El script sería algo así:
<script type='text/javascript'>
//<![CDATA[
function SINO(cual) {
var elElemento=document.getElementById(cual);
if(elElemento.style.display == 'block') {
elElemento.style.display = 'none';
} else {
elElemento.style.display = 'block';
}
}
//]]>
</script><h2 onclick='SINO("permutar")'><data:title/></h2> <div class='widget-content' id='permutar' style='display:none;'> ....... </div>
Pero, JavaScript permite que hagamos lo mismo de modo más automático, para eso están addEventListener y attachEvent que son la forma de agregar esos eventos (onclick por ejemplo) en ciertas etiquetas, sin tener que escribir eso atributos ni agregar IDs. Para eso, siempre necesitamos modificar la plantilla porque, de alguna manera debemos indicarle cuáles son las que queremos manipular. Pero, como queremos que sea algo mucho más genérico, en lugar de usar IDs, usamos clases.
Entonces, en cualquier widget de Blogger:
<h2 class='expcon'><data:title/></h2> <div class='widget-con'> .............. </div>
Si no se quiere hacer esto y se quieren mantener las etiquetas existente (por las dudas) podemos agregar un DIV de este modo:
<h2 class='expcon'><data:title/></h2> <div class='widget-con'> <div class='widget-content'> .............. </div> </div>
<script type='text/javascript'> //<![CDATA[ // agrega un ID a la etiqueta si se usa Internet Explorer // http://www.codingforums.com/archive/index.php/t-125144.html var IEelem={}; function IEaddID(fn,uniqueID) { return function(event) {return fn.call(IEelem[uniqueID],event);} } // esta es la función que agregará el evento onclick function agregarEVENTO() { // creo una lista con todas las etiquetas H2 var el = document.getElementsByTagName("h2"); // leo la lista una por una for (var i=0; i<el.length; i++) { var c = el[i].className; // leo el contenido del atributo class // si es una etiqueta H2 con la clase que definí (expcon) // le agrego un evento que ejecute una función a la que llamo togglewidget if (c=="expcon") { if (el[i].addEventListener) { // Firefox, Chrome, Opera, IE9 el[i].addEventListener("click", togglewidget, false); } else if (el[i].attachEvent) { // Internet Explore 8 var uniqueID = el[i].uniqueID;IEelem[uniqueID] = el[i]; el[i].attachEvent("onclick",IEaddID(togglewidget,uniqueID)); } } } } // y esta es la función que permuta el contenido function togglewidget() { // hice click en la etiqueta H2 pero, debo ocultar la etiqueta DIV que es la siguiente; así que la busco var obj = this.nextElementSibling || this.nextSibling; // y le invierto la clase if(obj.className=="widget-con") { // esta oculta así que la muestro obj.className = "widget-exp"; } else { // esta visible así que la oculto obj.className = "widget-con"; } } // una vez que la página web se carga, ejecuto la función onload=function() { agregarEVENTO(); } //]]> </script>
<style>
h2.expcon { cursor: pointer; }
.widget-exp { display: block; }
.widget-con { display: none; }
</style>Es verdad que en lugar de cambiar la clase podría cambiar la propiedad display pero, perfiero que quede así ya que esto, me permitirá agregar efectos ... otro dia.
Seguimos alineando verticalmente |

Curabitur sed mauris purus, pulvinar dictum metus.
Hola

Pulvinar dictum metus.
El CSS posee otra posibilidad que es usar tablas sin tablas ya que entre los nuevos valores aceptados para la propiedad display, hay dos en particular que nos facilitan las cosas: display:table y display:table-cell sobre las que algua vez he hablado pero, sobre las que vale la pena seguir insistiendo ya que su uso no está muy difundido.
Primero, voy a definir dos clases; una para el contenedor y otra para el contenido:
<style>
.contenedor {
display:table; /* esta es la propiedad clave */
/* todas las demás propiedades son optativas */
}
.contenido {
display:table-cell; /* esta es la propiedad clave */
text-align:center; /* esto centra el contenido horizontalmente */
vertical-align:middle; /* esto centra el contenido verticalmente */
/* todas las demás propiedades son optativas */
}
</style><div class="contenedor"> <div class="contenido"> ....... cualquier contenido ....... </div> </div>

Curabitur sed mauris purus, pulvinar dictum metus.
<div class="contenedor"> <div class="contenido"> ....... cualquier contenido ....... </div> <div class="contenido"> ....... cualquier contenido ....... </div> </div>

Curabitur sed mauris purus, pulvinar dictum metus.

Pulvinar dictum metus.
<div class="contenedor"> <div class="contenido"> ....... cualquier contenido ....... </div> <div class="contenido"> ....... cualquier contenido ....... </div> <div class="contenido"> ....... cualquier contenido ....... </div> </div>

Curabitur sed mauris purus, pulvinar dictum metus.
Hola

Pulvinar dictum metus.
Editar plantillas en el nuevo diseño de Blogger |
En lo personal, me resulta muy incómodo; todo está "lejos" y lo que más me interesa está escondido allá en el fondo del barril; me refiero a la edición de plantillas.
Hacer ese largo viaje hasta allí es molesto así que primero que nada, uno puede agregarlo a los marcadores para evitarse el trabajo; la URL es siempre del mismo tipo y sólo cambia el numerito que identifica a cada blog:
http://draft.blogger.com/blogger.g?blogID=0000000#template
Pero, eso solo no basta. Para llegar al editor hay que ir hasta abajo de todo, salteándose las plantillas de nuevo estilo que se nos cruzan en el camino como vendedores callejeros y luego, hacer click en el enlace correspondiente que nos despliega una cosita chiquitita donde apenas entran unas cuantas líneas ... desde ya, todo esto, merece mi caluroso aplauso a los desarrolladores que esta vez se han superado; uno creía que no podían hacerlo peor pero ¡lo han logrado!!!
En fin, algo hay que hacer y entonces es cuando aparece Stylish que no es otra cosa que una extensión para Firefox y Chrome que nos permite personalizar las páginas web a nuestro gusto, utilizando sólo CSS.Una vez instalado, lo veremos en la barra de estado o donde lo hayamos colocado. Ahora, podemos hacer dos cosas, o creamos un estilo para personalizar esa parte en todos nuestros blogs o creamos uno solo para un blog determinado; es indistinto ya que los estilos personales se activan y desactivan con un simple click sin tener que recargar las páginas.

@namespace url(http://www.w3.org/1999/xhtml);
@-moz-document url("http://draft.blogger.com/blogger.g?blogID=0000000#template") {
}@namespace url(http://www.w3.org/1999/xhtml);
@-moz-document url("http://draft.blogger.com/blogger.g?blogID=*#template") {
}
div.GC5D1NMFJB {display:none;}
div.GC5D1NMEJB {display:none;}
div.GC5D1NMHIB {display:none;}
div.GC5D1NMEP {display:none;}
div.GC5D1NMMIB {display:block !important;}
div.GC5D1NMOIB textarea {
font-family: Arial !important;
font-size: 12px !important;
height:600px;
}Esto es lo que se personaliza que no son otra cosa que algunos DIVs de la página de Blogger que, eventualmente, como se trata de un sitio en proceso de desarrollo, pueden cambiar.
Todo estilo agregado es fácilmente editable e incluso se pueden desactivar temporalmente, tanto desde el ícono de la extensión como desde el menú Herramientas del navegador.

La letra A |
Hand Drawn Web Icon Set |
Google y los perfiles privados |
Esos perfiles podían ser privados o públicos pero eso ha cambiado y a partir del 31 de julio, todos los perfiles deberán ser públicos o serán eliminados.
Es probable que, si alguien tiene un perfil privado, Google envie un email informando de este cambio.
¿Que significa esto y en que nos afecta?
Hay ciertas certezas y algunas dudas. Para tranquilizar a quienes preguntan del tema, NO es obligatorio tener un perfil publico para mantener nuestras cuentas de Blogger, GMail o Picasa; estas, seguirán siendo accesibles y no sufrirán cambios por lo tanto, quien así lo prefiera, puede ignorar todo esto y ni siquiera debe molestarse en eliminarlo ya que todo perfil que no sea público, será eliminado por Google lo que no implica que en cualquier otro momento, pueda ser creado otra vez.
El resto de los detalles puede ser consultado en las distintas páginas de ayuda de Google pero acá va un resumen de aquellas que me parecen importantes.

La visibilidad de esta información puede ser modificada cuantas veces se quiera pero es importante tener en cuenta que, si se cambia el nombre del perfil, automáticamente se cambia el nombre en la cuenta de Google y este tipo de modificación afecta a todos los productos; por el contrario, si se borra el perfil, las cuentas seguirán existiendo.
Cada perfil posee una URL; originalmente era de tipo:
https://profiles.google.com/u/0/000000000000000
pero tiende a cambiar por algo así:
https://plus.google.com/000000000000000/
Esa dirección URL tambien es pública y, por defecto, se indexa por lo que puede ser accesible a través de los motores de búsqueda, cosa que puede ser modificada en cuyo caso, el perfil seguirá siendo visible para quienes la conozcan pero, sitios web, blogs y productos de Google, como Álbumes web de Picasa) que enlazan con tu perfil aún pueden aparecer en los resultados de búsqueda de Google y de otros motores.
Moraleja: No está claro cuáles son los productos donde sea necesario el uso de un perfil. Se sabe que para Google+ y Google Buzz serán obligatorios y que para GMail y Blogger no pero, hay otros como Google Reader donde eso es poco claro ya que, aparentemente, también requerirán que el perfil sea público o no podrán usarse.
Fechas relativas en Blogger |
Una fecha relativa, en lugar de mostrar dia, mes y año de cierta entrada, lo que indica es el tiempo transcurrido desde su publicación hasta el momento actual; por ejemplo: "hace 2 minutos" o "dos dias atrás" o "hace un año"; cualquier texto que a uno se le ocurra.
Quienes usan Wordpress disponen de muchos plugins ya pensados para eso (la mayoría en inglés, of course) pero, en Blogger no es algo que se vea muy seguido. En Blog and Web hay una explicación de cómo hacerlo en este tipo de blogs y se trata de una adaptación de, justamente, un plugin de WordPress. Basándome en eso, vamos a ver si se pueden generar otras posibilidades.
Lo primero que pienso es que, para que este tipo de cosas funcione correctamente lo que debo usar es una fecha perfecta ¿A qué me refiero? A que JavaSprit posee muchas funciones para manejar fechas pero si quiero hacer un cálculo preciso, necesito un formato de fecha de esos que, a primera vista, es completamente ilegible así que no puedo usar ni <data:post.dateHeader/> ni <data:post.timestamp/> que son los dos datos que puedo configurar, tanto en el blog como en el widget de las entradas; necesito otro que no usamos nunca pero que está allí y se llama: <data:post.timestampISO8601/>
Ese dato me dará como resultado una fecha de este tipo:
2010-03-25T15:30:20-03:00
¿Que es eso? El año, el mes, el dia; seguido de la letra T que indica la hora, los minutos y los segundos, seguido de un valor (-03:00 en mi caso) que es la Zona Horaria establecida en Configuración | Formato.

Suponiendo que la variable dato contenga esa fecha :
// la fecha y hora de publicación del post, expresada en segundos
var fechapost = new Date(dato).getTime()/1000;
// la fecha y hora actual expresada en segundos
var ahora = new Date().getTime()/1000;
// si la fecha es mayor que "ahora" es un post con fecha futura así que debería hacer algo distinto o no hacer nada
if(fechapost>ahora) { return; }
// estos son los segundos transcurridos entre el momento actual y el momento en que se publicó el post
var segundos = ahora - fechapost;var calctiempo = segundos;
var salida = "";
var bucle = 6;
var t;
var p = [];
p['año'] = 31536000;
p['semana'] = 604800;
p['dia'] = 86400;
p['hora'] = 3600;
p['minuto'] = 60;
p['segundo'] = 1;
for(var periodo in p) {
var valor = p[periodo];
if(calctiempo>=valor) {
t = Math.floor(calctiempo/valor);
calctiempo%=valor;
salida += t; // es el valor
salida += " "; // un caracter espacio
salida += periodo; // el texto
if(t>1){ salida += "s"; } // los plurales
}
salida += " "; // otro caracter espacio
bucle--;
if(bucle==0){ break; }
}
document.write(salida);2 dias 17 horas 59 minutos 10 segundos
Ahora bien, sería mejor usar algo menos matemático y poner textos más humanos, ya sea "hace instantes", "hace más de un hora" o "hace tanto tiempo que ya no me acuerdo". Para eso puede usarse el mismo tipo de esquema que utilizan los scripts de Twitter así me voy a crear una función similar donde, usando aritmética, podamos ir estableciendo fracciones de tiempo a gusto de cada uno; nada grave, por ejemplo:
minutos = segundos / 60
horas = segundos / 60*60 = segundos / 3600
dias = segundos / 60*60*24 = segundos / 86400
semanas = segundos / 60*60*24*7 = segundos / 604800
Los meses ya son complicados de calcular así que voy por lo fácil, hago de cuenta que todos tienen 31 dias y a otra cosa:
meses = segundos / 60*60*24*31 = segundos / 2678400
Algo similar pasaría con los años bisiestos pero acá no se trata de precisión sino de redondeos así que:
años = segundos / 60*60*24*365 = segundos / 31536000
La función que pongo antes de </head>
<script type='text/javascript'>
//<![CDATA[
function fecharelativa(dato) {
var fechapost = new Date(dato).getTime()/1000; // fecha y hora de la publicación
var ahora = new Date().getTime()/1000; // fecha y hora actual
if(fechapost>ahora) { return; } // si la fecha es incongruente no hago nada
// los segundos transcurridos entre esas dos fechas
var segundos = ahora - fechapost;
// calculo toods los datos
var minutos = (parseInt(segundos / 60)).toString();
var horas = (parseInt(segundos / 3600)).toString();
var dias = (parseInt(segundos / 86400)).toString();
var semanas = (parseInt(segundos / 604800)).toString();
var meses = (parseInt(segundos / 2678400)).toString();
var anios = (parseInt(segundos / 31536000)).toString();
// y comienzo a armar lo que será el texto teneindo en cuenta que debo redondear ciertas fracciones
var salida = "";
if (minutos < 1) { // menos de un minuto
salida = "hace menos de un minuto";
} else if(minutos == 1) { // un minuto y algo más, menos de dos minutos
salida = "hace poco más de un minuto";
} else if(horas < 1) { // menos de una hora
salida = "hace " + minutos + " minutos";
} else if(horas == 1) { // una hora y algo más, menos de dos horas
salida = "hace poco más de una hora";
} else if(dias < 1) { // menos de un dia
salida = "hace " + horas + " horas";
} else if(dias == 1) { // un dia y algo más, menos de dos dias
salida = "hace poco más de un dia";
} else if(semanas < 1) { // menos de una semana
salida = "hace menos de una semana";
} else if(semanas == 1) { // una semana y algo más, menos de dos semanas
salida = "hace una semana";
} else if(meses < 1) { // aproximadamente menos de un mes
salida = "hace " + dias + " días";
} else if(meses == 1) { // un mes ... con un cierto margen
salida = "hace un mes";
} else if(anios < 1) { // menos de un año
salida = "hace " + meses + " meses";
} else if(anios == 1) { // aproximadamente un año
salida = "hace un año";
} else { // más de un año
salida = "hace " + anios + " años";
}
// y escribo ese texto
document.write(salida);
}
//]]>
</script>Publicado por <data:post.author/>
<script type='text/javascript'>fecharelativa('<data:post.timestampISO8601/>');</script>
Como no voy a usar este esquema de fechas de entradas, no hay un ejemplo pero, no sólo es posible utilizarlo para mostrar la fecha de las entradas, también podríamos usarlo para mostrar la fecha de los comentarios que suele ser uno de esos datos que uno no personaliza y en el que solemos ver la hora.
Para esto, el script es exactamente el mismo pero, debo ir a Configuración | Comentarios y establecer un formato de fecha adecuado; en este caso, elijo este que es el más completo:

<dd class='comment-footer'>
<span class='comment-timestamp'>
<a expr:href='"#comment-" + data:comment.id' rel='nofollow' title='comment permalink'><data:comment.timestamp/></a>
<b:include data='comment' name='commentDeleteIcon'/>
</span>
</dd><script type="text/javascript">fecharelativa('<data:comment.timestamp/>');</script>
¿Qué es transform-origin? |
Si bien todos los navegadores modernos aceptan la propiedad, por ahora, cada uno de ellos utiliza prefijos propios:
-moz-transform para Firefox -webkit-transform para Chrome y Safari -o-transform para Opera -ms-transform para Internet Explorer 9


-moz-transform-origin -webkit-transform-origin -o-transform-origin -ms-transform-origin
El orden es el mismo que en todas las otras propiedades, el primero indica la coordenada horizontal y el segundo la vertical. Así que si pusieramos 0 0 o left top, cambiaríamos el punto de origen al ángulo superior izquierdo (que es como funcionan los filtros de IE):


transform-origin: center center o transform-origin: 50% 50% es el centro y el valor por defecto
transform-origin: left top o transform-origin: 0% 0% es el ángulo superior izquierdo
transform-origin: right top o transform-origin: 100% 0 es el ángulo superior derecho
transform-origin: left bottom o transform-origin: 0% 100% es el ángulo inferior izquierdo
transform-origin: right bottom o transform-origin: 100% 100% es el ángulo inferior derecho
| center top | center bottom | left center | right center |
![]() | ![]() | ![]() | ![]() |






















