Comment lister les derniers articles WordPress sur un site en PHP ?

De plus en plus de développeurs font le choix d’utiliser la plateforme WordPress pour développer l’ensemble d’un site internet et non pas seulement le blog. Cette démarche a l’intérêt de préserver très facilement une cohérence globale sur le site. Une seule gestion des utilisateurs, une seule gestion des commentaires, un seul routing…

Pour ma part, je préfère garder séparée la plateforme de blog WP du reste de mon site. Mais j’ai pourtant envie d’afficher la liste des derniers articles postés sur mon blog directement sur mon site. Comment faire ?

Les solutions

Le flux RSS

Une des solutions qui semble la plus retenue par les développeurs est la récupération et le parsing du flux RSS généré automatiquement par WordPress. Ce choix présente de nombreux avantages comme la possibilité de choisir le flux adapté à son besoin : tri par tag, par auteur, par catégorie…

En revanche, le parsing peut être un peu compliqué et semble moins performant qu’un accès direct en base. J’ai donc choisi d’utiliser une classe PHP qui récupère directement dans ma base de données WordPress les articles et informations associées. Si toutefois vous préférez la solution « Flux RSS », sachez que de très nombreux exemples pourront être dénichés sur les forums francophones dédiés à WordPress ou sur Google en général.

Récupération en base

La deuxième solution consiste donc à se connecter directement à la base de données de WordPress pour y récupérer à la demande les derniers articles et les informations associées.

En cherchant sur Google je suis tombé sur un projet de Peter Upfold dédié à ce sujet. Développé en PHP, cette classe permet après configuration de générer automatiquement le code HTML permettant de lister les derniers articles de son blog. Si vous cherchez une solution clé en main, je vous invite à consulter directement son site :

http://peter.upfold.org.uk/projects/wpget

Vous trouverez même à cette adresse un script permettant de générer automatiquement le fichier de configuration adapté à votre serveur (adresse base de données, nom d’utilisateurs, password…) :

http://peter.upfold.org.uk/projects/wpget/installer

WPGet Installer

Une fois le fichier wpget.php configuré, vous n’aurez plus qu’à écrire dans le code un bout de script semblable à celui ci-dessous pour insérer la liste de vos derniers articles correctement formatée en HTML :

<?php include_once("./wpget.php");
$wpget = new wpGet;
$wpget->dateformat = "d/m/Y H:i";
$wpget->showcredit = false;
$wpget->getWordpressEntries(2, 200, true, true, true); ?>

Pour ma part, je cherchais une classe plus simple que je pourrai utiliser dans mon application symfony et qui me laisserai gérer la partie présentation manuellement. J’ai donc réécrit entièrement la classe de Peter Upfold pour finalement obtenir deux petites classes PHP 5 (tant qu’à faire !). La première gère la récupération des données en base et la deuxième représente de manière simple un article WordPress avec les getters et setters associés.

Je vous livre le code tel quel ci-dessous :


<?php

/*
Réécriture de la classe PHP de Peter Upfold (http://peter.upfold.org.uk)
pour récupérer la liste des derniers articles postés sur un blog WordPress.

@author: Olivier Balais (http://blog.overnetcity.com)
*/
class WPEntries
{
  protected $dbUser;
  protected $dbPwd;
  protected $dbHost;
  protected $dbName;
  protected $dbTablesPrefix;

  protected $connection;

  // Fonction trouvée à l'origine sur http://uk2.php.net/manual/en/function.substr.php#59719
  private static function html_substr($posttext, $minimum_length = 200, $length_offset = 20, $cut_words = false, $dots = true)
  {
    // $minimum_length:
    // The approximate length you want the concatenated text to be

    // $length_offset:
    // The variation in how long the text can be in this example text
    // length will be between 200 and 200-20=180 characters and the
    // character where the last tag ends

    // Reset tag counter &amp;amp; quote checker
    $tag_counter = 0;
    $quotes_on = false;
    // Check if the text is too long
    if (strlen($posttext) > $minimum_length) {
      // Reset the tag_counter and pass through (part of) the entire text
      $c = 0;
      for ($i = 0; $i < strlen($posttext); $i++) {
        // Load the current character and the next one
        // if the string has not arrived at the last character
        $current_char = substr($posttext,$i,1);
        if ($i < strlen($posttext) - 1) {
          $next_char = substr($posttext,$i + 1,1);
        }
        else {
          $next_char = "";
        }
        // First check if quotes are on
        if (!$quotes_on) {
          // Check if it's a tag
          // On a "<" add 3 if it's an opening tag (like <a href...)
          // or add only 1 if it's an ending tag (like </a>)
          if ($current_char == '<') {
            if ($next_char == '/') {
              $tag_counter += 1;
            }
            else {
              $tag_counter += 3;
            }
          }
          // Slash signifies an ending (like </a> or ... />)
          // substract 2
          if ($current_char == '/' &amp;amp;&amp;amp; $tag_counter <> 0) $tag_counter -= 2;
          // On a ">" substract 1
          if ($current_char == '>') $tag_counter -= 1;
          // If quotes are encountered, start ignoring the tags
          // (for directory slashes)
          if ($current_char == '"') $quotes_on = true;
        }
        else {
          // IF quotes are encountered again, turn it back off
          if ($current_char == '"') $quotes_on = false;
        }

        // Count only the chars outside html tags
        if($tag_counter == 2 || $tag_counter == 0){
          $c++;
        }

        // Check if the counter has reached the minimum length yet,
        // then wait for the tag_counter to become 0, and chop the string there
        if ($c > $minimum_length - $length_offset &amp;amp;&amp;amp; $tag_counter == 0 &amp;amp;&amp;amp; ($next_char == ' ' || $cut_words == true)) {
          $posttext = substr($posttext,0,$i + 1);
          if($dots){
            $posttext .= '...';
          }
          return $posttext;
        }
      }
    }
    return $posttext;
  }

  private static function convert_smart_quotes($string) // not mine either - thanks to Chris Shiflett at http://shiflett.org/archive/165
  {
    $search = array(chr(145),
    chr(146),
    chr(147),
    chr(148),
    chr(151));

    $replace = array('‘',
    '’',
    '“',
    '”',
    '—');

    return str_replace($search, $replace, $string);
  }

  public function __construct($dbUser = "", $dbPwd = "", $dbHost = "localhost", $dbName = "wordpress", $dbTablesPrefix = "wp_")
  {
    $this->dbUser         = $dbUser;
    $this->dbPwd          = $dbPwd;
    $this->dbHost         = $dbHost;
    $this->dbName         = $dbName;
    $this->dbTablesPrefix = $dbTablesPrefix;

  }

  public function getLastEntries($number = 2, $limit = null, $stripJavascript = true, $stripImages = true, $stripEmbed = true)
  {
    // Connexion à la base de données
    try
    {
      $connection = new PDO('mysql:host='.$this->dbHost.';dbname='.$this->dbName, $this->dbUser, $this->dbPwd);
    }
    catch(Exception $e)
    {
      echo $e->getMessage();
      die();
    }

    // Préparation de la requête
    $request = $connection->prepare("SELECT `post_content`, `post_date`, `post_title`, `display_name`, `comment_count`, `guid`
    FROM `".$this->dbTablesPrefix."posts` as posts
    INNER JOIN `".$this->dbTablesPrefix."users` as users ON users.ID = posts.post_author
    WHERE posts.`post_status` = 'publish' AND posts.`post_type` = 'post'
    ORDER BY `post_date` DESC LIMIT ".$number.";");

    // Récupération des articles
    $articles = array();

    try
    {
      $request->execute(array());
    }
    catch(Exception $e)
    {
      echo $e->getMessage();
      die();
    }

    while ($result = $request->fetch(PDO::FETCH_OBJ))
      {
      $content = $result->post_content;

      if ($limit > 0)
      {
        $content = stripslashes(self::html_substr($content, $limit, 20));
        $content = self::convert_smart_quotes($content);
      }
      else
      {
        $content = self::convert_smart_quotes($content);
      }

      if ($stripJavascript)
        $content = ereg_replace("<script.*</script>", "", $content);

      if ($stripImages)
        $content = ereg_replace("<img.*/>", "", $content);

      if ($stripEmbed)
        $content = ereg_replace("<embed.*</embed>", "", $content);

      $article =
        new WordPressArticle($content,
        $result->post_date,
        $result->post_title,
        $result->display_name,
        $result->comment_count,
        $result->guid);

      $articles[] = $article; // Ajout de l'élément à la liste à retourner
    }

    return $articles;
  }
}

class WordPressArticle
{
  protected $content;
  protected $postDate;
  protected $postTitle;
  protected $authorName;
  protected $commentsCount;
  protected $link;

  public function __construct($content = "", $postDate = "", $postTitle = "", $authorName = "", $commentsCount = "", $link = "")
  {
    $this->content = $content;
    $this->postDate = $postDate;
    $this->postTitle = $postTitle;
    $this->authorName = $authorName;
    $this->commentsCount = $commentsCount;
    $this->link = $link;
  }

  public function setContent($content)
  {
    $this->content = $content;
  }

  public function getContent()
  {
    return nl2br($this->content);
  }

  public function setPostDate($postDate)
  {
    $this->postDate = $postDate;
  }

  public function getPostDate()
  {
    return $this->postDate;
  }

  public function setPostTitle($postTitle)
  {
    $this->postTitle = $postTitle;
  }

  public function getPostTitle()
  {
    return $this->postTitle;
  }

  public function setAuthorName($authorName)
  {
    $this->authorName = $authorName;
  }

  public function getAuthorName()
  {
    return $this->authorName;
  }

  public function setCommentsCount($commentsCount)
  {
    $this->commentsCount = $commentsCount;
  }

  public function getCommentsCount()
  {
    return $this->commentsCount;
  }

  public function setLink($link)
  {
    $this->link = $link;
  }

  public function getLink()
  {
    return $this->link;
  }
}


Ci-dessous, un exemple de fonctionnement simplissime dans une application symfony.

Dans l’action :

/**
* Executes index action
*
*/
public function executeIndex()
{
  $wpEntries= new WPEntries("db_user", "db_pwd", "localhost", "wordpress", "wp_");
  $this->entries = $wpEntries->getLastEntries();
}

Dans la vue :

<ul>
 <?php foreach($entries as $entry): ?>
 <li><?php echo $entry->getPostTitle() ?></li>
 <?php endforeach ?>
/ul>

Tout simplement !
N’hésitez pas à utiliser ce bout de code et à me faire un retour le cas échéant.

Ajouter une ou plusieurs signatures HTML dans GMail

GMail est un outil fabuleux !

Longtemps j’ai refusé de fournir mes données à Google par principe. Je trouve très angoissant l’idée de voir l’intégralité de sa vie électronique gérée par une entreprise qui détient déjà le monopole de la recherche sur Internet.

Néanmoins, après de longs mois de résistance, il a bien fallu se rendre à l’évidence qu’aucun des Webmails disponibles sur le marché n’égale de près ou de loin GMail. Premier webmail à supporter correctement et gratuitement l’IMAP, support des comptes Exchange, intégration quasi parfaite dans la nébuleuse Google… J’ai bien tenté GMX pendant un moment mais son incapacité à gérer correctement les caractères unicode m’a poussé vers Google.

Mais comme rien n’est parfait, Gmail a lui aussi ses défauts. Et parmi ces défauts, on compte l’absence de gestion intégrée des signatures riches, c’est à dire, au format HTML. Difficile à comprendre d’ailleurs.

Plusieurs solutions existent. Celle que j’ai retenu utilise un script qui permet de créer un lien à ajouter dans vos favoris. Ce lien, une fois cliqué, insère dans le mail en cours de rédaction la signature associée. Des plugins existent pour Chrome et Firefox notamment visant à simplifier l’insertion de signatures dans GMail. Aucun ne m’a encore convaincu à l’heure actuelle…

Etape 1 :

Dans un premier temps, créez votre signature au format HTML. Il existe certainement des outils prévus à cet effet en ligne. Je vous donne ici le code de ma signature en exemple :

<p>
  <img  src="http://www.francetelecom.com/sirius/logos_mail/obs_left.gif"  width="94" height="40">
</p>
<p style="font-family: Arial, sans-serif; margin-top: 0pt;  margin-bottom: 5px; font-size: 10pt; color:#000000;">
  <span style="font-weight:bold;">Olivier Balais</span>
</p>
<p style="font-family: Arial, sans-serif; margin-top: 0pt;  margin-bottom: 0pt; font-size: 10pt; color:#000000;">
  tel. 06.89.xx.xx.xx<br />
  <a href="mailto:mon_mail@orange-ftgroup.com" style="font-family:  Arial, sans-serif; font-size: 10pt;  color:#ff6600">mon_mail@orange-ftgroup.com</a><br />
  BU IT&Labs <br />
  <a href="http://www.orange-business.com" style="font-family: Arial,  sans-serif; font-size: 10pt;  color:#ff6600">www.orange-business.com</a>
</p>
<p>
  <img  src="http://www.francetelecom.com/sirius/logos_mail/ampersand.gif"  width="18" height="20">
</p>

Vous constaterez que le CSS est inclut directement dans le code HTML sans passer par une feuille de style. En effet, la plupart des clients mails ne gèrent pas les feuilles de style externes. Il est donc préférable de gérer sa signature de la sorte. De la même manière, pour une signature un peu plus complexe que celle là, il est plus prudent d’utiliser les tableaux HTML plutôt que les propriétés float CSS.

Etape 2 :

Une fois votre code HTML préparé, rendez-vous sur cette page : http://projets.geekfg.net/?/1-how+to+insert+html+signature+in+gmail.htm, cliquez sur le bouton HTML, et collez votre code.

Insertion code signature

Cliquez sur le bouton TEXT pour vérifier si le rendu vous semble correct.

Rendu visuel signature

Appuyez ensuite sur GO STEP 2 pour continuer.

Etape 3 :

Le script a généré un lien à ajouter à vos favoris. Vous n’avez donc plus qu’à glisser / déposer ce lien dans vos favoris et à le renommer comme il se doit.

Bouton favoris signature

Désormais, quand vous rédigerez un mail dans GMail, vous n’aurez qu’à cliquer sur le favoris ainsi créé pour que la signature HTML s’insère automatiquement. L’avantage de cette technique est que vous pouvez créer plusieurs signatures différentes pour les différents profils professionnels et personnels que vous pouvez avoir.

Rendu final signature gmail

Bienvenue sur OvernetCity

Que dire dans un premier article ?

Il est certainement d’usage de souhaiter à tous la bienvenue sur son blog quoique, vraisemblablement, s’agissant d’un premier article, personne ne visite encore ce blog. Il y a donc bien peu de chance que cet article soit lu.

Malgré tout, s’il s’avère un jour qu’un visiteur remonte dans le passé et les archives de ce blog, il y a une probabilité que cet article soit bel et bien lu… Soyons prévoyant !

Cher lecteur, via ce premier article, je te souhaite la Bienvenue sur mon blog…

Il y a bien longtemps que je souhaite ouvrir un blog. Ce n’est d’ailleurs pas la première fois que je le fais. Aussitôt créé, aussitôt supprimé. Pour un blog il faut du temps et surtout un sujet. L’idée de créer un blog est similaire à celle de créer une entreprise. J’ai toujours eu, quelque part, l’envie de créer une entreprise. Créer. Oui mais on ne crée pas une entreprise pour créer une entreprise. Et bien c’est la même chose pour un blog. Encore faut-il savoir quoi écrire, de quoi parler, quelle ligne éditoriale suivre, quelle information relayer, quelle information s’approprier.

J’ai l’impression aujourd’hui d’avoir mûri la question. Depuis toujours passionné par l’informatique et les nouvelles technologies d’une manière générale, ce blog sera pour moi l’occasion de transmettre certaines actualités intéressantes (pour moi en tout cas !), rédiger quelques articles techniques ou encore, partager avec vous la vision que j’ai du monde tel qu’il se prépare.

Je vous invite donc à me suivre, à me répondre éventuellement et à me transmettre toute information que vous trouvez pertinente et en rapport avec le sujet de ce blog.

A très bientôt j’espère…