URLs relativas são URLs que não incluem as partículas de protocolo e nome de domínio a que pertencem. Exemplos:

  • /sobre.html
  • /contato.php
  • home.php

As URLs são ser relativas somente à "pasta" em que se encontram (como no home.php acima); para que uma URL seja relativa à raiz do domínio ou subdomínio é necessário que ela comece com o caractere de barra, como nos dois primeiros exemplos.

Em contrapartida, URLs absolutas são as que incluem pelo menos o nome do domínio (com a chegada do HTML5 o protocolo passou a ser opcional). Exemplos:

Por padrão, todas as URLs de um blog WordPress são absolutas. O próprio sistema faz com que todos os recursos sejam referenciados pela URL completa, o que é muito saudável porque minimiza os riscos de links quebrados dentro do próprio site.

Entretanto, há pelo menos duas situações em que pode ser útil ter um blog configurado para usar URLs relativas.

A primeira diz respeito àqueles casos em que o ambiente de desenvolvimento não está na mesma maquina do ambiente de produção (o que deveria ser a regra, mas parece, infelizmente, ser a exceção).

O segundo caso em que as URLs relativas podem ser úteis é quando o dono do blog é neurótico por desempenho e quer uma economia ainda maior ao evitar de transferir uns poucos bytes a mais por página do servidor para o cliente.

A rigor haveria até uma terceira hipótese para alguém querer seu WP usando somente URLs relativas, mas ela desviaria demais do propósito do presente artigo, e vai ficar para uma outra oportunidade.

O Plugin Super Cache para URLs Relativas

Para quem deseja apenas resolver seu problema de URLs relativas em ambiente de desenvolvimento, ou não quer sujar as mãos com código, o plugin Relative URL será suficiente.

Para outros casos será necessário abordagens mais agressivas, e a que proponho implica escrever um pequeno plugin para o WP-Super-Cache (o melhor plugin de cache, indispensável para qualquer WordPress) que antes de salvar o cache de uma dada página vai converter todas as URLs para suas equivalentes relativas, em vez de absolutas.

Um plugin para Super Cache é diferente de um plugin padrão para WordPress. Há limitações, contextos que não existem, e filtros e ganchos específicos para o Super Cache.

Infelizmente a documentação para quem deseja escrever seu próprio plugin é confusa e superficial, mas apesar disso consegui escrever um plugin que resolve o meu problema, e torna todas as minhas URLs internas em relativas.

O código do plugin é muito simples.

<?php  
function relativepaths_internal($theURL, $buffer){  
    $theProtocol = ('https' == substr($theURL, 0, 5) ? 'https://' : 'http://');

    $URL = explode($theProtocol, $theURL);
    $domainfolder = $URL[1];
    $domain = explode('/', $domainfolder)[0];
    $site = $theProtocol.$domain;

    $buffer = str_replace("=\"$site/", '="/', $buffer);
    $buffer = str_replace("='$site/", '=\'/', $buffer);

    // DEBUG:
    // $buffer .= "\n" . '<!-- $site = ' . $site . ' -->';
    return $buffer;

}
function relativepaths_action( $buffer ) {  
    $theURL = strtolower(get_bloginfo('url'));
    $buffer = relativepaths_internal($theURL, $buffer);

    // Garante que não vai haver mixed content em caso de páginas https
    $theURL = str_replace('https://', 'http://', $theURL);
    $buffer = relativepaths_internal($theURL, $buffer);
    return $buffer;
}

function relativepaths_actions() {  
    global $cache_relativepaths;
    if( $cache_relativepaths == '1' ) {
        add_filter( 'wpsupercache_buffer', 'relativepaths_action' );
    }
}
add_cacheaction( 'add_cacheaction', 'relativepaths_actions' );

wp_supercache_relativepaths_admin() {  
    global $cache_relativepaths, $wp_cache_config_file, $valid_nonce;

    $cache_relativepaths = $cache_relativepaths == '' ? '0' : $cache_relativepaths;

    if(isset($_POST['cache_relativepaths']) && $valid_nonce) {
        $cache_relativepaths = (int)$_POST['cache_relativepaths'];
        wp_cache_replace_line('^ *\$cache_relativepaths', "\$cache_relativepaths = '$cache_relativepaths';", $wp_cache_config_file);
        $changed = true;
    } else {
        $changed = false;
    }
    $id = 'relativepaths-section';
    ?>
    <fieldset id="<?php echo $id; ?>" class="options">
        <h4><?php _e( 'Relative Paths', 'wp-super-cache' ); ?></h4>
        <form name="wp_manager" action="" method="post">
            <label><input type="radio" name="cache_relativepaths" value="1" <?php if( $cache_relativepaths ) { echo 'checked="checked" '; } ?>/> <?php _e( 'Enabled', 'wp-super-cache' ); ?></label>
            <label><input type="radio" name="cache_relativepaths" value="0" <?php if( !$cache_relativepaths ) { echo 'checked="checked" '; } ?>/> <?php _e( 'Disabled', 'wp-super-cache' ); ?></label>
            <p><?php _e( 'Enables or disables plugin to force relative paths.', 'wp-super-cache' ); ?></p>
            <?php
            if ($changed) {
                if ( $cache_relativepaths )
                    $status = __( "enabled" );
                else
                    $status = __( "disabled" );
                echo "<p><strong>" . sprintf( __( "Relative Paths is now %s", 'wp-super-cache' ), $status ) . "</strong></p>";
            }
            echo '<div class="submit"><input class="button-primary" ' . SUBMITDISABLED . 'type="submit" value="' . __( 'Update', 'wp-super-cache' ) . '" /></div>';
            wp_nonce_field('wp-cache');
            ?>
        </form>
    </fieldset>
    <?php

}
add_cacheaction( 'cache_admin_page', 'wp_supercache_relativepaths_admin' );  
?>

O código acima cria uma interface padrão para ativação do plugin nas opções avançadas do Super Cache. Caso o plugin esteja habilitado o código fará a substituição de toda incidência da URL do site (seguida por uma barra) para a barra propriamente dita:

$buffer = str_replace("=\"$site/", '="/', $buffer);
$buffer = str_replace("='$site/", '=\'/', $buffer);

Meu código é mais uma prova de conceito, então não faço verificações mais avançadas, tais como a verificação de se o endereço do site é parâmetro de algum tipo de link ou não.

Para fazer uso do plugin ele deve ser salvo no diretório de plugins do Super Cache, diretamente com a extensão .php (o nome de arquivo sugerido é relativepaths.php).

Caso prefira baixar o plugin que funciona nos meus sites, o link segue abaixo.

relativepaths.zip

Garantias e Suporte

Naturalmente, como de costume, a única garantia que posso dar é que o código acima funciona bem no meu ambiente. Ponto. Tampouco posso dar suporte (a menos que você seja cliente da PortoFácil).

Antes de fazer uso do plugin apresentado faça backup de seu blog, e se caso algo sair errado restaure o backup. Sua hospedagem web poderá ajudar com essa questão.

PageSpeed

Você deve preferir usar o mod_pagespeed sempre que possível para tornar suas URLs relativas. É mais seguro, funciona sempre, e funciona em qualquer página, não só nas páginas do WP Super Cache.