Contenido

Adapta tus comentarios a WordPress 2.7 sin problemas

26 Dic

+ 35

Bueno, me he alargado y lo he dejado mucho tiempo, pero más vale tarde que nunca. Entre turrones y garrapiñadas he pensado que sería interesante hacer digestión haciendo algo constructivo, así que vamos al lio.

Introducción

Como es dificil hacer un artículo que abarque a todos los themes disponibles vamos a usar Kubrick para ilustrar con ejemplos este tutorial. Al ser el theme por defecto de WordPress todos disponemos de él para poder hacer las pruebas mientras seguimos el tutorial.

Para los menos experimentados, el Theme Kubrick es el que nos encontraremos en la carpeta wp-content/themes/default/, concretamente vamos a editar el fichero comments.php de este directorio.

Detectar WordPress 2.7

Si estamos desarrollando un theme para WordPress 2.7, este punto puede ser interesante, pero si por el contrario estás haciendo un theme para tu blog, el que ya está en WordPress 2.7, puedes ahorrarte hacer la comprobación ya que siempre se va a cumplir.

if (function_exists('wp_list_comments')) :
// WordPress 2.7
else :
// WordPress 2.6-
endif;

Veamos como quedaría en el theme Kubrick.

<?php if ($comments) : ?>
	<h3 id="comments"><?php comments_number('No Responses', 'One Response', '% Responses' );?> to &#8220;<?php the_title(); ?>&#8221;</h3>
	<ol class="commentlist">
	<?php if (function_exists('wp_list_comments')) : ?>
	<!-- WordPress 2.7 -->
	<?php else : ?>
	<?php foreach ($comments as $comment) : ?>
		<li <?php echo $oddcomment; ?>id="comment-<?php comment_ID() ?>">
			<?php echo get_avatar( $comment, 32 ); ?>
			<cite><?php comment_author_link() ?></cite> Says:
			<?php if ($comment->comment_approved == '0') : ?>
			<em>Your comment is awaiting moderation.</em>
			<?php endif; ?>
			<br />
			<small class="commentmetadata"><a href="#comment-<?php comment_ID() ?>" title=""><?php comment_date('F jS, Y') ?> at <?php comment_time() ?></a> <?php edit_comment_link('edit','&nbsp;&nbsp;',''); ?></small>
			<?php comment_text() ?>
		</li>
	<?php
		/* Changes every other comment to a different class */
		$oddcomment = ( empty( $oddcomment ) ) ? 'class="alt" ' : '';
	?>
	<?php endforeach; /* end for each comment */ ?>
	<!-- WordPress 2.6- -->
	<?php endif;?>
	</ol>
 <?php else : // this is displayed if there are no comments so far ?>
	<?php if ('open' == $post->comment_status) : ?>
		<!-- If comments are open, but there are no comments. -->
	 <?php else : // comments are closed ?>
		<!-- If comments are closed. -->
		<p class="nocomments">Comments are closed.</p>
	<?php endif; ?>
<?php endif; ?>

Como podemos ver, ya tenemos el sistema medio montado. Ahora si el WordPress en el que está corriendo nuestro theme no tiene WordPress 2.7 nos mostrará los comentarios como los estaba haciendo hasta ahora, en caso contrario y con WordPress 2.7 disponible no mostraremos nada, por el momento.

wp_list_comments()

La clave de todo es esta función que se encarga de mostrarnos los comentarios de nuestros posts de una forma sencilla y rápida. Como la mayoría de funciones de WordPress esta tiene una serie de parámetros para personalizar su salida.

  • walker, nos activa/desactiva los comentarios anidados (Por defecto Null)
  • max_depth, máxima profundidad de estos comentarios (Por defecto »)
  • style, estilo con el que WordPress nos permite mostrar los comentarios [ul, div] (Por defecto ul)
  • callback, función que nos permite personalizar completamente la salida de los comentarios, se lanzará en cada uno de los comentarios.
  • end-callback, función que se lanzará al terminar la iteración de los comentarios.
  • type, especifica el tipo de comentarios a mostrar [comment, pingback, all] (Por defecto all)
  • page, página en la que empezamos a mostrar los comentarios.
  • per_page, comentarios por página
  • avatar_size, tamaño del avatar de los usuarios que comentan (Por defecto 32)
  • reverse_top_level, nos muestra los comentarios en orden inverso al que se introdujeron (Por defecto Null)
  • reverse_children, orden inverso en los hijos de los comentarios anidados (Por defecto »)

Bueno, ahora que conocemos las opciones disponibles en wp_list_comments() incorporémoslo en el código anterior.

<?php if ($comments) : ?>
	<h3 id="comments"><?php comments_number('No Responses', 'One Response', '% Responses' );?> to &#8220;<?php the_title(); ?>&#8221;</h3>
	<ol class="commentlist">
	<?php if (function_exists('wp_list_comments')) : ?>
	<!-- WordPress 2.7 -->
		<?php wp_list_comments(); ?>
	<?php else : ?>
	<?php foreach ($comments as $comment) : ?>
		<li <?php echo $oddcomment; ?>id="comment-<?php comment_ID() ?>">
			<?php echo get_avatar( $comment, 32 ); ?>
			<cite><?php comment_author_link() ?></cite> Says:
			<?php if ($comment->comment_approved == '0') : ?>
			<em>Your comment is awaiting moderation.</em>
			<?php endif; ?>
			<br />
			<small class="commentmetadata"><a href="#comment-<?php comment_ID() ?>" title=""><?php comment_date('F jS, Y') ?> at <?php comment_time() ?></a> <?php edit_comment_link('edit','&nbsp;&nbsp;',''); ?></small>
			<?php comment_text() ?>
		</li>
	<?php
		/* Changes every other comment to a different class */
		$oddcomment = ( empty( $oddcomment ) ) ? 'class="alt" ' : '';
	?>
	<?php endforeach; /* end for each comment */ ?>
	<!-- WordPress 2.6- -->
	<?php endif;?>
	</ol>
 <?php else : // this is displayed if there are no comments so far ?>
	<?php if ('open' == $post->comment_status) : ?>
		<!-- If comments are open, but there are no comments. -->
	 <?php else : // comments are closed ?>
		<!-- If comments are closed. -->
		<p class="nocomments">Comments are closed.</p>
	<?php endif; ?>
<?php endif; ?>

De esta forma estaremos obteniendo los comentario con los parámetros por defecto, pero ¿que pasa si queremos adaptar a nuestro gusto los comentarios?

Parámetro callback

El parámetro callback representa el nombre de una función que será lanzada en cada comentario y a la que se le pasará el comentario por parámetro para disponer de todas las opciones dentro de ella. De esta forma podemos personalizar nuestros comentarios.

<?php if (function_exists('wp_list_comments')) : ?>
	<?php wp_list_comments('callback=MI_TEMPLATE_DE_COMENTARIOS'); ?>
	<div class="navigation">
	<div class="alignleft"><?php previous_comments_link() ?></div>
	<div class="alignright"><?php next_comments_link() ?></div>
<?php else : ?>
	<?php foreach ($comments as $comment) : ?>
		<?php MI_TEMPLATE_DE_COMENTARIOS($comment);?>
	<?php endforeach; ?>
<?php endif; ?>

Y la función MI_TEMPLATE_DE_COMENTARIOS() tendrá un aspecto similar a este:

<?php
function MI_TEMPLATE_DE_COMENTARIOS($comment, $args, $depth) {
// Comentario actual
   $GLOBALS['comment'] = $comment; ?>
   /*
   		comment_class() --> Nos permite hacer comentarios tipo zabra.
   		comment_ID() --> ID del comentario actual
   */
   <li <?php comment_class(); ?> id="comment-<?php comment_ID() ?>">
     <div id="div-comment-<?php comment_ID(); ?>
      <div class="comment-author vcard">
/* Mostramos el avatar del usuario */
         <?php echo get_avatar(); ?>

/* Enlace a la URL del autor del comentario */
         <?php printf(__('<cite class="fn">%s</cite> <span class="says">says:</span>'), get_comment_author_link()) ?>
      </div>

/* Controlamos que el comentario esté aprovado */
      <?php if ($comment->comment_approved == '0') : ?>
         <em><?php _e('Your comment is awaiting moderation.') ?></em>
         <br />
      <?php endif; ?>
/* Datos extra de los comentarios */
      <div class="comment-meta commentmetadata"><a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>"><?php printf(__('%1$s at %2$s'), get_comment_date(),  get_comment_time()) ?></a><?php edit_comment_link(__('(Edit)'),'  ','') ?></div>
/* Texto del comentario */
      <?php comment_text() ?>
/*Botón de reply, con él podremos responder a un comentario.*/
      <div class="reply">
         <?php comment_reply_link(array_merge( $args, array('add_below' => 'div-comment', 'depth' => $depth, 'max_depth' => $args['max_depth']))) ?>
      </div>
     </div>
   </li>
<?php } ?>

Exactamente lo que hará WordPress, será hacer pasar la variable $comment por esta función en cada comentario, haciendo que esta sea la encargada de pintar la salida por pantalla.

Responder comentarios

La posibilidad de responder a comentarios sin tener que montarlo tu mismo, es un aliciente más que WordPress 2.7 nos ofrece, pero para entender como funciona debemos conocer comment_reply_link().

comment_reply_link();

Se trata de generar el enlace necesario para poder responder a un comentario, en el código anterior, vemos como lo insertamos despues de comment_text(). Por defecto esta función recibe 3 parámetros:

  • $args, argumentos que condicionarán la salida
  • $comment, comentario que vamos a responder
  • $post, post en el que se encuentra en comentario que hemos de responder.

Los argumentos disponibles que condicionarán la salida nos darán una cierta flexibilidad a la hora de generar el enlace:

  • add_below, patrón al que se le añadirá el ID del comentario que indicará a que comentario hará referencia la respuesta (Por defecto comment-XXX)
  • respond_id, lugar en el que se insertará el comentario recien comentado (Por defecto respond)
  • reply_text, etiqueta que informará al usuario de la acción del enlace (Por defecto «Reply»)
  • login_text, etiqueta que mostrará en caso de que el usuario no esté logueado y sea necesario (Por defecto «Log in to Reply»)
  • depth, profundida del comentario, para comentarios anidados (Por defecto 0)
  • before, HTML que se insertará delante del enlace
  • after, HTML que se inseratá despues del enlace.

Esto nos generará el enlace necesario para responder a comentarios, pero aún nos queda adaptar el theme para poder recibir la respuesta.

La magia del javascript

La respuesta de comentarios necesitará de unas funciones de Javascript para hacer más dinámica la tarea de responder a los comentarios, para ello tendremos que añadir en el <head></head> de nuestro theme la siguiente línea:

if ( is_singular() ) wp_enqueue_script( 'comment-reply' );

Se encargará de cargar los Javascript necesarios para disfrutar de esta funcionalidad.

Modificando el formulario

WordPress por si solo no puede detectar los nombres de los elementos de nuestros formularios y como necesitan ciertos campos que hasta ahora no existían nos obliga a añadir esta línea en nuestro formulario para generar los campos necesarios para la respuesta.

<?php comment_id_fields(); ?>

Si nuestro theme tiene un elemento <input /> llamado comment_post_ID, podemos borrarlo ya que esta función se encargará de generarlo automáticamente.

Para indicarle el lugar en el que se encuentran los elementos necesarios para responder, debemos insertar un enlace en forma de ancla en el formulario, simplemente nos servirá para llevar el foco al formulario de envio:

<a id="respond"></a>

Para terminar, tenemos la función comment_form_title(), que se encargará de cambiar el famoso texto de «Leave a comment» por un «Leave a reply for XXX» en caso de estar respondiendo un comentario, para ello deberemos reemplazar el texto:

<h3 id="respond">Leave a Reply</h3>

por este otro:

<h3><?php comment_form_title( 'Leave a Reply', 'Leave a Reply to %s' ); ?></h3>

Si el usuario decide cancelar la acción y desechar la respuesta al comentario debe tener un enlace que le permita hacer esto, por eso tendremos que añadirlo en nuestro formulario de comentarios con la siguiente función:

<div id="cancel-comment-reply">
   <small><?php cancel_comment_reply_link() ?></small>
</div>

¿Y la paginación?

Otra de las mejoras que los comentarios nos traen en esta nueva versión, es la paginación de los mismos, haciendo que los posts con centenares de comentarios queden un poco más legibles. Para ello tenemos un serie de funciones que nos permiten dotar nuestros themes de esta funcionalidad. Evidentemente estas funciones será usadas únicamente en el apartado que destinamos a WordPress 2.7 ya que estas funciones no están disponibles para versiones previas.

next_comments_link();

Nos enlaza con la siguiente página de comentarios dentro de nuestro post. Esta función recibe 2 parámetros:

  • label, etiqueta que deseamos mostrar para informar al usuario del uso del enlace. (Por defecto «Newer Comments »»)
  • max_pages, máximo de páginas mostradas para enlazar. (Por defecto 0)

previous_comments_link();

Nos enlaza con los comentarios anteriores, si los hubiera. Por defecto dispone de un único parámetro:

  • label, etiqueta que deseamos mostrar (Por defecto «« Older Comments»)

Deploy, consigue una base para tus aplicaciones web

4 Dic

+ 10

Via Ajaxian, descubro Deploy*, una aplicación web que nos permite crear instalaciones base para iniciar nuestros proyectos. Mediante una pequeña selección de opciones disponibles, podemos crear un zip con la estructura de directorios, los ficheros Javascript y un index.php listo para iniciar el desarrollo de nuestra aplicación web.

proyect_deploy

Además, si nos gusta la idea, podemos descargar el código fuente y adaptarlo a nuestras necesidades.

iMeneame.net se lava la cara

26 Oct

+ 17

Hace más de un año que iMeneame vió la luz, la versión para el iPhone de Meneame.net (versión no oficial) ha tenido que aguantar con un diseño realmente horrible (evidentemente mio) hasta que me he topado con Lucas Savelli de WydStudio.

new_imeneamenew_meneame_single

Gracias a Lucas, iMeneame ha adquirido un aspecto más moderno y más eficiente para el dispositivo que fue creado. Debido a que el contenido lo saco del RSS de Meneame me veo condicionado a lo que este formato nos devuelve, las limitaciones del XSL tampoco han ayudado mucho, pero creo que el resultado es más que satisfactorio apesar de las salvedades encontradas.

Espero que os guste, y me comuniqueis todos los fallos e impresiones.

Ficheros de configuración dependientes del servidor

29 Sep

+ 15

Cuando desarrollamos una aplicación, generalmente trabajamos, inicialmente en local con unos datos para conectar a la base datos, unos ficheros con datos, unas rutas diferentes,… y esto suele provocar ediciones de fichero para que al subirlo a producción (al servidor online) no provoquen un error.

Una solución sencilla que podemos usar es la siguiente:

<?php
    // Nombre del fichero 
    $configfile = $_SERVER["SERVER_NAME"].".php";

    // Cargamos el fichero
    if (file_exists($configfile)) require $configfile;
    else die("Fichero ".$configfile." no existe");

?>

De esta forma podemos tener 2 ficheros con los datos necesarios para conectar en ambas bases de datos, con las rutas correctas para cada servidor,… completamente independientes. En mi caso, los ficheros son:

  1. localhost.php
  2. www.anieto2k.com.php

Automáticamente al entrar en la aplicación, comprobaremos $_SERVER["SERVER_NAME"] y cargaremos el fichero que sea oportuno.

Es una tontería, pero yo estuve mucho tiempo modificando los ficheros antes de subirlos y volviendo a modificarlos al volver a descargarlos 😀

Crea tu propio framework javascript

28 Sep

+ 58

El uso de frameworks Javascript aporta muchas ventajas al desarrollo web, facilidad de uso, estandarización, cross-browsing, … pero estas ventajas nos hacer perder el control y el conocimiento del código, sin contar con la carga de funcionalidades extras que no llegamos a usar.

Por estos motivos, llevo ya tiempo pensando en montar un framework Javascript que cubra mis necesidades, algo ligero y completo que me permita tener el completo control sobre el javascript que desarrollo.

Franki.js

Vamos a ver como montar tu propio framework javascript, montando las funciones básicas para posteriormente ir añadiendo las que necesitemos sin alterar el resto del framework.

Franki.js es un nombre que creo le viene que ni pintado, ya que nos vamos a nutrir de trozos de otros scripts con los que montaremos nuestra criatura. Nos sentiremos con el Dr. Frankenstein creando a su criatura 😀

var franki = {
   .. opciones ..
};

Extendiendo

La clave de los frameworks Javascript es sin duda la capacidad de extender elementos y así añadir nuevas funcionalidades a los elementos DOM con los que generalmente trabajamos. La función que es capaz de extender cualquier elemento es realmente sencilla, pero a la vez realmente poderosa.

extend: function(el, opt){
        for (var name in opt) el[name] = opt[name];
        return el;
 },
// Ejemplo
franki.extend(document.getElementById("logo"), {option: 'nueva propiedad'});

Como podemos ver, esta función recibe 2 parámetros, el elemento  que queremos extender y las opciones que queremos añadir a dicho elemento.

Recogiendo elementos

La función que usamos más en nuestros scripts es sin duda document.getElementById(); y evidentemente tenemos que reducir el número de letras que hemos de teclear para obtener un elemento pasándole un ID.

get: function(id){
        return franki.extend(document.getElementById(id), franki);
},
// Ejemplo
franki.get("logo);

Aprovechando que ya disponemos de extend() devolvemos el elemento extendido con las propiedades que franki.js va a incorporar.

Esta función no hace nada especial, aunque puede extenderse fácilmente con todas las posibilidades que javascript nos ofrece.

Creando e Insercción de Elementos

La creación de elementos DOM es otra funcionalidad que usamos considerablemente en nuestros scripts, por lo que es realmente necesario enmascarar la función document.createElement();

 create: function(type){
        return franki.extend(document.createElement(type), franki);
  },
// Ejemplo
var newDiv = franki.create("div");

insert: function(what) {
        return this.appendChild(what);
},
// Ejemplo
franki.get("logo).insert(newDiv);

Seguimos devolviendo el elemento extendido con las propiedades que poco a poco a ir haciendo crecer.

Atributos y Estilos

Los elementos que hemos extendido, necesitan tener la capacidad de devolver y modificar los atributos y estilos que los componen, para ello crearemos 2 funciones más.

css: function(name, value) {
        if (!value) return this.style[name];
        this.style[name] = value;
        return this;
},
// Ejemplo
var oldBorder = franki.get("logo").css("border");
franki.get("logo").css("border", "1px red solid");

attr: function(name, value) {
        if (!value) return this.getAttribute(name);
        this.setAttribute(name, value);
        return this;
},
// Ejemplo
var oldSrc = franki.get("logo").attr("src");
franki.get("logo").attr("src", "NUEVO_SRC");

Como vemos, disponemos de 2 nuevas propiedades que automáticamente se añadirán a los elementos con los que trabajemos.

Gestión de eventos

Los eventos asociados a los elementos es algo que por comodidad y por compatibilidad con navegadores podemos aprovechar para incluir en nuestro framework.

 addEvent: function(type, fn ) {
      if ( this.attachEvent ) {
        this['e'+type+fn] = fn;
        this[type+fn] = function(){this['e'+type+fn]( window.event );}
        this.attachEvent( 'on'+type, this[type+fn] );
      } else
        this.addEventListener( type, fn, false );
return this;
    },
// Ejemplo
franki.get("logo").addEvent("click", function(){ alert("Click");});

removeEvent: function(type, fn ) {
      if ( this.detachEvent ) {
        this.detachEvent( 'on'+type, this[type+fn] );
        this[type+fn] = null;
      } else
        this.removeEventListener( type, fn, false );
return this;
    },
// Ejemplo
franki.get("logo").removeEvent("click", function(){ alert("Click");});

Estas funciones, sacadas de este post de John Resig, nos sirven para poder trabajar perfectamente con nuestros elementos, aunque podríamos optar por la última revisión de Incoherence Babble.

Encadenamiento

Algo que siempre me ha gustado de los frameworks javascript actuales es la posibilidad de encadenar funcionalidades en la misma línea. Esto además de ayudarte a reducir el peso de nuestros scripts ayuda (a mi por lo menos) a ver más claro el código que estas escribiendo.

La clave de nuestro framework para poder encadenar funcionalidades es SIEMPRE devolver el elemento con el que estamos trabajando. Si nos fijamos en las funciones anteriores, nos devuelven el elemento que estamos usando. De esta forma podemos conseguir cosas como estas.

franki.get("logo").css("border", "2px red solid").addEvent("mouseover", function(){alert("MouseOver");});

Últimos retoques

Necesitamos un alias para evitar la llamada franki.get(), que es la base del framework. Por ello podemos optar por el famoso $(), o cualquier otra combinación que nos guste o nos vaya bien.

window.get = el.get;
get("logo").css("border", "2px red solid");

Aclaraciones

Las funciones son muy básicas y únicamente son para que sirvan de ejemplo de por donde empezar a construir tu propio framework, las posibilidades de extensión son infinitas.

El código

Veamos como quedaría todo juntito 😀

var franki = {
    get: function(id){
        return franki.extend(document.getElementById(id), franki);
    },
    extend: function(el, opt){
        for (var name in opt) el[name] = opt[name];
        return el;
    },
    create: function(type){
        return this.extend(document.createElement(type));
    },
    insert: function(what) {
        return this.appendChild(what);
    },
    css: function(name, value) {
        if (!value) return this.style[name];
        this.style[name] = value;
        return this;
    },
    attr: function(name, value) {
        if (!value) return this.getAttribute(name);
        this.setAttribute(name, value);
        return this;
    },
    addEvent: function(type, fn ) {
      if ( this.attachEvent ) {
        this['e'+type+fn] = fn;
        this[type+fn] = function(){this['e'+type+fn]( window.event );}
        this.attachEvent( 'on'+type, this[type+fn] );
      } else
        this.addEventListener( type, fn, false );
    return this;
    },
    removeEvent: function(type, fn ) {
      if ( this.detachEvent ) {
        this.detachEvent( 'on'+type, this[type+fn] );
        this[type+fn] = null;
      } else
        this.removeEventListener( type, fn, false );
    return this;
    }
};
// Alias
window.$ = franki.get;

Promoción

¿Has usado este post para crear tu propio framework? Pues usalo tambien para promocionarlo, usa los comentarios, evitar pegar el código, mejor usar un enlace algún lugar donde ver el código/ejemplos/tutoriales/…

Mejoras

Jose nos comenta el problema que puede provocar que franki disponga de métodos públicos a los que podrían acceder externamente provocando errores al acceder al elemento this.

franki.css("border", "1px red solid");
// --> Error

Este ejemplo nos arrojaría un error al detectar que this (franki) no dispone de las propiedades própias de un HTMLElement, por ese momento Jose nos propone un sistema para sacar lo métodos de franki, haciéndolos privados e innaccesibles desde fuera.

var franki = (function(){
    var metodosExtendidos = {
    get: function(id){
        return franki.extend(document.getElementById(id), franki);
    },
    extend: function(el, opt){
        for (var name in opt) el[name] = opt[name];
        return el;
    },
    create: function(type){
        return this.extend(document.createElemen(type));
    },
    insert: function(what) {
        return this.appendChild(what);
    },
    css: function(name, value) {
        if (!value) return this.style[name];
        this.style[name] = value;
        return this;
    },
    attr: function(name, value) {
        if (!value) return this.getAttribute(name);
        this.setAttribute(name, value);
        return this;
    },
    addEvent: function(type, fn ) {
      if ( this.attachEvent ) {
        this['e'+type+fn] = fn;
        var oThis = this;
        this[type+fn] = function(){oThis['e'+type+fn]( window.event );}
        this.attachEvent( 'on'+type, this[type+fn] );
      } else
        this.addEventListener( type, fn, false );
    return this;
    },
    removeEvent: function(type, fn ) {
      if ( this.detachEvent ) {
        this.detachEvent( 'on'+type, this[type+fn] );
        this[type+fn] = null;
      } else
        this.removeEventListener( type, fn, false );
    return this;
    }
};

    return {
       extend: function(el, opt){
         for (var name in opt) el[name] = opt[name];
         return el;
       },
       get: function(id){
               return franki.extend(document.getElementById(id), metodosExtendidos);
       }
    };
}());

Como podemos ver la variable metodosExtendidos se convierte en privada y es la usada en la función get() para extender el elemento que queremos usar.

Gracias Jose por la corrección, no había pensado en esa posibilidad.

CommentFeed: Más Novedades

31 Ago

+ 10

El fin de semana es dificil dedicarle algo de tiempo a cualquier cosa, entre comidas con la familia y cenas con los amigos, queda poco tiempo para teclear. Pero estar alejado del PC da lugar a las mejores ideas, así que he aprovechado y he ido recopilando unas cuantas de estas ideas para CommentsFeeds.

1) Usando los servidores de Google

He creado un proyecto en Google Code, en el que he alojado el fichero commentfeeds.js que cargamos desde nuestro marcador para así disponer de un buen server donde tener alojado el script, y así disponer de una carga más rápida.

Esto nos obliga cambiar el enlace anterior a esto:

javascript:(function(s){s.type='text/javascript';s.src='http://commentfeed.googlecode.com/files/commentfeed.js?rand='+Math.random();document.getElementsByTagName('head')[0].appendChild(s)})(document.createElement('script'));

El enlace antíguo lo eliminaré el miercoles, así que si alguien le falla apartir de ese día, deberá cambiar el «Marcador fantasma» por el mostrado anteriormente.

También he usado Google Ajax Libraries, en que alojan los principales frameworks JS en los servidores de Google haciendo la carga más rápida.

2) Eliminando el CSS

En la fase anterior, usabamos un fichero CSS para colocar los elementos dentro de Google Reader. Ahora los aplico mediante Javascript evitando ese tiempo de demora para cargar el fichero.

Bueno, espero tener algo listo a final de semana, pero no quiero adelantar nada. Depende del tiempo libre que tenga. Saludos y gracias por el feedback que me estais reportando.

CommentFeed: Novedades

29 Ago

+ 10

Bueno, ante todo, quiero dar las gracias a todos los que con sus pruebas me han ayudado a solucionar un par de problemas y a plantearme las cosas de una forma diferente. Esta tarde he podido dedicarle un poco de tiempo y he podido hacer alguna modificación a lo que os mostré ayer, os las enumero una a una.

1) Comentarios

Evidentemente, el no ver los comentarios previos podría suponer problemas para algunos casos, como bien comenta _SxR_ en su comentario.

Para ello he añadido los comentario relacionados al post, necesita un poco de diseño pero ahora lo importante es la funcionalidad.

commenfeed-comentarios

2) Diferencia entre «Expanded View» y «List View».

Google Reader, permite usar 2 diferentes formas para visualizar los feeds, la «Expanded List» que nos presenta los artículo abiertos y a medida que vamos haciendo scroll hacia abajo,  nos va seleccionando el post que se encuentre en el centro.

Por otro lado, tenemos «List View», que nos muestra las entradas cerradas, mostrando únicamente el título y al hacer click sobre él, nos abre el artículo dejando los demás cerrados.

Dependiendo del modo usado, la funcionalidad puede ser diferente.

a) Expanded View

Una vez cargado el script, haciendo click sobre el artículo haremos aparecer la opción de «Comenta».

b) List View

Para este modo, y realmente para cualquiera, he hecho que el testigo que vemos justo arriba, al lado del motor de busqueda, sea un enlace que al hacer click sobre él, nos mostrará la opción de «Comenta».

Posibles problemas

Al tratarse de un fichero JS, puede verse afectado por algún tipo de caché y no disponer de alguna de las mejoras. Podemos hacer 3 cosas:

1. Armarnos de paciencia y esperar a que se recarge por si solo.

2. Acceder al enlace siguiente y recargar la página para así hacer una recarga nueva del fichero.

https://www.anieto2k.com/demo/commentfeed/commentfeed.js

3. Añadir al final del enlace del Marcador (Math.random()) dejando el marcado así:

javascript:(function(s){s.type='text/javascript';s.src='https://www.anieto2k.com/demo/commentfeed/commentfeed.js?rand='+Math.random(); document.getElementsByTagName('head')[0].appendChild(s)})(document.createElement('script'));

Gracias de nuevo a todos los que me están ayudando con sus ideas, consejos y sugerencias.

Comentarios con estilo en tu WordPress

25 Ago

+ 2

Los chicos de CSS-Trick nos muestran un tutorial de como conseguir mostrar los comentarios de cada entrada de una forma bastante elegante y original.

comments

Como podeis ver, hay mucho CSS por delánte. Usando los iconos de calendario de Sotak, y mucho códugo CSS podremos conseguir el mismo efecto de la imagen. Un complemento perfecto para aquel calendario que pusimo hace más de 2 años 😀

Estadísticas de tu WordPress con protoChart

25 Ago

+ 7

Hace unos días estuve testeando librerías JS para mostrar gráficas. Realmente he encontrado librerías geniales, pero protoChart ha sido la que más me ha gustado. Para hacer pruebas, estuve usando datos de aNieto2k, y así de paso veía estadísticas del blog de una forma rápida y clara.

stats

He preparado un zip con el que podreis mostrar vuestras estadísticas de la misma forma. En principio, únicamente mostraría estadísticas relacionadas con los posts, comentarios y pingbacks, comparativas con años anteriores, … y si tienes StatPress tendrás además estadísticas de visitas por horas del día actual y del día anterior, además de las visitas del mes (para ello tendremos que tener la opción de 30 días activada en el plugin).

Modificaciones

Para hacer las pruebas creé una clase a la que le podemos pasar una sentencia SQL con la que poder obtener datos X e Y y componer una gráfica.

var posts = [<?=$stat->getResults('line', "SELECT count(post_date) as data, DAY(post_date) as label FROM ".$wpdb->posts." WHERE MONTH(post_date) = ".$month." and YEAR(post_date) = $year AND post_parent = ''  GROUP BY 2 ORDER BY 2 ASC;")?>];

Simplemente hemos de respetar los valores que devolvemos con nuestra SQL. Los nombre data y label deben mantenerse ya que serán usados para mostrar leer los resultados.

Para añadir un nuevo campo a las estadísticas deberemos añadir el elemento HTML nuevo y las líneas necesarias del JS al final del fichero.

// HTML
<h2>Comparativa de comentarios por meses del año (<?=$year?>)</h2>
<div id="commentYear" style="width:100%; height:300px"></div>

// Javascript
var results1 = [<?=$stat->getResults('line', "SQL1")?>];
var results2 = [<?=$stat->getResults('line', "SQL2")?>];
new Proto.Chart($('commentYear'),
[
    {data: results1, label: "Resultados de SQL1"},
    {data: results2, label: "Resultados de SQL2"}
],
{
	xaxis: {min: 1, max: 31, tickSize: 1, tickDecimals: 0},
	lines: {show: true, fill: true},
	points: {show: true},
	legend: {show: true}
});

Tambien podemos hacer uso de gráficas de «quesitos», para ello pasaremos el parámetro ‘pie’ a la método getResults() de la clase stats.

// HTML
<h2>Navegadores de los usuarios (StatPress)</h2>
<div id="navegadores" style="width:100%; height:300px"></div>

// Javascript
new Proto.Chart($('navegadores'),
[
    <?=$stat->getResults('pie', $sql)?>
],
{
	pies: {show: true, autoScale: true},
	legend: {show: true}
});

Hay una infinidad de opciones para hacer tus gráficos más profesionales.

Instalación

  1. Descargamos el ficheros
  2. Descomprimimos y subimos a la raiz de nuestro WordPress.
  3. Accedemos a la ruta http://tublog/stats.php

Descargar

El fichero se compone de:

  • stats.php
  • js/prototype.js
  • js/protochart.js
  • js/excanvas.js // Para Internet Explorer 6

[Descargar] [Ejemplo]

Recuento de datos

21 Ago

+ 7

Hagamos un recuento de datos de los proyectos:

GeekTest

  • 1.200 usuarios de media, se ponen a prueba cada día.
  • 1.436 preguntas insertadas en 137 días funcionando, lo que da una media de 10,4 preguntas enviadas por día (solo las aceptadas).
  • Aproximadamente una media de 1-3 preguntas son eliminadas cada día por quejas de los usuarios.

Ir a la aplicación

WpAdminThemes

  • 147 usuarios registrados
  • 91 themes creados y disponibles para descargar
  • 110 días de funcionamiento

Ir a la aplicación

iMeneame

  • 800 usuarios cada día visualizan esta versión no oficial de Meneame para iPhone.
  • El 45% usa Internet Explorer como navegador principal.
  • El 23% tiene una resolución de pantalla inferior a 800×600

Ir a la aplicación

Themes en Castellano

  • Aproximadamente 200 themes completamente en castellano
  • 700 usuario cada día descargan algún theme
  • Todo gracias a Fernando Tellado y demás usuarios por su inestimable ayuda

Ir a la aplicación

BlogoEdad

  • 2218 usuarios registrados
  • Una media de 1500 usuarios lo visitan cada día
  • Una media de 3 usuarios al mes son eliminados por irregularidades en el registro.
  • El 27 de Octubre es el día que más bloggers han nacido
  • La media de edad es de 25 años (somos unos yogurines :D)

Ir a la aplicación

Gracias a todos por hacer posible este sueño 😉