Micaela 2 de noviembre de 2009 a las 09.02
   Imprimir artículo
elWebmaster.com

Crea un sistema de comentarios estilo Google Wave


googlewaveTodos hemos visto los videos (y algunos incluso han tenido acceso a la previsualización de desarrolladores) del nuevo producto de Google: Google Wave.

Esta herramienta que posee una gran IU es realmente inspiradora. Es por eso que en esta nota te ense√Īaremos c√≥mo crear un sistema de comentarios estilo Google Wave.

Paso 1 – XHTML

Las tecnologías que estamos utilizando incluyen PHP como un back-end, MySQL como un almacenador de datos, jQuery, CSS y  XHTML para el front-end con AJAX en el medio. El deslizador es un componente creado con jQuery UI.

Primero echémosle un vistazo a la sección del cuerpo de demo.php

demo.php

  1. <div id="main">
  2.  
  3. <p id="orig">View the <a href="http://tutorialzine.com/2009/10/google-wave-history-slider-jquery/" target="_blank">original tutorial &raquo;</a></p>
  4. <h1>Google Wave-like</h1>
  5. <h2>History Slider</h2>
  6.  
  7. <div id="wave">
  8. <div id="topBar">Your Demo Wave</div>
  9. <div id="subBar">
  10. <img src="img/tutorialzine.png" alt="Tutorialzine" /><img src="img/demo.png" alt="Demo" /><img src="img/curious.png" alt="Curious" />
  11. </div>
  12.  
  13. <div id="sliderContainer">
  14. <div id="slider"></div>
  15. <div class="clear"></div>
  16. </div>
  17.  
  18. <div id="commentArea">
  19.  
  20. <?php
  21. foreach($comments as $c)
  22. {
  23.     showComment($c);
  24.     // Showing each comment
  25. }
  26. ?>
  27.  
  28. </div>
  29. <input type="button" class="waveButtonMain" value="Add a comment" onclick="addComment()" />
  30.  
  31. <div id="bottomBar">
  32. </div>
  33.  
  34. </div>
  35. </div>

Esto es b√°sicamente todo el dise√Īo que usaremos. La raz√≥n principal por la cual el c√≥digo es tan corto es que estamos usando CSS para darle estilo, y la salida de comentarios est√° manejada por una funci√≥n PHP especial, que explicaremos pronto.

google

Paso 2 – CSS

Lo genial de jQuery es que, gracias a CDN de Google, se puede a√Īadir directamente en tu sitio, sin tener que descargarlo y almacenarlo en tu servidor. Esto tambi√©n ayuda al tiempo de carga de tu p√°gina.

Lo miso sucede con la UI de jQuery, que contiene nuestro deslizador. No sólo eso, sino que el CDN también contiene el estilo y las imágenes necesarias para mostrarlo de forma apropiada.

Sin embargo, todavía tenemos que incluir nuestros propios estilos personales. Los archivos de ejemplo se pueden encontrar en demo.css. Aquí sólo se muestran las partes más interesantes:

demo.css

  1. #orig{
  2.     /* The link that float to the right of the title */
  3.     float:right;
  4.     font-family:"MyRiad Pro",Arial;
  5.     font-size:10px;
  6.     letter-spacing:1px;
  7.     text-transform:uppercase;
  8.     padding-top:10px;
  9. }
  10.  
  11. .clear{
  12.     /* Clearfix, needed by IE6 */
  13.     clear:both;
  14. }
  15.  
  16. #main{
  17.     /* The main container */
  18.     width:600px;
  19.     margin:30px auto;
  20. }
  21.  
  22. #wave{
  23.     /* CSS rounded corners */
  24.     -moz-border-radius:6px;
  25.     -khtml-border-radius: 6px;
  26.     -webkit-border-radius: 6px;
  27.     border-radius:6px;
  28.  
  29.     background:white;
  30.     width:100%;
  31.     overflow:hidden;
  32. }
  33.  
  34. #topBar{
  35.     background:url(img/bg.jpg) repeat-x;
  36.     font-size:12px;
  37.     color:white;
  38.  
  39.     height:20px;
  40.     overflow:hidden;
  41.     padding:5px 0 0 10px;
  42.  
  43.     border-bottom:1px solid #e4f1ff;
  44.     -moz-border-radius:6px 6px 0 0;
  45.     /* A Firefox fix, for once */
  46. }
  47.  
  48. #bottomBar{
  49.     height:40px;
  50.     background-color:#c9e2fc;
  51.     -moz-border-radius:0 0 6px 6px;
  52.     border-top:1px solid #CCCCCC;
  53. }
  54.  
  55. #subBar{
  56.     background-color:#c9e2fc;
  57.     padding-left:10px;
  58. }
  59.  
  60. #subBar img{
  61.     /* The avatars at the top of the page */
  62.     margin:8px 8px 8px 0;
  63.     border:1px solid #cccccc;
  64. }
  65.  
  66. .waveButton,.waveButtonMain{
  67.     /* The submit buttons */
  68.     background:url(img/button_bg.jpg) repeat-x 50% 50%;
  69.     border:1px solid #DDDDDD;
  70.     padding:4px;
  71.  
  72.     cursor:pointer;
  73. }
  74.  
  75. .waveButtonMain{
  76.     display:block;
  77.     margin:10px 20px;
  78. }
  79.  
  80. .textArea{
  81.     padding:4px;
  82.     font-family:Arial,Helvetica,Sans-serif;
  83.     font-size:12px;
  84.     color:#666666;
  85.     border:1px solid #66aff9;
  86.     margin-bottom:10px;
  87. }
  88.  
  89. .replyLink{
  90.     float:right;
  91. }
  92.  
  93. #commentArea{
  94.     padding:10px;
  95.     color:#444444;
  96. }
  97.  
  98. .commentText{
  99.     margin-left:40px;
  100. }
  101.  
  102. .waveComment .waveComment{
  103.     padding-left:30px;
  104. }
  105.  
  106. .waveComment .waveComment .replyLink{
  107.     /* Hiding the reply link on the comment replies -
  108.     only 2 levels of ancestry are allowed */
  109.  
  110.     display:none;
  111. }
  112.  
  113. .waveTime{
  114.     color:#999999;
  115.     float:right;
  116.     font-size:10px;
  117. }
  118.  
  119. #slider{
  120.     width:400px;
  121.     font-size:10px;
  122.     float:right;
  123.     margin-right:10px;
  124. }
  125.  
  126. #sliderContainer{
  127.     background:url(img/dark_bg.jpg) repeat-x #f5f5f5 50% 50%;
  128.     padding:9px 10px;
  129.     border:1px solid #bbbbbb;
  130.     border-left:0;
  131.     border-right:0;
  132.  
  133.     height:10px;
  134.     padding:9px 10px;
  135. }
  136.  
  137. div.ui-widget-content{
  138.     /* Styling the slider */
  139.     background:#FFFFFF;
  140.     border:1px solid #CCCCCC;
  141. }
  142.  
  143. .comment{
  144.     margin:5px 10px;
  145.     padding:8px 10px;
  146.     border:2px solid #cccccc;
  147.  
  148.     /* Rounding the comment */
  149.     -moz-border-radius:6px;
  150.     -khtml-border-radius: 6px;
  151.     -webkit-border-radius: 6px;
  152.     border-radius:6px;
  153.  
  154.     overflow:hidden;
  155. }
  156.  
  157. span.name{
  158.     font-weight:bold;
  159.     color:#999999;
  160. }
  161.  
  162. .commentAvatar{
  163.     width:30px;
  164.     height:30px;
  165.     float:left;
  166.     margin-right:10px;
  167. }

google2

Paso 3 – PHP

Hay 4 archivos PHP principales que manejan el back-end:

1. demo.php – da salida a los comentarios;

2. ajax/saveComment.php – a√Īade nuevos comentarios, se llega a √©l por medio de peticiones AJAX;

3. functions.php – retiene algunas funciones utilizadas por demo.php;

4. connect.php Рmaneja la conexión de base de datos.

Aquí sólo miraremos los tres primeros archivos:

demo.php

  1. define("INCLUDE_CHECK",1);
  2. require 'connect.php';
  3. require 'functions.php';
  4. // Including the files for the DB connection and our custom functions
  5. // Removing comments that are older than an hour.
  6.  
  7. mysql_query("DELETE FROM wave_comments WHERE id>5 AND dt<SUBTIME(NOW(),'0 1:0:0')");
  8.  
  9. $comments_result = mysql_query("SELECT * FROM wave_comments ORDER BY id ASC");
  10. // Selecting all the comments ordered by id in ascending order
  11.  
  12. $comments=array();
  13. $js_history='';
  14.  
  15. while($row=mysql_fetch_assoc($comments_result))
  16. {
  17.     if($row&#91;'parent']==0)
  18.     // If the comment is not a reply to a previous comment, put it into $comments directly
  19.     $comments&#91;$row['id']] = $row;
  20.     else
  21.     {
  22.         if(!$comments&#91;$row['parent']]) continue;
  23.  
  24.         $comments&#91;$row['parent']]['replies'][] = $row;
  25.         // If it is a reply, put it in the 'replies' property of its parent
  26.     }
  27.  
  28.     $js_history.='addHistory({id:"'.$row&#91;'id'].'"});'.PHP_EOL;
  29.     // Adds JS history for each comment
  30. }
  31.  
  32. $js_history='<script type="text/javascript">
  33. '.$js_history.'
  34. </script>';
  35.  
  36. // This is later put into the head and executed on page load

Los comentarios son o parents (se anadem directamente al thread) o children (a√Īadidos como una r√©lica a un parent). S√≥lo se permiten dos niveles de ancestr√≠a (lo que quiere decir que las r√©plicas para los children est√°n deshabilitadas).

Los comentarios son mostrados por la función showComment (se puede ver en el paso XHTML de arriba).

ajax / saveComment.php

  1. define("INCLUDE_CHECK",1);
  2. require'../connect.php';
  3.  
  4. if(empty($_POST['comment'])) die("0");
  5. // If there isn't a comment text, exit
  6.  
  7. $comment = mysql_real_escape_string(nl2br(strip_tags($_POST['comment'])));
  8. $user='Demo';
  9. // This would be a nice place to start customizing - the default user
  10. // You can integrate it to any site and show a different username.
  11.  
  12. $addon='';
  13. if($_POST['parent']) $addon=',parent='.(int)$_POST['parent'];
  14.  
  15. mysql_query("INSERT INTO wave_comments SET usr='".$user."', comment='".$comment."', dt=NOW()".$addon);
  16.  
  17. if(mysql_affected_rows($link)==1)
  18.     echo mysql_insert_id($link);
  19.     // If the insert was successful, echo the newly assigned ID
  20. else
  21.     echo '0';

Y por ultimo, est√° functions.php

functions.php

  1. if(!defined('INCLUDE_CHECK')) die('You are not allowed to execute this file directly');
  2.  
  3. function showComment($arr)
  4. {
  5.     echo '
  6.     <div class="waveComment com-'.$arr&#91;'id'].'">
  7.  
  8.         <div class="comment">
  9.         <div class="waveTime">'.waveTime($arr['dt']).'</div>
  10.         <div class="commentAvatar">
  11.         <img src="img/'.strtolower($arr['usr']).'.png" width="30" height="30" alt="'.$arr['usr'].'" />
  12.         </div>
  13.  
  14.         <div class="commentText">
  15.         <span class="name">'.$arr['usr'].':</span> '.$arr['comment'].'
  16.         </div>
  17.  
  18.         <div class="replyLink">
  19.         <a href="" onclick="addComment(this,'.$arr['id'].');return false;">add a reply &raquo;</a>
  20.         </div>
  21.  
  22.         <div class="clear"></div>
  23.     </div>';
  24.  
  25.     // Output the comment, and its replies, if any
  26.     if($arr['replies'])
  27.     {
  28.         foreach($arr['replies'] as $r)
  29.         showComment($r);
  30.     }
  31.     echo '</div>';
  32. }
  33.  
  34. function waveTime($t)
  35. {
  36.     $t = strtotime($t);
  37.  
  38.     if(date('d')==date('d',$t)) return date('h:i A',$t);
  39.     return date('F jS Y h:i A',$t);
  40.     // If the comment was written today, output only the hour and minute
  41.     // if it was not, output a full date/time
  42. }

El √ļltimo paso es el m√°s complicado, en este caso es el c√≥digo jQuery.

Paso 4 – jQuery

Todo el código JS está localizado en script.js. Lo dividiremos en dos partes:

script.js – parte 1

  1. $(document).ready(function(){
  2.     // Executed once all the page elements are loaded
  3.  
  4.     lastVal = totHistory;
  5.  
  6.     // Create the slider:
  7.     $("#slider").slider({
  8.         value:totHistory,
  9.         min: 1,
  10.         max: totHistory,
  11.         animate: true,
  12.         slide: function(event, ui) {
  13.  
  14.             if(lastVal>ui.value)
  15.             $(buildQ(lastVal,ui.value)).hide('fast').find('.addComment').remove();
  16.             // Using buildQ to build the jQuery selector
  17.             // If we are moving the slider backward, hide the previous comment
  18.  
  19.             else if(lastVal<ui.value)
  20.             $(buildQ(lastVal,ui.value)).show('fast');
  21.             // Otherwise show it
  22.  
  23.             lastVal = ui.value;
  24.         }
  25.     });
  26. });
  27.  
  28. var totHistory=0;
  29. // Holds the number of comments
  30.  
  31. var positions = new Array();
  32. var lastVal;
  33.  
  34. function addHistory(obj)
  35. {
  36.     /* Gets called on page load for each comment, and on comment submit */
  37.     totHistory++;
  38.     positions.push(obj.id);
  39. }
  40.  
  41. function buildQ(from,to)
  42. {
  43.     /* Building a jQuery selector from the begin
  44.     and end point of the slide */
  45.  
  46.     if(from>to)
  47.     {
  48.         var tmp=to;
  49.         to=from;
  50.         from=tmp;
  51.     }
  52.  
  53.     from++;
  54.     to++;
  55.  
  56.     var query='';
  57.     for(var i=from;i<to;i++)
  58.     {
  59.         if(i!=from) query+=',';
  60.         query+='.com-'+positions&#91;i-1];
  61.     }
  62.  
  63.     /* Each comment has an unique com-(Comment ID) class
  64.     that we are using to address it */
  65.  
  66.     return query;
  67. }
  68. &#91;/php]
  69.  
  70. Como recordarán, hemos generado una string PHP especial, que contiene las llamadas a la función addHistory. Cada vez que se ejecuta, incrementa el contador totHistory. Luego de que todos los comentarios se cargan el $(document).ready se ejecuta y el slider se inicia con totHistory como el máximo valor del deslizador. El valor mínimo es 1, porque deseamos tener por lo menos un comentario visible.
  71.  
  72. Ahora, miremos la segunda parte del archivo:
  73. <h3>script.js - parte 2</h3>
  74. [php]
  75. function addComment(where,parent)
  76. {
  77.     /*  This functions gets called from both the "Add a comment" button
  78.     on the bottom of the page, and the add a reply link.
  79.     It shows the comment submition form */
  80.  
  81.     var $el;
  82.     if($('.waveButton').length) return false;
  83.     // If there already is a comment submition form
  84.     // shown on the page, return and exit
  85.  
  86.     if(!where)
  87.         $el = $('#commentArea');
  88.     else
  89.         $el = $(where).closest('.waveComment');
  90.  
  91.     if(!parent) parent=0;
  92.  
  93.     // If we are adding a comment, but there are hidden comments by the slider:
  94.     $('.waveComment').show('slow');
  95.     lastVal = totHistory;
  96.  
  97.     $('#slider').slider('option','value',totHistory);
  98.     // Move the slider to the end point and show all comments
  99.     var comment = '<div class="waveComment addComment">\
  100.     \
  101.     <div class="comment">\
  102.     <div class="commentAvatar">\
  103.     <img src="img/demo.png" width="30" height="30" />\
  104.     </div>\
  105.     \
  106.     <div class="commentText">\
  107.     \
  108.     <textarea class="textArea" rows="2" cols="70" name="" />\
  109.     <div><input type="button" class="waveButton" value="Add comment" onclick="addSubmit(this,'+parent+')" /> or <a href="" onclick="cancelAdd(this);return false">cancel</a></div>\
  110.     \
  111.     </div>\
  112.     </div>\
  113.     \
  114.     </div>';
  115.  
  116.     $el.append(comment);
  117.     // Append the form
  118. }
  119.  
  120. function cancelAdd(el)
  121. {
  122.     $(el).closest('.waveComment').remove();
  123. }
  124.  
  125. function addSubmit(el,parent)
  126. {
  127.     /* Executed when clicking the submit button */
  128.     var cText = $(el).closest('.commentText');
  129.     var text = cText.find('textarea').val();
  130.     var wC = $(el).closest('.waveComment');
  131.     if(text.length<4)
  132.     {
  133.         alert("Your comment is too short!");
  134.         return false;
  135.     }
  136.  
  137.     $(el).parent().html('<img src="img/ajax_load.gif" width="16" height="16" />');
  138.     // Showing the loading gif animation
  139.     // Send an AJAX request:
  140.  
  141.     $.ajax({
  142.         type: "POST",
  143.         url: "ajax/saveComment.php",
  144.         data: "comment="+encodeURIComponent(text)+"&parent="+parent,
  145.         /* Sending both the text and the parent of the comment */
  146.         success: function(msg){
  147.  
  148.             /* PHP returns the automatically assigned ID of the new comment */
  149.             var ins_id = parseInt(msg);
  150.             if(ins_id)
  151.             {
  152.                 wC.addClass('com-'+ins_id);
  153.                 addHistory({id:ins_id});
  154.                 $('#slider').slider('option', 'max', totHistory).slider('option','value',totHistory);
  155.                 lastVal=totHistory;
  156.             }
  157.  
  158.             transForm(text,cText);
  159.             // Hiding the form and showing the newly-added comment in its place
  160.         }
  161.     });
  162. }
  163.  
  164. function transForm(text,cText)
  165. {
  166.     var tmpStr ='<span class="name">Demo:</span> '+text;
  167.     cText.html(tmpStr);
  168. }

Las funciones de esta parte del código manejan la entrega de comentarios via AJAX al back-end PHP.

Como saben, se llama cuando hemos ejecutado de forma exitosa la petición AJAX (en este caso se llama si el comentario fue escrito a la base de datos MySQL).

Dentro de está función verificamos si se devuelve una ID apropiada, que corresponde a la id MySQL interna que se dió al campo auto-incrementado (miren abajo para la parte MySQL part o miren table.sql en los archivos de ejemplo).

Si todo est√° bien, llamamos la funci√≥n addHistory con la nueva informaci√≥n y actualizamos el valor m√°ximo del deslizador. Esto asegura que el nuevo comentario a√Īadido sea hist√≥ricamente scrollable con el resto de ellos.

Step 5 – MySQL

Este paso sólo se necesita si deseas hacer andar un demo en tu propio servidor.

Para poder hacer funcionar el demo, deberás crear la table MySQL wave_comments  con el siguiente código (también disponible en los archivos de ejemplo table.sql):

  1. CREATE TABLE `wave_comments` (
  2. `id` int(11) NOT NULL auto_increment,
  3. `parent` int(11) NOT NULL default '0',
  4. `usr` varchar(16) collate utf8_unicode_ci NOT NULL default '',
  5. `comment` text collate utf8_unicode_ci NOT NULL,
  6. `dt` datetime NOT NULL default '0000-00-00 00:00:00',
  7. PRIMARY KEY  (`id`),
  8. KEY `parent` (`parent`,`id`)
  9. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Con esto, ¡Nuestro deslizador histórico tipo Google Wave está completo!

Conclusión

Siéntanse libres de modificar el código de este ejemplo y utilizarlo en sus propios sitios. También sería genial que compartan lo que realicen con la comunidad. ¡Esperamos ver sus logros!

Descarga los archivos aqu√≠¬Ľ

Fuente: Tutorialzine


Enviar a Del.icio.us Enviar a Meneame Enviar a Digg Enviar a Fresqui Enviar a Enchilame

Comentarios (22)

  1. Henry Cabrera dice:

    Es realmente interesante y muchas gracias por los archivos me ayudaron bastante sigan asi

  2. Pablo Sela dice:

    Quiero que me llegue la invitación!!! quiero probar google wave!!!

  3. jose andres dice:

    Muy interesenate , sigan asi por favor y no se detengan en inculcar mas acerca de los tips , para beneficio y prosperidad de las paginas web. Gracias

  4. ERIC IGNACIO SANTIAGO TOGA dice:

    Me parece estupendo la mejora de las paginas WEB ya que ayuda aprovechando al maximo la funcionalidad
    de las paginas WEB

  5. uSorac2009 dice:

    Muy buen ejemplo. Gracias

  6. william gonzalez dice:

    muy buen tutorial y muy interezante lastima que no cuento con las herramientas para ponerlo en practica pero gracias por ayudarnos.

  7. panikus dice:

    Estaria bueno un tuto para implementarlo a algun sistema de foros o sistema de blogging

  8. jhonattan dice:

    Hola, muy bueno el tutorial, soy muy novato en esto del php, así que quiero preguntar cómo serías posible incluir esto en cada articulo de una página web para que la gente comente, pero solo los que esten registrados. Gracias.

  9. Pedro dice:

    Hola, intente implementarlo en mi pagina, tal cual ya que soy nuevo y primero queria verlo en funcionamiento para despues hacerle algunas modificaciones (Si es que puedo) pero no he podido echarlo a andar, la direccion es esta, y marca el error, me podrían ayudar?

    http://www.harteforjada.com/06productos/demo/demo.php

  10. Vicnero dice:

    hola me permito felicitar este blog en general me ah ayudado bastante
    tengo una duda acerca de este tema
    como le podre hacer para agregar
    un nuevo campo de entrada por ejemplo
    agregar un campo para el nombre de quien comenta
    se podra hacer? bueno espero y respondan
    zaludos!

  11. Maxorchuck dice:

    Muy bueno pero lo malo que no se como ponerlo en wordpress

  12. spacartagena fashionfrance dice:

    en este sitio puedes ver todo lo relacionado con el

  13. Roger dice:

    He conseguido hacer que me muestre los comentarios incluso a√Īadiendo un campo para el nombre pero no hay manera de que se a√Īadan los comentarios a la base de datos. Me estoy saltando algo porque no lo entiendo. alguien puede ayudarme? Gracias!

  14. infodisfap dice:

    estaba intentando mostrar solo 2 comentarios y no todos pero no he podido solo e podido que el slide se mueva a una posicion 2 mas me muestra todos los comentarios

    http://www.infodisfap.com/sistema_comentario/demo.php

    http://www.infodisfap.com/
    informacion discapacitados fuerzas armadas del peru

  15. Juan Sebasti√°n dice:

    Hola, excelente traducci√≥n, muy √ļtil y me result√≥ buenisimo, ahora el problema me surge cuando quiero agregar m√°s campos a la publicaci√≥n, algo normal, nombre, email y titulo, no se como editar el javascript y/o el savecomments.php para que los guarde correctamente.

    Ojal√° me puedas dar una mano, hasta siempre!

  16. derzz dice:

    hola haber si me ayudan…
    esoty aprendiendo php y no se como habilitar este sistema de comnts

  17. cheap louboutins dice:

    quiero agregar más campos a la publicación, algo normal, nombre, email y titulo, no se como editar el javascript

  18. juan jose rodrigo dice:

    al poner comentarios no se me guardan en la base de datas como hago para solucionarlos?

  19. abel dice:

    no se no me gusta mucho que digamos… igual esta bueno pero que control tenemos de los comentarios? ninguno.

  20. maikel dice:

    se agradece el aporte

  21. josué dice:

    muy buen aporte y orientación para mi persona gracias por los archivos

  22. Alexander dice:

    Buen tutorial… pero si se accede desde distintos navegadores donde esta alojado la aplicacion, si un usuario hace un comentario el otro no puede visualizarlo en tiempo real sino hasta k refresque la pagina… Como podr√≠a hacer que se vizualize en tiempo real para todos los usuarios… Espero puedan ayudar en eso, gracias.

Deja tu opinión

© 2007 - 2008 elWebmaster.com | Powered by Wordpress | Diseño CSS y XHTML válido. | Algunos íconos basados en FamFamFam Mini
Acceder