Creating Categories in Blogger

Monday, August 07, 2006

Categorías dinámicas con Blogger

Presento a continuación una forma de crear categorías en los posts de Blogger. La idea se basa en el artículo How can I make show/hide links for my posts? aparecido en Blogger Help. Las entradas en el blog que pertenezcan a la categoría seleccionada se mostrarán y el resto se ocultan dinámicamente. Se puede saltar fácilmente de una categoría a otra. Un ejemplo de cómo funciona puede verse en mi otro blog: biominds.blogspot.com.

En primer lugar, se definen dos clases en la hoja de estilos (CSS), entre las tags o etiquetas <style> y </style> tags:

.posthidden {display:none}
.postshown {display:inline}



A continuación, añadimos el siguiente script entre las etiquetas <head> y </head>:
<script type="text/Javascript">
var numbers = new Array();
var dates = new Array();

function showcategory (tag) {

var reg = new RegExp(tag);
var showdate = new Array();
for (var i=numbers.length-1;i>=0;i--)
{
showdate[dates[numbers[i]]] = 0;
}

for (var i=numbers.length-1;i>=0;i--)
{
whichpost = document.getElementById(numbers[i]+'2');
mytags = whichpost.getElementsByTagName("tag");
hidepost = 1;
for(var j=mytags.length-1;j>=0;j--)
{
if (reg.test(mytags[j].getAttribute('label')))
{
hidepost = 0;
showdate[dates[numbers[i]]] = 1;
}
}
if (hidepost) {
whichpost.className="posthidden";
}
else {
whichpost.className="postshown";
}
}
for (var i=numbers.length-1;i>=0;i--)
{
whichdate = document.getElementById(dates[numbers[i]]);
if(showdate[dates[numbers[i]]]) {
whichdate.className="postshown";
} else {
whichdate.className="posthidden";
}
}
}

function listcategory (postid) {

whichpost = document.getElementById(postid);
mytags = whichpost.getElementsByTagName("tag");
for(var j=mytags.length-1;j>=0;j--)
{
label=mytags[j].getAttribute('label');
document.write('<a href="javascript:showcategory('
+"'"+label+"'"+')">'+label+'</a> ');
}
}

function sidebarcategories () {

var taghash = new Array();
var taglist = new Array();

document.write('<li><a href="javascript:showcategory('
+"''"+')">All</a></li>');
alltags = document.getElementsByTagName("tag");
for(var j=alltags.length-1;j>=0;j--)
{
taghash[alltags[j].getAttribute('label')]++;
}

for(x in taghash)
{
taglist[taglist.length] = x;
}

taglist.sort();
for(var j=0;j<taglist.length;j++)
{
count = taghash[taglist[j]];
document.write('<li><a href="javascript:showcategory('
+"'"+taglist[j]+"'"+')">'+taglist[j]+'</a> </li>');
}
}
</script>


Una vez hecho esto, hay que modificar la sección BlogDateHeader:
<BlogDateHeader>
<span class="postshown" id="$BlogDateHeaderDate$">
<script type="text/Javascript">currentdate ='<$BlogDateHeaderDate$>';</script>
<h2 class="date-header"><$BlogDateHeaderDate$></h2> </span>
</BlogDateHeader>


El siguiente paso es incluir el siguiente código al principio de la sección dedicada al post:
<!-- Begin .post -->

<span class="postshown" id="<$BlogItemNumber$2">
<script type="text/Javascript">
numbers[numbers.length] = '<$BlogItemNumber$>';
dates['<$BlogItemNumber$>']=currentdate;
</script>


Al final de la sección de post, puede añadirse una llamada a listcategory(), con lo cual se listarán las categorías a las que pertenece la entrada actual. Por otra parte, debe cerrarse la sección span que se había abierto:

<script type="text/Javascript"> listcategory('<$BlogItemNumber$>2');</script>
</div>
</span>
<!-- End .post -->


El paso final es colocar en la sidebar o barra lateral la lista de categorías:

<div class="Box">
<div class="Inner">
<h2 class="sidebar-title">Categories</h2>
<ul>
<script type="text/Javascript">sidebarcategories();</script>
</ul>
</div>
</div>

¿Cómo funciona?

Veamos cómo funcionan las categorías: cada vez que se añada un nuevo post, se puede asociar a este las etiquetas en HTML que se desee que aparezcan en la lista de categorías. Por ejemplo:
<tag label="hobbies"></tag> <tag label="music"></tag>


Los identificadores tag and label han sido elegidos de un modo un tanto arbitrario y pueden cambiarse por otros si fuera necesario.

¿Comentarios?

En esta entrada hemos dado simplemente una guía de referencia rápida. Estoy trabajando para publicar una descripción más detallada del código. Hasta ahora, este método me convence en cuanto que tiene muy buena respuesta interactiva, pero aún debería mejorarse en varios aspectos, especialmente es importante conseguir que este script muestre no sólo las categorías presentes en la página que se está mostrando, sino también en los mensajes anteriores guardados en los archivos.

Tuesday, August 01, 2006

"Ajax" in action

I've been playing for a while with the Ajax stuff. I think I will eventually work out the issue of having the complete categories list from the archives on the main page, but still need more testing.

For the moment, I copy below the Ajax Magic Spelling, and how to parse HTML code. Really impressive.



function getFile(pURL) {
if (window.XMLHttpRequest) { // code for Mozilla, Safari, etc
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=postFileReady;
xmlhttp.open("GET", pURL, true);
xmlhttp.send(null);
} else if (window.ActiveXObject) { //IE
xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
if (xmlhttp) {
xmlhttp.onreadystatechange=postFileReady;
xmlhttp.open('GET', pURL, false);
xmlhttp.send();
}
}
}

// function to handle asynchronous call
function postFileReady() {
if (xmlhttp.readyState==4) {
if (xmlhttp.status==200) {
document.getElementById('theDivToLoad').innerHTML=xmlhttp.responseText;
}
}
}



if (window.ActiveXObject){
vXMLDoc = new ActiveXObject("Microsoft.XMLDOM");
vXMLDoc.async = false;
//IE uses the loadXML method when the source document is NOT XML
vXMLDoc.loadXML(xmlhttp.responseText);
}else if(document.implementation.createDocument){
//Firefox requires a parser object to read the text
var vParser = new DOMParser();
vXMLDoc = vParser.parseFromString(xmlhttp.responseText, "text/xml");
}
if(vXMLDoc == null) alert("XML Doc Load Failed");

Keeping the quick guide updated

I've been testing and updating a little bit the code and the styles on this weblog. Any change will be always updated on the quick guide, so I keep the quick guide post as the main reference, and the welcome page.

Code internals

There are two global variables:
  • numbers : an array where we save the unique code assigned to each post by usign the span tag;
  • dates : a hash which has the post numbers as keys and their associated dates as values.

There are three functions in the script:
  • showcategory(tag): check for the tag in all posts, show the hits and hide the rest. Furthermore, show the dates for the hits;
  • listcategory(postid): list the categories for the current post;
  • sidebarcategories(tag): sort and list all the categories in the document;