Sujet : A propos du référencement de Hoa

Hey,

par curiosité j'ai regardé la source de hoa de la page d'accueil en ce qui concerne le référencement.
J'ai relevé aucune balise méta (description, titre, keywords, author, etc...) est ce un oubli ?!

<head> 
  <title>Page principale — Hoa Framework</title> 
  <meta http-equiv="content-type"        content="application/xhtml+xml; charset=utf-8" /> 
  <meta http-equiv="content-script-type" content="text/javascript; charset=utf-8" /> 
  <meta http-equiv="content-style-type"  content="text/css; charset=utf-8" /> 
 
  <link type="image/png" href="Media/Image/Favicon.png" rel="shortcut icon" /> 
 
  <link type="text/css" href="Css/Reset.css"  rel="stylesheet" media="all" /> 
  <link type="text/css" href="Css/Base.css"   rel="stylesheet" media="screen,projection" /> 
  <link type="text/css" href="Css/Layout.css" rel="stylesheet" media="screen,projection" /> 
  <link type="text/css" href="Css/Print.css"  rel="stylesheet" media="print" /> 
  <!--[if lte IE 6]>
  <link type="text/css" href="Css/IE.css"     rel="stylesheet" media="screen,projection" />
  <![endif]--> 
 
  <script type="text/javascript" src="Asset/Script/Mootools.js"></script> 
  <script type="text/javascript" src="Asset/Script/Site.js"></script> 
</head> 

---

Il y a un bout de temps de ça, j'avais bricolé une classe HEAD pour facilité la gestion du head, et ressemant j'ai créé une classe pour générer des mots clés suivant des contenus.

Il me semble pas mal de créer un Package similaire à hoa_form, je me suis donc lancé il y a 2 jours dans la création d'un package Hoa_Head.

Je ne peux pas dire combien de temps ce Package va prendre car je suis assez charrette en ce moment, mais bon, petit à petit...

Voici les classes bricolées il y a longtemps, pour donner quelques idées sur le principe. bien sur le Package aura rien a voir dans la méthodologie utilisée.

A la recherche d'idées avant de me mettre pour de bon à la création...

/**
 * Classe de balise HEAD
 * Générateur de balises d'en-tête HEAD
 *
 * @version 1.5
 * @date 27/03/2008
 * @author Grégory Darche
 * @url http://netiva.fr
 */

class head {

    private $elements;       //!< (array) Tableau des balises ajoutées

    /**
     * Constructeur
     * Initialise la tableau des valeurs par default pour les balises
    */
    public function __construct () {
        $this->elements = array(
           # Commentaires
            'comments' => "<!-- ".date('Y-d-m H:i:s')." -->\r\n",
            # META
            'meta' => array(
                'http-equiv' => array(
                    'Content-Type' => 'text/html; charset=UTF-8',
                    'Content-language' => 'fr',
                    'Robots' => 'all,follow,index',
                    'expires' => '',
                    'refresh' => '',
                    'set-cookie' => ''
                    ),
                'schemes' => array(
                    'ISBN' => '',
                    ),
                'name' => array(
                    'title' => 'Ma page',
                    'keywords' => 'mot1,mot2,mot3',
                    'description' => 'Ma description',
                    'author' => 'Grégory Darche - Netiva.fr',
                    'copyright' => 'Netiva.fr 2007',
                    'rev' => 'support@netiva.fr',
                    'generator' => 'Netiva.fr !',
                    'rating' => 'general',
                    'revisit-after' => '7 days',
                    'robots' => 'all',
          'verify-v1' => '',      /* Clé de référencement google */
          'msvalidate.01' => '',  /* Clé de référencement bing */
          'y_key' => ''           /* Clé de référencement yahoo */
                    )
                ),
            # Link
            'link' => array(
                'favicon' => 'favicon.png',
                'stylesheet' => array(
          'files' => array(
                        'screen' => array(),
                        'print' => array(),
                        'media' => array(),
                        'aural' => array(),
                        'tty' => array(),
                        'tv' => array(),
                        'projection' => array(),
                        'handheld' => array(),
                        'braille' => array(),
                        'all' => array(),
                 'scripts' => array(),
                    )
                )
            ),
            # Scripts
            'script' => array(
                'javascript' => array(
                    'files' => array(),
                    'scripts' => array(),
                    )
                )
        );
        }

    #----------------------------------------------------------------------------
    # Fonctions title, http, metatags, keywords, description
    #----------------------------------------------------------------------------

    /**
     * setTitle
     * Définir la balise META TITLE
     *
     * @param     $str      (string)    Titre de la page
     * @param     $opt    (string)  optionnel - traitement de la variable
     *                            + permet l'ajout a la valeur actuelle (default)
     *                            = permet le remplacement de la valeur actuelle
    */
    public function setTitle($str, $opt='+') {
        if ($opt=='=')
        $this->elements['meta']['name']['title'] = $str;
        else
        $this->elements['meta']['name']['title'].= $str;
        }

    /**
     * setKeywords
     * Définir la balise META KEYWORD
     *
     * @param     $str      (string)  Mots clés de la page
     * @param     $opt    (string)  optionnel - traitement de la variable
     *                            + permet l'ajout a la valeur actuelle (default)
     *                            = permet le remplacement de la valeur actuelle
    */
    public function setKeywords($str, $opt='+') {
    if ($opt=='=') 
        $this->elements['meta']['name']['keywords'] = $str;
        else
        $this->elements['meta']['name']['keywords'].= ','.$str;
        }

    /**
     * setDescription
     * Définir la balise META DESCRIPTION
     *
     * @param     $str      (string)  Description de la page
    */
    public function setDescription($str) {
        $this->elements['meta']['name']['description'] = $str;
        }

    /**
     * setMetaName
     * Définir les balises META avec l'attribut NAME
     *
     * @param     $name      (string)  Contenu de l'attribut NAME
     * @param   $content(string)  valeur de l'attribut CONTENT
    */
    public function setMetaName($name, $content) {
        $this->elements['meta']['name'][$name] = $content;
        }

    /**
     * setMetaHttp
     * Définir les balises META avec l'attribut HTTP
     *
     * @param     $name      (string)  Contenu de l'attribut HTTP
     * @param   $content(string)  valeur de l'attribut CONTENT
    */
    public function setMetaHttp($name, $content) {
        $this->elements['meta']['http-equiv'][$name] = $content;
        }

    /**
     * setMetaSchemes
     * Définir les balises META SHEMES
     *
     * @param     $name      (string)  Contenu de l'attribut HTTP
     * @param   $content(string)  valeur de l'attribut CONTENT
    */
    public function setMetaSchemes($name, $content) {
        $this->elements['meta']['schemes'][$name] = $content;
        }

    /**
     * setFavicon
     * Définir la balise LINK FAVICON
     *
     * @param     $file      (string)  URL de l'icone
    */
    public function setFavicon($file) {
        $this->elements['link']['favicon'] = $file;
        }

    #----------------------------------------------------------------------------
    # Fonctions feuilles et scripts Javascript et CSS
    #----------------------------------------------------------------------------

    /**
     * addCssFile
     * Ajouter un fichier de style CSS
     *
     * @param     $file      (string)  URL du fichier
     * @param   $media  (string)  Optionnel - type de media (default:screen)
    */
    public function addCssFile($file, $media='screen') {
        array_push($this->elements['link']['stylesheet']['files'][$media], $file);
        }

    /**
     * addCssScript
     * Ajouter une portion de code CSS
     *
     * @param     $file      (string)  portion de code
    */
    public function addCssScript($script) {
        $this->elements['link']['stylesheet']['scripts'][] = $script;
        }

    /**
     * addJsFile
     * Ajouter un fichier javascript
     *
     * @param     $file      (string)  URL du fichier
    */
    public function addJsFile($file) {
        array_push($this->elements['script']['javascript']['files'], $file);
        }

    /**
     * addJsScript
     * Ajouter une portion de code Javascript
     *
     * @param     $file      (string)  portion de code
    */
    public function addJsScript($script) {
        $this->elements['script']['javascript']['scripts'][] = $script;
        }

    #----------------------------------------------------------------------------
    # Fonctions pour créer le code HTML <HEAD>
    #----------------------------------------------------------------------------

    /**
     * create
     * Créer la portion HTML contenant l'ensemble des balises générées
     *
     * @return     (string)  Portion HTML
    */
    private function create() {
        $h = $this->elements['comments'];
        $h.= "<title>".$this->cutString($this->elements['meta']['name']['title'], 80)."</title>\r\n";
        foreach($this->elements['meta']['http-equiv'] as $key => $value) {
        if (!empty($value))
        $h.= "<meta http-equiv=\"".$key."\" content=\"".$value."\" />\r\n";
        }
        foreach($this->elements['meta']['schemes'] as $key => $value) {
        if (!empty($value))
        $h.= "<meta schemes=\"".$key."\" name=\"identifier\" content=\"".$value."\" />\r\n";
        }
        foreach($this->elements['meta']['name'] as $key => $value) {
    if (!empty($value)) {
        if ($key=='keywords')
        $value = $this->cutString($value, 1000);
        else if ($key=='description')
        $value = $this->cutString($value, 200);
        $h.= "<meta name=\"".$key."\" content=\"".$value."\" />\r\n";
        }
        }
        foreach($this->elements['link']['stylesheet']['files'] as $media => $files) {
        foreach($files as $value) {
        $h.= "<link rel=\"stylesheet\" type=\"text/css\" href=\"".$value."\" media=\"".$media."\" />\r\n";
        }
      }
        if (!empty($this->elements['link']['favicon']))
        $h.= "<link rel=\"shortcut icon\" href=\"".$this->elements['link']['favicon']."\" />\r\n";
    $code='';
    if (isset($this->elements['link']['stylesheet']['scripts'])) {
        foreach($this->elements['link']['stylesheet']['scripts'] as $value) {
        $code.= $value;
        }
        }
        if ($code!=='')
    $h.= "<style type=\"text/css\">".$code."</style>\r\n";
        foreach($this->elements['script']['javascript']['files'] as $value) {
        $h.= "<script type=\"text/javascript\" src=\"".$value."\"></script>\r\n";
        }
      $code='';
        foreach($this->elements['script']['javascript']['scripts'] as $value) {
        $code.= $value;
        }
        if ($code!=='')
        $h.= "<script type=\"text/javascript\">".$code."</script>\r\n";
        $h = substr($h, 0, -2);
        return $h;
        }

    /**
     * __toString
     * Retourne la portion HTML contenant l'ensemble des balises générées
     *
     * @return     (string)  Portion HTML
    */
    public function __toString() {
      return $this->create();
        }

    #----------------------------------------------------------------------------
    # Fonctions privées diverses, debug et destructeur
    #----------------------------------------------------------------------------

    private function cutString($str, $nbChars) {
        if(strlen($str)>=$nbChars)
        return $str=substr($str,0,$nbChars);
        else
        return $str;
        }

    public function debug() {
        $str = nl2br(htmlentities($this->create()));
        $str.= '<pre>';
        $str.= print_r($this, true);
        $str.= '</pre>';
        return $str;
        }

    private function __destructor () {
        unset($this);
        }
        
//fin.
}

/**
 * Classe Native_Keyword
 * Générateur de mots clés pour un ensemble de textes
 *
 * @version 1.5
 * @date 28/06/2008
 * @author Grégory Darche
 * @url http://netiva.fr
 */

/**
 * Mises à jour
 * 
 * 01/07/2008  MODIF   Fonction addExceptions ajout d'option + ou = 
 * 01/07/2008   MODIF   Fonction addTxt ajout d'option + ou =
 * 01/07/2008   MODIF   Amélioration des conditions d'exclusion
 * 01/07/2008   MODIF   Amélioration des performances du regex de détection des verbes
 * 01/07/2008   AJOUT   Fonction addExceptions()
 * 29/06/2008   AJOUT   Suppréssion des verbes (er, ir, ez)
 */ 

class Native_Keyword {

    public $txt = '';
    public $keywords = array();
    public $min_word_length = 5;
    public $exceptions = 'center|justify';
    private $is_make = false;
    
    public function __construct ( $txt='' ) {
        
        self::addTxt($txt, '=');
    }

    public function addTxt ( $txt='', $opt='+' ) {

        // Remplacement
        if ($opt=='=') 
                $this->txt = $txt;

        // Ajout
            else if ($opt=='+') 
                $this->txt.= ' '.$txt;
    }

    public function addExceptions ( $exceptions='', $opt='+' ) {

        // Remplacement
        if ($opt=='=') 
                $this->exceptions = $exceptions;

            // Ajout
        else if ($opt=='+') 
                $this->exceptions.= '|'.$exceptions;
    }

    public function get ( $nb=10 , $remake=false ) {
    
        // on explore le texte si cela n'est pas fait
        if (!$this->is_make || $remake!==false)
            self::explode();
        
        $this->is_make = true;
        
        // On retourne le tableau des mots clés
        return array_keys(array_slice($this->keywords, 0, $nb));
    }

    public function explode ( ) {
    
        // On nettoie le texte
        $txt = self::clean($this->txt);

        // On démonte chaque mot du texte et on le place dans un tableau
        $this->keywords = explode('-', $txt);
        
        // on retire les mot de moins de 3 lettres ainsi que les exceptions
        $exceptions = explode('|', $this->exceptions);
        foreach($this->keywords AS $v => $k) {

            // si trop petit ou dans les exceptions
            if ( strlen($k) <= $this->min_word_length )
                unset($this->keywords[$v]);

            // si verbe
            if ( preg_match('/[^.]er|ir|ez$/', $k) )
                unset($this->keywords[$v]);

            // si dans les exceptions
            if ( in_array($k, $exceptions) )
                unset($this->keywords[$v]);

        }
        
        // On rassemble les mots et on les comptes
        $this->keywords = array_count_values($this->keywords);

        // On trie le tableau des mots clés par importance
        arsort($this->keywords, SORT_NUMERIC);
    }

    private function clean ( $txt='' ) {

        // Suppression des espaces en début et fin de chaîne
          $txt = trim($txt);

          // Mise en minuscule
          $txt = mb_strtolower($txt, 'UTF-8');
  
        // Suppression des balise HTML
        $txt = html_entity_decode($txt);
        $txt = strip_tags($txt);

          // Suppression des accents
          $remplace = array(
            'Š'=>'S', 'š'=>'s', '?'=>'Dj', '?'=>'dj', 'Ž'=>'Z', 'ž'=>'z', '?'=>'C', '?'=>'c', '?'=>'C', '?'=>'c',
            'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
            'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
            'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
            'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
            'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
            'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
            'ÿ'=>'y', '?'=>'R', '?'=>'r'
        );
        $txt = strtr($txt, $remplace); 

          // Suppression des espaces et caracteres spéciaux
          $txt = str_replace(' ', '-', $txt);
          $txt = preg_replace('#([^a-z0-9-])#', '-',$txt);

          // Suppression des tirets multiples
          $txt = preg_replace('#([-]+)#', '-', $txt);
       
          // Suppression du premier caractère si c'est un tiret
          if($txt{0} == '-')
              $txt = substr($txt,1);
       
          // Suppression du dernier caractère si c'est un tiret
          if(substr($txt, -1, 1) == '-')
              $txt = substr($txt, 0, -1);
       
          return $txt;
    }
// fin.
}
Le code c'est comme le paic citron, quand il y en a plus... il y en a encore !

2

Re : A propos du référencement de Hoa

Hey smile,

Merci pour la contribution.
Alors, déjà, oui Hoa n'a pas de référencement, mais c'est volontaire. Le projet est en bêta et je ne veux pas commencer à lui faire de la pub alors qu'il reste un peu bancal. Je ferai une vraie pub' quand j'aurai terminé les bases (du moins, ce que j'appelle les bases).

Pour Hoa_Head, ce serait plus un assistant de vue, mais l'idée est intéressante, je suis preneur. Ça m'évite une grosse partie documentation sur les en-têtes par moteur de recherche, donc je gagne beaucoup de temps. Fait moi signe quand ta classe est terminée, car ça m'intéresse smile.

Par contre, pour ton générateur de mot-clé pour une page donnée, il me faut plus d'informations. C'est un sujet auquel je n'avais jamais pensé, mais qui peut s'avérer fort intéressant et utile. Toutefois, il doit nécessiter des preuves dans la pertinence du résultat, quelque chose comme un rapport de recherche ou quelque chose d'aussi sérieux que ça. Ou as-tu puissé les sources ?

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

3

Re : A propos du référencement de Hoa

Hey,

pour Hoa_Head, je vais tenir informé au fur et a mesure, de toute façon je vais mettre sur papier les idées et les publier ici afin d'avoir une première version assez complète.

Pour le générateur de mots clé, il faut effectiviement réfléchir un peu plus. C'est un début car j'avais besoin de générer des mots clés pour des sites clients et je disposais de peu de temps. Cependant, j'obtient en moyenne une pertinence des mots à 73% avec les outils d'analyse du type "meta tag analyser".

Pour le moment la classe est simple et loin d'être une version définitive.
Son utilisation est assez simple :

La méthode addTxt() permet d'ajouter plusieurs textes à suivre à explorer.
La méthode addExceptions() permet de dresser une liste d'exceptions (mots a retirer absolument).
La méthode get() permet de retourner la liste de mots.

Exemple:

$kw = new Native_Keyword('mon premier texte...');
$kw -> addTxt('un second texte...');
$kw -> addTxt('et encore un autre si besoin...');
$kw -> addExceptions('premier|besoin|...');
echo '<meta name="keywords" content="monsite, '.implode(',', $kw->get('20')).'" />';

Couplé avec la classe Native_Head, on ferait:

$_head->setKeywords('mot1, mot2, mot3', '='); // le = reset la liste des mots
$_head->setKeywords('mot4, mot5', '+'); // le + ajoute a la liste de mots
$_head->setKeywords(implode(',', $kw->get('20'))); // pas de + car il est optionnel et par défaut

Cette classe est pour le moment très simple. Elle compte la récurrence des mots dans l'ensemble de textes, retire les mots de moins de 5 lettres puis retire les mots finissant par er, ir, ez.

Contrairement a l'anglais, le français n'est pas si facile. La conjugaison des verbes et les accords de divers mots rendent difficile la gestion des exceptions pour obtenir une pertinence idéal.

Si vous avez des idées, n'hésitez pas !


---


Hywan: Ou as-tu puissé les sources ?

Heu, dans ma petite tête ^^.
J'avais cherché une classe similaire à Native_Head car suivant le contenu il faut parfois ajouter à la volée du js ou du css soit en fichiers inclus  soit en codes insérés.
J'ai trouvé cette idée pratique donc j'ai bricolé cette classe.

Ta question porte peu être sur le Native_ qui préfixe les classes. Comme je t'en avais parlé il y a quelques temps sur un autre post, je me suis développé un petit CMS pour nos projets clients.
NATIVE -> NETIVA c'est le nom de notre société.

Voili voilou, allez..., préparation des affaires de plages pour le weekend et du bloc-note pour réfléchir à Hoa_Head

Au fait Hoa_Head vous va comme nom de Package ?

A bientôt.

Dernière fois dit par tetardo (10 Jul. 2009 14:02)

Le code c'est comme le paic citron, quand il y en a plus... il y en a encore !

4

Re : A propos du référencement de Hoa

Je pense que ta classe finira en helper bundle pour Hoa_View, mais peu importe du nom pour l'instant.

Pour la création de mot-clé, c'est très intéressant, vraiment. Il faudrait le faire sous-forme de plug-in attaché à la couche Response de Hoa_Controller (on commence à voir son utilité !). Mais pour l'instant, il faut se concentrer sur le code. On verra son application et son intégration à Hoa plus tard, c'est un détail.
Ta méthodologie n'est pas suffisamment pertinente. Il faudrait plutôt regarder du côté de la radicalisation des mots par exemple (stemming en anglais). Je te conseille la lecture d'un livre que je suis en train de lire : Algorithms on Strings. C'est très intéressant (mais un peu compliqué si on ne connaît pas les notions de graphes, d'automates, de théories des langages etc.; heureusement, un rappel est effectué en début de livre). Le livre est originellement édité en français mais je ne le trouve plus. Je pense qu'il y a des nombreuses réponses et algorithmes efficaces dans ce livre (pour l'avoir parcouru l'année dernière, j'en suis plus que persuadé). Une bonne piste à mon humble avis.

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »