Live Blogging avec #WP custom post type / taxo

Crédits Photo Live On Air from the Isle of Wight by adambowie, on Flickr

√áa faisait un moment que je n’avais pas consacr√© un article √† WordPress, trop occup√© sans doute √† explorer les possibilit√©s de BuddyPress… Aujourd’hui je vous propose un petit tutoriel pour cr√©er une page de Live Blogging.

En fait l’id√©e est de disposer d’un outil simple pour ¬ę¬†retransmettre en direct¬†¬Ľ un √©v√®nement, un peu √† la mani√®re de ¬ę¬†yahoo live¬†¬Ľ, sauf que dans mon cas il s’agit de conf√©rences dans le cadre de mon taf :).

2013-02-13 : Update !!

Voici un child th√®me pour twentytwelve qui adapte le tuto en profitant notamment des tax query. Il suffit d’ajouter le shortcode expliqu√© dans la suite du tuto, de d√©finir un post meta du nom de duration avec une valeur en millisecondes pour la page qui accueillera vos live posts. Tested on WP 3.5.1.


2012-04-25 : Update !!

Thanks to Roger, i’ve fixed the ajaxurl issue.. To make things easier i’ve packed the scripts into a twentyeleven child theme. Tested on WordPress 3.4 beta 3.


Pour arriver à cet objectif voici ma recette :

  1. Votre WordPress (version 3.0 minimum)
  2. Un custom post type
  3. Une custom taxonomy de type tag
  4. Un soupçon de shortcode API
  5. Une pinc√©e d’ajax
  6. Une page ¬ę¬†LIve¬†¬Ľ WP assaisonn√©e d’un post-meta
  7. 0 plugin
  8. Garniture optionnelle : un mod√®le de page ūüėČ

Notre marmitte sera le script functions.php de notre thème actif, un script bien utile et pratique !

Commençons par le custom post type et la custom taxonomy :

Le custom post type a un avantage c’est qu’il n’est pas inclus par d√©faut dans le loop des posts classiques, du coup pour notre cas, nous ne prenons pas le risque de m√©langer les genres ! On peut √©ventuellement s’en passer en utilisant une cat√©gorie qu’on exclue du loop principal, du search, des archives… mais c’est vraiment se compliquer la vie et √©crire en dur des ID de cat√©gorie, j’aime pas trop. Si vous souhaitez en savoir plus, je vous conseille une nouvelle fois le blog de Justin Tadlock qui explique admirablement le concept de ce contenu particulier.

Pour ajouter nos contenus personnalis√©s, il s’agit d’ajouter un hook √† l’√©v√®nement d’init de WordPress, voici donc le d√©but de notre tambouille :

<?php
function function imath_live_post() {
    register_post_type( 'live-post', array(
        'label'           => __( 'Live Posts' ),
        'singular_label'  => __( 'Live Post' ),
        'public'          => true,
        'show_ui'         => true,
        'capability_type' => 'post',
        'hierarchical'    => false,
        'rewrite'         => false,
        'query_var'       => true,
        'supports'        => array( 'title', 'editor', 'author' )
    ) );
    
    register_taxonomy_for_object_type( 'live-tags', 'live-post' );
}
add_action( 'init','imath_live_post' );

function imath_live_taxonomies() {
    register_taxonomy( 'live-tags','live-post', array(
        'hierarchical' => false,
        'label'        => 'Live Tags',
        'query_var'    => true,
        'rewrite'      => false
    ) );
}
add_action( 'init', 'imath_live_taxonomies' );

NB : si vous préférez un type catégorie pour la taxo, changer dans le register_taxonomy la valeur de hierarchical pour true. Une fois que vous avez ajouté et enregistré ce code dans votre functions.php, vous allez retrouver un nouveau menu dans votre administration WordPress, comme illustré ci-dessous :

Tada ! On retrouve donc le lien vers la liste des ¬ę¬†live posts¬†¬Ľ, celui de l’ajout et vers la d√©finition de nos tags persos

Si on clique sur Ajouter, nous retrouvons l’ambiance des posts classiques tout en disposant de la box pour ajouter nos tags directement

Poursuivons par la shortcode API

Pour que √ßa soit plus simple au moment de configurer notre page ¬ę¬†Live¬†¬Ľ, l’utilisation de cette API est tr√®s int√©ressante puisqu’en fait elle nous permet de directement et simplement d√©clencher notre loop personnalis√© tout en lui passant des param√®tres. Dans notre cas nous lui passerons le ¬ę¬†slug¬†¬Ľ du tag, vous l’aurez compris ce tag nous permettra le cas √©ch√©ant d’organiser plusieurs retransmissions diff√©rentes

<?php
function function imath_live_event_handle_shortcode( $atts ) {
    extract( shortcode_atts( array(
        'ref' => '0'
    ), $atts ) );
    
    // didn't manage to make ajax requests with custom taxonomies
    $custom_tag_id = get_term_by( 'slug', $ref, 'live-tags' );
    
    // to check if there's a new post
    $check_latest = 0;
    
    // time to wait till next ajax call
    $duration = get_post_meta( get_the_ID(), 'duration', true );
    
    // it works when no ajax
    query_posts( 'taxonomy=live-tags&term=' .$ref. '&posts_per_page=-1' ); ?>
        <div id="event-countdown" style="border-bottom:solid 1px #CCC;margin-bottom:10px">
            Prochaine mise á jour dans <span><?php echo $duration/1000;?></span> sec(s)
        </div
        <div id="event-container">
        
            <?php if ( have_posts() ) : while ( have_posts() ) : the_post();
                if( $check_latest == 0 ) {
                    $the_latest = get_the_ID() ;
                } ?>
                
                <div class="live-post">
                    <h5><?php the_time("G:i");?> <?php the_title();?></h5>
                    <div class="live-content"><?php the_content();?></div>
                </div>
            
            <?php $check_latest +=1;   endwhile; else:   ?>
                <b>L'évènement n'a pas démarré, merci de revenir plus tard...</b>
            <?php endif; ?>
        </div>

        <?php wp_reset_query(); ?>
        
        <!--Beginning of the auto refresh code-->
        <script type="text/javascript">
            var live_interval = <?php echo $duration;?>/1000;
            var i=1;
            
            function refreshCountDown() {
                next_live = live_interval - i;
                jQuery( '#event-countdown span' ).html( next_live );
                
                if( next_live == 0 ) { 
                    i=0;
                }
                
                i+=1;
            }
            
            jQuery( document ).ready( function( $ ) {
                set_latest( <?php echo $the_latest;?> );
                
                //funtion for the countdown
                countDown = setInterval( function() {
                    refreshCountDown();
                }, 1000 );
                
                // ajax calls each $duration/1000 seconds
                refreshLive = setInterval( function() {
                    live_event_get_latest( the_new, <?php echo $custom_tag_id->term_id;?>);
                }, <?php echo $duration;?> );
            } );

        </script>
        
        <!--End of the auto refresh code-->
    <?php
}
add_shortcode( 'live-event', 'imath_live_event_handle_shortcode' );

Le shortcode √† ajouter √† notre page se pr√©sentera ainsi [live-event ref=¬†¬Ľslug-du-tag¬†¬Ľ]. Ainsi lorsque WordPress rencontre le shortcode live-event, il appelle la fonction imath_live_event_handle_shortcode en lui passant l’attribut ref lequel contiendra le slug de notre tag. $duration r√©cup√®re le post-meta de la page ¬ę¬†Live¬†¬Ľ permettant ainsi de nous laisser le choix de la dur√©e de l’intervalle en millisecondes. Dans l’exemple de la vid√©o, j’ai utilis√© 10s (10000 millisecondes). Le query_posts() recherche tous les ¬ę¬†live-posts¬†¬Ľ dont la taxonomy est ¬ę¬†live-tags¬†¬Ľ et le slug la valeur de l’attribut ref.

Ajax pour rafra√ģchir les ¬ę¬†live-posts¬†¬Ľ sans recharger la page.

Etrangement, je ne sais pour quelle raison, je ne suis pas parvenu √† utiliser le query_posts sur une custom taxo en ajax, j’ai donc cr√©√© une requ√™te sp√©cifique pour approvisionner la liste des live-posts si toutefois un nouvel id a √©t√© publi√©

<?php
function imath_add_js_live_event() {
    //Your WordPress page must have a this title : Live
    if ( is_page( 'Live' ) ) {
        ?>
        <script type="text/javascript" >
            var the_new;

            function set_latest( val ){
                the_new=val;
            }

            function live_event_get_latest( latest, tag ) {
                if ( ! window.ajaxurl ) {
                    ajaxurl = "<?php bloginfo( 'wpurl' ); ?>/wp-admin/admin-ajax.php";
                }

                var data = {
                    action: 'imath_refresh_event',
                    the_latest: latest,
                    the_tag: tag
                };

                jQuery.post( ajaxurl , data, function( response ) {
                    html = response.split("|");
                    id   = jQuery.trim( html[0] );

                    if( id != 'nonew' ) {
                        jQuery( '#event-container #latest' ).attr( 'id','' );
                        jQuery( '#event-container' ).html( html[1]+jQuery('#event-container"').html() );
                        jQuery( '#latest' ).fadeOut();
                        jQuery( '#latest' ).fadeIn();

                        set_latest( id );
                    }
                } );
            }
        </script>
        <?php
        }
}
add_action( 'wp_head', 'imath_add_js_live_event' );

function imath_refresh_event_stream() {
    global $wpdb;

    $latest = $_POST['the_latest'];
    $tag    = $_POST['the_tag'];

    //didn't manage to make ajax requests with custom taxonomies
    $new_live_posts = $wpdb->get_row( "SELECT ID, post_date, post_title, post_content
        FROM {$wpdb->base_prefix}posts
        LEFT JOIN {$wpdb->base_prefix}term_relationships ON({$wpdb->base_prefix}posts.ID = {$wpdb->base_prefix}term_relationships.object_id)
        LEFT JOIN {$wpdb->base_prefix}term_taxonomy ON({$wpdb->base_prefix}term_relationships.term_taxonomy_id = {$wpdb->base_prefix}term_taxonomy.term_id) WHERE post_type = 'live-post' AND post_status = 'publish' AND term_id='$tag' ORDER BY post_date DESC LIMIT 1");

    if ( $new_live_posts && $new_live_posts->ID > $latest ) {
       echo $new_live_posts->ID."|"; ?>
       <div class="live-post" id="latest">
            <h5><?php echo mysql2date( "G:i", $new_live_posts->post_date, false );
                echo $new_live_posts->post_title;?></h5>
                <div class="live-content"
                    ><?php echo $new_live_posts->post_content;?>
                </div>
            </div>
            <?php
        } else {
            echo "nonew|";
        }

        die();
}
add_action('wp_ajax_imath_refresh_event', 'imath_refresh_event_stream');

Notons que pour √©viter de trimballer le code partout dans le blog, il n’est charg√© que si c’est la page ¬ę¬†Live¬†¬Ľ qui est affich√©e. Apr√®s avoir ajouter ces deux derniers morceaux de code au functions.php, nous pouvons d√©sormais utiliser notre outil de Live Blogging :).

Ajout de la page ¬ę¬†Live¬†¬Ľ

Edition de la page Live

Il suffit de renseigner le titre ¬ę¬†Live¬†¬Ľ pour cette page, d’ins√©rer le shortcode dans l’√©diteur (dans notre exemple, le slug du live-tag est ¬ę¬†conference¬†¬Ľ et d’ajouter un post-meta ¬ę¬†duration¬†¬Ľ dont l’intervalle de temps est exprim√© en millisecondes (ici 10s).

Ensuite, pour les questions √©ventuelles, on peut charger le comment template dans le script page.php et autoriser les commentaires pour cette page. Si vous ne voulez pas toucher au script page.php, il suffit de le copier sous un autre nom, d’en faire un mod√®le de page et de l’affecter √† cette page.

Il ne reste plus qu’√† consommer !

Pour cela, il suffit d’ajouter un ¬ę¬†live-post¬†¬Ľ depuis le sous menu ¬ę¬†Ajouter¬†¬Ľ du menu Live posts de l’administration de WordPress, en n’oubliant pas de choisir le tag qui a √©t√© ins√©r√© dans le shortcode ;).

Voil√†, si vous souhaitez t√©l√©charger une archive du fichier functions.php ainsi qu’un exemple de mod√®le de page..

15 commentaires sur “Live Blogging avec #WP custom post type / taxo

  1. Bonjour Monsieur,

    I would like to try your code live tweeting a football match (real football, not american sh*t)
    From what I can understand (I am by no means a coder) there’s a php function which inserts actual time.
    How can I change this in order to show match time (and considering each game is divided into two 45′ halves) ?

  2. Hi, imath. I have been looking for something similar to this and this looks wonderful. (Your other work looks very interesting as well!) I’m running into a problem though, when using your example. I can get the duration timer to count down, but the AJAX for refreshing doesn’t seem to be working and I’m not sure what I’m doing incorrectly. If I refresh the page manually, my posts are there. Will this work on WordPress 3.3.2 or even 3.4 Beta 3 or is it too outdated? Thank you for any help.

  3. Hi @ Roger,

    Thanks for your feedback and comment.

    Just added a child theme to fix the ajax issue, i’ve built it in WP 3.4 beta 3. It should work in 3.3.2

    Check the grey box at the beginning of the post.

    Tell me if anything goes wrong ūüėČ

  4. Hi imath! Thank you so much for the quick response. I didn’t know you would actually go out of your way to edit anything. I was honestly looking for direction to find the issue myself. I’m a huge fan of learning and your tutorials here on this site are invaluable to me. I’ve learned a lot already, and I want to thank you for your contribution to the community.

    With that said, the update did not work for me right away, but it helped me spot an issue (at least on my end). On my debug.log file, it gave me 2 interesting notices:

    PHP Notice: Undefined variable: the_latest in /path/wp-content/themes/live-blogging/functions.php on line 94
    PHP Notice: Trying to get property of non-object in /path/wp-content/themes/live-blogging/functions.php on line 98

    This lead me to believe there was something wrong with the query that returns new live posts. After some editing, I got it to work. I’m not sure why what you provided for me did not work, but just in case any of your other users run into the same issue, I want to share the edit:

    http://pastebin.com/mdjWXvhT

    I thank you very much for the help, and I’m sorry to have bothered you. I love your explanations when you post new material. Please continue to do that, so that your users may also thoroughly learn WordPress/BuddyPress. You have a new reader here, for sure!

    1. Hello Roger,

      Thanks for the fix on the query and for your comment. Unfortunately, yesterday morning i didn’t have time to check the query as i wrote it when WP version was 3.0, i think it can be optimized (since WP introduced new features in custom taxo queries in newest versions). I’ll check it soon ūüôā
      You didnt bother me, i’m actually very happy you like my little contributions to the WordPress Community ūüėČ
      Thanks for your fidelity and feedbacks.

  5. Bonjour imath,
    Premièrement super script ! merci.
    Je l’ai test√© sur wp version 3.3.2 et je n’ai pas √©t√© d√©√ßu, √ßa fonctionne bien.
    Par contre depuis j’ai fait la MAJ de wordpress (3.5.1) et le script ne fonctionne plus.
    J’ai vu que le code faisait r√©f√©rence √† la page wp-admin/admin.php qui a depuis bien chang√©. Je n’y connais pas grand chose en ajax, j’ai test√© de mettre dans l’ent√™te de mon th√®me la m√™me version jquery que celle de wp 3.3.2 c’est √† dire la version jquery 1.7.1 et 1.7.2 mais rien √† faire ! donc je ne sais pas si c’est un probl√®me de jquery ou si cela faisait appel √† quelque chose de bien particulier dans l’ancienne page admin.php.
    En vous remerciant de votre aide.

      1. oui je l’ai test√© aussi. j’ai vu dans celui-ci qu’il lan√ßait le wp_enqueue_script(‘jquery’); , mais rien n’y fait !
        ça fonctionne pour vous sous la dernière version wp 3.5.1 ?
        Merci de votre réponse super rapide !!!!!

        1. Le truc date un peu en m√™me temps ūüôĀ Y a pas un plugin fait par WordPress sur le sujet ou dans jetpack peut √™tre.. Je regarde et te tiens au courant pour ce tuto.
          À+

        2. re,
          Oui effectivement quand j’ai vu la date des derniers commentaires j’avais un peu peur qu’il n’y ai pas de suite voir de r√©ponse.
          Et bien j’ai pas mal chercher, dans les plugins je n’ai pas trouv√© mon bonheur … l√† c’√©tait bien c’√©tait juste une page et non tout le site.
          Jetpack je ne pense pas non plus qu’il le fasse malgr√© sa panoplie…
          Par contre j’avais trouv√© le plugin ¬ę¬†live bogging¬†¬Ľ
          http://wordpress.org/extend/plugins/live-blogging/

          Mais ce n’est pas encore √ßa ! c’est un message qui apparait dans un article existant…
          En tout cas merci c’est sympa, y a pas urgence.
          Mais vous aviez un bon script l√† …

          1. Salut,

            Je viens d’ajouter un child th√®me pour 2012. Test√© sur WP 3.5.1. Il est important de rattacher les live post au tag ins√©r√© dans le shortcode et de bien d√©finir le post meta (champ personnalis√©) ¬ę¬†duration¬†¬Ľ avec une valeur en millisecondes pour permettre √† l’intervalle js de faire les requ√™tes ajax.
            Live Blogging 2012 child

            A+

  6. Bonsoir iMath,
    Excellent !!!!!!!!!!!
    ça fonctionne ! je te remercie encore une fois de ta rapidité et pour ton travail. ça fait plaisir de tomber sur une personne réactive.

    Tr√®s bon site, et super tutos…
    @+

Les commentaires sont fermés.