Forum Pplware
[Tutorial PHP] Criar tag cloud / word cloud - Versão de Impressão

+- Forum Pplware (http://forum.pplware.com)
+-- Fórum: Mais Tech (/forumdisplay.php?fid=11)
+--- Fórum: Programação e Web (/forumdisplay.php?fid=16)
+---- Fórum: Guias e Tutorials (/forumdisplay.php?fid=38)
+---- Tópico: [Tutorial PHP] Criar tag cloud / word cloud (/showthread.php?tid=382)



[Tutorial PHP] Criar tag cloud / word cloud - maiden - 18-08-2008 21:23

Boas,

A maior parte dos utilizadores da Internet já se deparou, a certa altura, com uma tag cloud (nuvem de tags) em sites bastante conhecidos como por exemplo o delicious, Flickr, Technorati ou, no geral, em qualquer website ou blog da Web 2.0.
Há quem lhe chame mais uma moda desta read-write web, algo que está no seu auge neste momento mas que poderá deixar de ser utilizado dentro em breve. Na minha opinião esta é uma forma eficaz e rápida de gerir os conteúdos do nosso blog, já que permite uma maior percepção global daquilo que escrevemos, os tópicos sobre os quais discutimos, etc.
Apesar da maior parte dos CMS's existentes possuírem já funções integradas para a criação destes elementos, ou da existência de sites como o MakeCloud que geram o código referente à tag cloud do site dado o url, decidi criar este tutorial para demonstrar que não é algo muito difícil de se fazer e também para aprender mais sobre este assunto.
Serão disponibilizados os ficheiros da aplicação e da base de dados (com alguns registos inseridos) num ficheiro .zip no final do post. Peço que não liguem ao aspecto da aplicação, visto que foi algo feito mais para demonstrar as partes técnicas (se alguém quiser melhorar a interface está à vontade Wink).

Afinal o que é uma tag cloud?

[Imagem: 30893b9493.png]

Uma tag cloud é uma percepção visual das tags / conteúdo existentes num website. É um conjunto de palavras (cada uma representa uma tag) cujo tamanho (geralmente é a propriedade mais utilizada, e foi a qual utilizei neste tutorial, mas podem variar outras propriedades como a cor, etc) varia de acordo com a frequência que uma tag é utilizada. Isto é, quanto maior for o número de posts nos quais uma tag conste, maior será o tamanho da palavra que lhe corresponde na tag cloud, e vice-versa.

Como posso criar a minha tag cloud?

Visto do que se trata quando falamos numa nuvem de tags, vamos deitar mãos à obra e criar a nossa própria tag cloud. Vou referir os principais passos, de forma a não tornar o tutorial demasiado extenso, e o resto podem encontrar no interior do ficheiro em anexo.

baseDados.php
Código PHP:
<?php

    
/**
     * baseDados.php
     * 
     * Possui a classe responsavel pela ligacao e interaccao com a base de dados
     **/
    
    // Constantes de configuracao de ligacao a base de dados
    
define('DB_SERVER','localhost');
    
define('DB_NAME''bdBlog');
    
define('DB_USER','root');
    
define('DB_PASS','');
    
define('TBL_POSTS','posts');
    
    class 
baseDados {
        
        public 
$connection;
        public 
$menorTag;
        public 
$maiorTag;
        public 
$dispersaoTags;
        
        function 
__construct() {
            
$this->connection mysql_connect(DB_SERVERDB_USERDB_PASS);
            
mysql_select_db(DB_NAME$this->connection);
        }
        
        function 
inserirPost($tags$titulo$conteudo) {
            
$data date('Y-m-d H:i:s');
            
            
$insComm "INSERT INTO " TBL_POSTS " (dataPost, tags, titulo, conteudo) "
            
"VALUES ('$data', '$tags', '$titulo', '$conteudo')";
            return 
mysql_query($insComm$this->connection);
        }
        
        function 
retornarPosts($tag 'all') {
            
$posts = array();
            if (
$tag == 'all') {
                
$getComm "SELECT * FROM " TBL_POSTS " ORDER BY dataPost DESC";
            } else {
                
$getComm "SELECT * FROM " TBL_POSTS " WHERE tags LIKE '%$tag%' ORDER BY dataPost DESC";
            }
            
$result mysql_query($getComm$this->connection);
            while (
$registo mysql_fetch_assoc($result)) {
                
array_push($posts$registo);
            }
            return 
$posts;
        }
        
        function 
retornarTags($sort 'nenhum') {
            
$postTags = array();
            
$tags = array();
            
$selComm "SELECT tags FROM " TBL_POSTS;
            
$result mysql_query($selComm$this->connection);

            
            while (
$registo mysql_fetch_assoc($result)) {
                
array_push($postTags$registo['tags']);
            }
            
            foreach(
$postTags as $tagKeys) {
                
$tagKeysSplitted explode(" "$tagKeys);
                foreach(
$tagKeysSplitted as $tag) {
                    
$tag strtolower($tag);
                    if (isset(
$tags[$tag])) {
                        
$tags[$tag] += 1;
                    } else {
                        
$tags[$tag] = 1;
                    }    
                }
            }
            
$this->menorTag min(array_values($tags));
            
$this->maiorTag max(array_values($tags));
            
$this->dispersaoTags $this->maiorTag $this->menorTag;
            
            if (
$this->dispersaoTags == 0) {
                
$this->dispersaoTags 1;
            }
            
            if (
$sort == 'tamanho') {
                
arsort($tags);
                return 
$tags;
            } else if(
$sort == 'alfa') {
                
ksort($tags);
                return 
$tags;
            }
            return 
$tags;
        }
    };
    
    
// Iniciar novo objecto do tipo baseDados (criaar uma instancia da classe)
    
$bd = new baseDados;
?>
Este é o ficheiro responsável pela ligação e interacção com a base de dados. É nele que o utilizador configura as suas credenciais de acesso à tabela da base de dados onde se encontram os posts e respectivas tags. Essas credenciais, que variam de utilizador para utilizador, deverão se introduzidas nas constantes definidas para esse fim:
  • DB_SERVER: Servidor onde se encontra a base de dados, se estiverem a correr a aplicação localmente basta colocar localhost ou 127.0.0.1
  • DB_NAME: Nome da base de dados na qual se encontra a tabela dos posts, a presente no ficheiro zip tem o nome bdBlog
  • DB_USER: Nome de utilizador com o qual vão aceder à base de dados
  • DB_PASS: Password do utilizador
  • TBL_POSTS: Nome da tabela de posts. Se não efectuaram alterações basta deixar o valor que vem por defeito (posts).
A classe baseDados possui os métodos de ligação e selecção da base de dados (através do construtor da classe - __construct()), inserção de posts (inserirPost()) e retorno de posts e tags (retornarPosts() e retornarTags(), respectivamente). Para este tutorial o método mais importante é o retornarTags() e é sobre ele que vou falar em mais pormenor.

De forma resumida, o método retornarTags percorre todos os registos da tabela posts de forma a obter a string presente no campo tags de cada um deles, que representa as tags em que o post se enquadra, separadas por espaços.
De seguida separa as palavras de cada string pelo espaço, através da função explode e, caso a tag em questão não conste do array associativo $tags, é inserida com uma unidade. Caso contrário é incrementada em uma unidade. A ideia é ter uma matriz que relacione o nome da tag e a quantidade de ocorrências da mesma.
Após estas operações é verificado qual o menor e maior número de ocorrências das tags, através das funções min e max, respectivamente. Estes valores são armazenados nos atributos $menorTag e $maiorTag da classe baseDados. A diferença entre a maior e a menor tag é guardada no atributo $dispersaoTags, que será utilizado mais adiante para verificar qual a taxa de aumento do tamanho da fonte que deverá ser aplicada.
Por fim, conforme o argumento passado no parâmetro $sort, o array $tags é ordenado por tamanho (de forma descendente) utilizando a função arsort ou alfabeticamente utilizando a função ksort que ordena as chaves (keys) do array associativo. Caso não tenha sido especificado nenhum argumento no parâmetro $sort é utilizado o valor por defeito - "nenhum". Desta forma a ordem dos elementos no array é a natural, a ordem pela qual foram lidos da base de dados.

No final do ficheiro é criado um novo objecto ($bd) da classe baseDados (característica da POO), de forma a que quando este for incluido no ficheiro index.php seja automaticamente efectuada a ligação à base de dados e garantidos os requisitos para a utilização dos métodos e atributos da classe.

processar.php
Código PHP:
<?php
    
    
/**
     * processar.php
     * 
     * Responsavel por receber e utilizar os dados enviados do form da aplicacao
     **/
    
    
include 'baseDados.php';
    
    class 
processar {
        function 
__construct() {
            if (isset(
$_POST['inserirPost'])) {
                
$this->processarPost();
            } else {
                
header("Location: index.php");
            }
        }
        
        function 
processarPost() {
            global 
$bd;
            
$tags trim($_POST['tags']);
            
$titulo trim($_POST['titulo']);
            
$conteudo trim($_POST['conteudo']);
            
            if (
$bd->inserirPost($tags$titulo$conteudo)) {
                
header("Location: index.php?action=insert&status=success");
            } else {
                
header("Location: index.php?action=insert&status=fail");
            }
        }
    };
    
    
// Criar objecto da classe processar
    
$process = new processar;
?>
No ficheiro processar.php é tratada a informação recebida pelos forms da aplicação (neste caso só temos o form de novo post). No construtor da classe é verificado se o utilizador veio realmente do form de introdução de novo post. Caso isto se verifique procede-se com a introdução do post na base de dados, caso contrário não existe razão para o utilizador se encontrar nesta página, pelo que é redireccionado para a página principal da aplicação.
No método processarPost() é chamado o método inserirPost do objecto $bd para adicionar a informação enviada através do POST à base de dados.

À semelhança do ficheiro baseDados.php é criado no final deste o objecto da classe processar.


index.php

O ficheiro index.php representa a página principal da aplicação e é nele que se econtra o código HTML dos posts e da tag cloud, que resultarão da execução do script php que recorrerá à classe baseDados criada anteriormente.

Na primeira linha do ficheiro, antes mesmo do DOCTYPE do HTML e da tag de abertura (<html>) fazemos a inclusão do ficheiro baseDados.php:
Código PHP:
<?php include 'baseDados.php'?>

Após a inserção do DOCTYPE e abertura das tags HTML, procedemos à criação da área de posts. Antes mesmo da iniciação do script PHP é criada a div posts que vai conter todos os posts.
Depois dá-se início ao script propriamente dito: é verificado se o utilizador seleccionou alguma tag da qual quer visualizar os posts, e estes são lidos da base de dados para um array através do método retornarPosts.
Após as operações sobre a base de dados é altura de transformar a informação obtida em código HTML, de forma a poder ser representada no website. Para isso percorremos o array criado anteriormente e para cada post é criada uma subdiv - post - na div posts, que possui os elementos armazenados na bd: título, data, conteúdo e tags do post.
Código PHP:
<h1>Posts Existentes</h1>
    <
div id="posts">
<?
php
    
global $bd;
    
$posts = array();
    if (isset(
$_GET['tag'])) {
        
$posts $bd->retornarPosts($_GET['tag']);
    } else {
        
$posts $bd->retornarPosts();
    }
    foreach (
$posts as $post) {
        print 
"<div id=\"post\">";
        print 
"<h2>" $post['titulo'] . "</h2>";
        print 
$post['dataPost'] . "<br />";
        print 
$post['conteudo'] . "<br />";
        print 
"<p class=\"tags\">Tags: " $post['tags'] . "</p>";
        print 
"</div>";
    }
?>
    </div> 

Por fim procedemos à parte fulcral deste tutorial, a criação da "caixa" que vai conter as tags do nosso blog. Para esse efeito é definida a div tagCloud.
No início desta div inseri os links para a página principal que fazem uso da querystring para enviar a informação relativa ao sistema rudimentar de sorting (ordenação) de tags que incluí, que só as ordena descendentemente pelo tamanho ou ascendentemente pela ordem do alfabeto.
De seguida dá-se início ao script PHP, com a verificação de se foi escolhida alguma tag específica para o carregamento de posts da base de dados. Caso não tenha sido seleccionada nenhuma, procede-se ao carregamento de todos os posts ordenados de forma descendente pela data.

São definidos os tamanhos de fonte minímos e máximos, respectivamente, através das variáveis $tagMinSize e $tagMaxSize, que são simultaneamente, em sentido matemático, o intervalo no qual o tamanho da fonte da tag variará ([tagMinSize, tagMaxSize]).

Por fim é criada uma ul (unordered list) que, após execução de outro script PHP conterá a lista de tags do nosso blog / website (cada tag dará origem a um item da lista). O array $tags é percorrido, seleccionando-se a tag em questão e o número de ocorrências da mesma. Desta forma, pega-se no número de ocorrências da tag ($size) bem como num conjunto de outras variáveis para efectuar um cálculo que nos permitirá obter o tamanho da fonte dessa tag (dentro do intervalo referido anteriormente). Este valor é armazenado na variável temporária $fontSize. Esta variável é utilizada para, através de CSS Inline (eu sei que não é a melhor técnica, mas foi a que me ocorreu), especificar o tamanho da fonte que a tag terá. A função intval tem como objectivo retornar apenas o valor inteiro do cálculo efectuado anteriormente, para obtermos por exemplo uma fonte com 18px e não 18.17768889999px (é aquilo a que geralmente vemos referido como "truncar" o valor, mas isto soa um pouco a brasileirismo).
Código PHP:
<div id="tagCloud">
        <
h2>Tag Cloud</h2>
        <
span id="sorting"><b>Ordenar:</b> <a href="index.php?ordTags=tamanho" title="Ordenar tags por tamanho">Tamanho</a
<
a href="index.php?ordTags=alfa" title="Ordenar tags alfabeticamente">Alfa</a></span>
<?
php
        
if (isset($_GET['ordTags']) && $_GET['ordTags'] == 'tamanho') {
            
$tags $bd->retornarTags('tamanho');
        } elseif (isset(
$_GET['ordTags']) && $_GET['ordTags'] == 'alfa') {
            
$tags $bd->retornarTags('alfa');
        } else {
            
$tags $bd->retornarTags();
        }
        
        
$tagMinSize 12;
        
$tagMaxSize 32;
        print 
"<ul>";
        foreach (
$tags as $tag => $size) {
            
$fontSize $tagMinSize + ($size $bd->menorTag) * ($tagMaxSize $tagMinSize) / $bd->dispersaoTags;
            print 
"<li style=\"font-size: " intval($fontSize) . "px\"><a href=\"index.php?tag=$tag\" title=\"$size post(s) com tag $tag\">$tag</a></li>";
        }
        print 
"</ul>";
}    
?>
</div> 

Como executar a aplicação?

Dentro do ficheiro .zip existem dois directórios: bd e myblog. Dentro do primeiro existe ainda outro directório com o nome bdblog o qual possui os ficheiros da base de dados. Esta pasta deverá ser copiada para o directório data presente no interior da pasta na qual se encontra instalado o MySQL.
A pasta myblog deve ser copiada para a pasta htdocs presente na pasta de instalação do Apache.

Após copiadas as pastas necessárias, deve-se proceder à configuração das credenciais MySQL. Para isso devemos dirigir-nos ao ficheiro baseDados.php presente na pasta da aplicação e inserir os dados da nossa conta nas constantes específicas como referido anteriormente.

Por fim devemos iniciar o Apache e o MySQL dirigirmo-nos ao nosso browser predilecto e aceder à aplicação através de http://localhost/myblog/ ou http://127.0.0.1/myblog/.


E com isto termino este "tutorial". Espero ter sido explícito e o mais correcto possível. Em caso de dúvida não hesitem em perguntar. Qualquer crítica será bem vinda Happy

Cumps,


RE: [Tutorial PHP] Criar tag cloud / word cloud - Sheik - 18-08-2008 21:56

Confesso que não o li do início ao fim, mas só posso dizer:

Grande post Wink


RE: [Tutorial PHP] Criar tag cloud / word cloud - Ana - 18-08-2008 22:55

Muito interessante!