sábado, 5 de janeiro de 2013

CodeIgniter: URLs SEO-friendly e localizados


Depois de ter visto como internationalizar CodeIgniter usando arquivos de idioma, vamos ver neste post como criar URLs localizados e SEO-friendly, isto é, URLs explícitos tanto para os motores de busca como para os usuários.

Limpeza dos URLs por defeito


Por defeito, os URLs incluem uma chamada para o ficheiro index.php: exemplo.com/index.php/controlador/metodo/parametro

Para obter um URL mais legível como exemplo.com/controlador/metodo/parametro, vamos usar as regras de reescrita de URL seguintes do Apache (no ficheiro .htaccess).
    .htaccess
    RewriteEngine on
    RewriteCond $1 !^(index\.php|images|robots\.txt)
    RewriteRule ^(.*)$ index.php/$1 [L]
O ficheiro de configuração (application/config/config.php) também deve ser alterado para indicar a página índice predefinida (vazio).
    $config['index_page'] = '';

Internacionalização: controlador e visão localizados


Por predefinição, os URLs produzidos por CodeIgniter (limpos por reescrita) são da forma exemplo.com/controlador/metodo/parametro

Um site internacionalizado deve passar nos seus parâmetros a linguagem de consulta (aqui usamos um código de idioma de duas letras).

O encaminhamento está definido no ficheiro application/config/routes.php
    // English
    $route['en/my-test/my-view'] = 'test/view/en';

    // Portuguese
    $route['pt/teste/visao'] = 'test/view/pt';
Suportam-se os URLs seguintes:
  • exemplo.com/en/my-test/my-view/
  • exemplo.com/pt/teste/visao/
Mas também estes:
  • exemplo.com/en/my-test/my-view
  • exemplo.com/pt/teste/visao
Assim, apenas as rotas listadas (outras sendo devolvidas em erro 404), mas dois URLs possíveis para cada página, uma com uma barra final, outra sem. Este é o problema do conteúdo duplicado onde vários endereços acessam ao mesmo conteúdo.

Cuidado: quando muda um URL durante a vida do site, os redirecionamentos 301 não podem ser configurados no ficheiro de configuração do encaminhamento mas ao nível do servidor (por exemplo, no ficheiro .htaccess).

Recuperação dos parâmetros


Para aceitar qualquer parâmetro adicional sem saber antecipadamente o seu valor, deve duplicar cada linha pela adição de (:any) que vai fazer corresponder com uma expressão regular o resto do URL com a segunda variável do controlador. Como pode ser visto na classe CI_Router (definida no ficheiro system/core/Router.php), (:any) é uma expressão regular gulosa (substituída por .+ que corresponde à qualquer carácter, incluindo a barra). Por conseguinte, é preferível substitui-la com ([^/]*) (qualquer carácter, exceto a barra).
    $route['en/my-test/my-view'] = 'test/view/en/';
    $route['en/my-test/my-view/([^/]*)'] = 'test/view/en/$1';
De outro modo, quereríamos poder passar qualquer número de parâmetros aos métodos dos controladores, sem a necessidade de definir por cada rota o número de parâmetros fixos que se podem aceitar. A solução anterior recupera apenas o primeiro parâmetro, na forma de string (onde preferiríamos uma tabela com todos os parâmetros).

Para fazer isso, vamos recuperar o URL completo no controlador e, em seguida, explodi-lo numa tabela com o método segment_array.
    class Test extends CI_Controller {
        public function view() {
            $params = $this->uri->segment_array();
O URL exemplo.com/en/my-test/my-view/param1/param2, portanto, cria a tabela Array ( [1] => en [2] => my-test [3] => my-view [4] => param1 [5] => param2 )

O primeiro elemento dele é o código de idioma, depois vem o controlador e a visão localizados (muito úteis se quiser fazer redirecionamentos), e por fim os parâmetros.

Como os parâmetros recuperados são independentes do encaminhamento, podemos reverter para uma expressão regular gulosa.
    // English
    $route['en/my-test/my-view'] = 'test/view/en/';
    $route['en/my-test/my-view/(.*)'] = 'test/view/en/$1';

    // Portuguese
    $route['pt/teste/visao'] = 'test/view/pt';
    $route['pt/teste/visao/(.*)'] = 'test/view/pt/$1';

Síntese


Separamos os nomes internos dos controladores e dos métodos deles dos nomes externos que aparecem nos URLs, o que é benéfico mesmo se o site suporte apenas um idioma. Então, falamos aqui de internacionalização, já que tudo está pronto para o site ser localizado em diferentes línguas/culturas. O código de idioma é passado antes o nome localizado do controlador no URL, dando a ilusão de um subdiretório específico para cada idioma suportado. Finalmente, o número de parâmetros suportados pelos métodos dos controladores é deixado livre no ficheiro de encaminhamento, desde que esteja gerido directamente nos métodos próprios.

Livro


CodeIgniter for Rapid PHP Application Development


Para ir mais longe, recomendo a leitura deste livro: CodeIgniter for Rapid PHP Application Development, por David Upton (2007, 220 páginas).


CodeIgniter : URLs SEO-friendly et localisées (em francês)
CodeIgniter: SEO-friendly localized URLs (em inglês)
CodeIgniter: URLs SEO-friendly y localizadas (em espanhol)

Sem comentários:

Enviar um comentário