Quando não há uma página principal dentro de um diretório no Apache, ele geralmente (caso habilitado) mostra uma listagem de todos os arquivos e subdiretórios presentes. Este tutorial ensina como personalizar essa lista!
1. O Índice Automático do Apache…
Quando aprendemos sobre páginas Web, sabemos que quando criamos a página principal temos que colocar como nome index.html ou index.htm. Isto ocorre porque os servidores Web adotaram este padrão, então toda vez que especificamos um endereço que não contenha um arquivo na URL, ele vai procurar por um index.html ou index.htm.
Por exemplo, quando digitamos:
https://www.devin.com.br
Na verdade ele vai procurar o index.html que está dentro do diretório configurado para o domínio www.devin.com.br. Neste caso específico, a configuração diz para procurar também por um index.php. Seria a mesma coisa que digitar:
https://www.devin.com.br/index.php
No Apache, quem controla essa procura por um arquivo de índice é o mod_dir. Dentro do arquivo de configuração do Apache (httpd.conf) tem uma diretriz chamada DirectoryIndex que configura quais arquivos ele deve procurar. Em uma instalação normal de Apache, vai estar assim:
DirectoryIndex index.html index.htm
Com essa configuração, o Apache primeiro procura por index.html, se não achá-lo, procura por index.htm. Poderia mudar para qualquer coisa, exemplo:
Directory babaca.html index.php index.html assinatura.html index.htm
Neste caso ele iria procurar por babaca.html primeiro, caso não encontrasse procurava por index.php e por aí vai!
Caso nenhum destes arquivos especificados no DirectoryIndex seja encontrado, então o Apache executa o módulo mod_autoindex. Esse módulo gera uma página HTML com um índice automático de todos os arquivos e diretórios. O resultado é algo parecido com isto:
Como podem ver, não existe nenhum HTML no diretório e por isso ele lista todos os diretórios e arquivos que tinham no diretório /teste, quando acessei http://localhost/teste/.
A questão é: Como personalizar essa saída para deixar mais bonitinho? :D
1.1. Habilitando o Índice Automático
Para o mod_autoindex funcionar, é necessário que o diretório do Apache contenha a opção Indexes. Na configuração padrão do Apache você vai encontrar as linhas parecidas com estas:
<Directory /var/www/html> Options Indexes FollowSymLinks [...corte...]
Ou seja, acima estou dizendo que dentro do diretório /var/www/html, a geração automática de índice via mod_autoindex está habilitada (opção Indexes) e que os links simbólicos serão utilizados (FollowSymLinks).
Você pode usar esta diretriz tanto no arquivo de configuração principal, como em um arquivo .htaccess.
2. Entendendo a configuração Padrão
Pra começar a aprender como personalizar o mod_autoindex, nada melhor do que olhar a configuração que vem com todo Apache e que mostra a listagem como no screenshot anterior. Antes de mais nada, se você não usar nenhuma configuração adicional e o Options Indexes estiver habilitado, a listagem será assim:
Agora vamos analisar todas as configurações do Apache que tornam essa listagem mais bonita e útil, como mostrado na primeira imagem mostrada neste tutorial. Em sistemas como Red Hat ou Fedora, estas configurações estarão no arquivo principal (httpd.conf), já em sistemas Debian a configuração estará separada no arquivo mods-available/autoindex.conf.
É legal lembrar também que estas configurações também podem ser incluídas em um arquivo .htaccess quando permitido.
Vejamos:
IndexOptions FancyIndexing VersionSort HTMLTable NameWidth=* AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip x-bzip2 AddIconByType (TXT,/icons/text.gif) text/* AddIconByType (IMG,/icons/image2.gif) image/* AddIconByType (SND,/icons/sound2.gif) audio/* AddIconByType (VID,/icons/movie.gif) video/* AddIcon /icons/binary.gif .bin .exe AddIcon /icons/binhex.gif .hqx AddIcon /icons/tar.gif .tar AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip AddIcon /icons/a.gif .ps .ai .eps [...corte...] AddIcon /icons/back.gif .. AddIcon /icons/hand.right.gif README AddIcon /icons/folder.gif ^^DIRECTORY^^ AddIcon /icons/blank.gif ^^BLANKICON^^ DefaultIcon /icons/unknown.gif HeaderName HEADER.html ReadmeName README.html IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
E agora explicando as opções:
- IndexOptions: Aqui estão as opções principais de como a lista de diretórios vai ser gerada. O principal elemento que precisamos saber aqui é o FancyIndexing, que adiciona ícones aos arquivos, informações como tamanho e data de criação/modificação. Basicamente o FancyIndexing é quem deixa a listagem mais bonitinha :PAs outras opções são: VersionSort faz com que caso os arquivos tenham versões no nome (exemplo: 1.0, 1.01, 1.02, 1.1, etc), o Apache ordene da forma certa. O HTMLTable, na minha opinião bastante importante, gera uma tabela para a listagem, ao invés do texto solto, o que é útil para personalizar o visual depois. Por último, o NameWidth=* faz com que a coluna do nome se extenda o quanto for preciso, pois se especificar um número, ele vai cortar o resto do arquivo quando completar o número de caracteres.
- AddIcon*: Todas as diretrizes que começarem com AddIcon especificam que ícone mostrar para o arquivo/diretório. O AddIconByEncoding especifica o ícone de acordo com o tipo de codificação do arquivo, o AddIconBytype especifica pelo tipo de arquivo e o AddIcon especifica por um sufixo contido no arquivo. Os próprios exemplos citados acima já dão uma boa idéia de como usá-los. Para ver todos os ícones disponíveis no seu Apache, acesse o diretório http://www.dominio.com.br/icons/.
- DefaultIcon: Simples, quando não souber qual ícone usar (ou seja, não estiver configurado com AddIcon*), utilizar este ícone.
- HeaderName: Que arquivo incluir acima da listagem. No exemplo padrão, se o diretório tiver um HEADER.html no diretório, ele vai incluir antes da listagem começar na página. Esta é a diretriz chave para a personalização.
- ReadmeName: Funciona da mesma forma que o HeaderName, só que inclui um arquivo abaixo da listagem. No exemplo padrão, se existir um arquivo README.html, ele será incluído depois da listagem terminar na página.
- IndexIgnore: Quais padrões de arquivos devem ser ignorados na hora de listar. Em outras palavras, tudo que tiver definido nessa diretriz não vai ser mostrada na listagem. No exemplo padrão ele vai omitir os arquivos ocultos, tudo que terminar com ~, tudo que começar com HEADER e README, e arquivos relacionados à CVS/RCS.
Não é tão difícil entender né?
Então como deu pra perceber, os pontos-chave aqui são: IndexOptions FancyIndexing, HeaderName e ReadmeName.
3. Personalizando a listagem!
Agora que entendemos como funciona o mod_autoindex, está na hora de personalizá-los! Para fazer isso, precisamos modificar o IndexOptions com uma nova opção. Então o exemplo anterior ficará assim:
IndexOptions FancyIndexing VersionSort HTMLTable NameWidth=* SuppressHTMLPreamble
O SupressHTMLPreamble faz com que na hora de gerar a listagem, caso seja encontrado um HeaderName, o Apache não vai gerar um cabeçalho HTML padrão antes do arquivo HeaderName e da listagem.
Isso significa agora que o arquivo que você definir no HeaderName será o cabeçalho da sua página HTML e o ReadmeName servirá como rodapé! No cabeçalho você poderá agora incluir estilos CSS e outras coisas mais que desejar.
Vamos montar um exemplo bonito aqui. Eu vou substituir primeiro todos os ícones padrões do Apache para ícones do Oxygen Icons, depois fazer um cabeçalho e rodapé utilizando alguns templates simples.
Vamos considerar agora que nenhuma configuração do mod_autoindex foi feita. Vou incluir agora a seguinte configuração de IndexOptions:
IndexOptions FancyIndexing VersionSort HTMLTable NameWidth=* SuppressHTMLPreamble IndexOptions FoldersFirst IconWidth=22 IconHeight=22 Charset=UTF-8 XHTML IndexOptions SuppressDescription SuppressColumnSorting IgnoreCase IconsAreLinks IndexOptions SuppressRules
Agora vou incluir também os arquivos de cabeçalho e rodapé da página, que estarão dentro de um diretório chamado /includes na raiz do domínio Web.
O cabecalho.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" href="/includes/autoindex.css" type="text/css" media="screen" /> <title>Listagem Automática do Apache</title> </head> <body> <div id="wrapper"> <div id="titulo"><h1>Listagem Automática do Apache</h1></div> <!-- Exemplo de seleção tirado da documentação do Apache --> <form action="" method="get"> <p>Ordenar por: <select name="C"> <option value="N" selected="selected"> Nome</option> <option value="M"> Data de Modificação</option> <option value="S"> Tamanho</option> </select> <select name="O"> <option value="A" selected="selected"> Crescente</option> <option value="D"> Decrescente</option> </select> Padrão: <input type="text" name="P" value="*" /> <input type="submit" name="X" value="Ir" /></p> </form> <div id="listagem">
Agora o rodape.html:
</div> <div id="disclaimer"> <p>Este é um exemplo e este é o rodapé do exemplo!</p> </div> </body> </html>
Agora o autoindex.css que incluí no cabeçalho:
body { background-color: #2949ff; font-size: 13px; } img { border: 0; } #wrapper { background-color: #ffffff; width: 95%; margin: 20px auto 20px auto; padding: 10px; text-align: center; } #titulo { text-align: center; } #listagem table { width: 90%; margin: 10px auto 10px auto; border: 1px dotted #000000; text-align: left; } #listagem table tr th { display: none; } #disclaimer { width: 75%; margin: 0 auto 0 auto; background-color: #e0e0ff; border: 1px solid #000000; text-align: center; }
Pronto! Com esses 3 arquivos dentro do /includes, vamos adicionar as seguintes configurações no Apache:
HeaderName /includes/cabecalho.html ReadmeName /includes/rodape.html
Também mudei os ícones, mas não vou colocar todas as linhas aqui, exemplos:
AddIconByType (TXT,/icons/oxygen/text-plain.png) text/* AddIcon /icons/oxygen/tar.png .Z .z .tgz .gz .zip AddIcon /icons/oxygen/go-previous.png .. AddIcon /icons/oxygen/stock_folder.png ^^DIRECTORY^^ AddIcon /icons/oxygen/openofficeorg-20-presentation.png .odp AddIcon /icons/oxygen/application-x-rpm.png .rpm
Agora é só reiniciar/recarregar o Apache e testar nossa nova listagem. Olha só como ficou:
4. Outras Dicas
4.1. Utilizando o PHP junto ao mod_autoindex
A diretriz HeaderName do mod_autoindex só aceita arquivos que tem o tipo text/html e por padrão, para o PHP funcionar ele deixa os tipos de arquivos como application/x-httpd-php. Isso quer dizer que se você colocar no HeaderName, por exemplo, cabecalho.php, ele não vai aceitar.
Para resolver isso, temos que executar o PHP como CGI, assim podemos especificar que o arquivo é do tipo text/html, mas é executado como se fosse um CGI pelo Apache. Então primeiramente verifique que você tenha instalado a versão CGI do PHP, vendo se o arquivo /cgi-bin/php existe no servidor Web e seja executável.
Agora na configuração do Apache (dentro do <Directory> ou em um .htaccess), coloque as seguintes linhas:
AddType text/html .php AddHandler php-script .php Action php-script /cgi-bin/php
Depois recarregue o Apache. Lembre-se que esta configuração é apenas recomendada para diretórios que utilizarão o mod_autoindex realmente.
Agora você já pode mudar o HeaderName:
HeaderName /includes/cabecalho.php
Isto é bastante útil para gerar templates dinâmicos do seu site dentro do mod_autoindex. Pode ser usado também para melhorar a saída do exemplo anterior deste tutorial, mostrando o diretório atual que o usuário se encontra, se um usuário está logado, entre muitas outras coisas que uma linguagem de programação como o PHP proporciona.
E apesar de eu citar o PHP, isto serve para qualquer outro tipo de linguagem, já que na verdade a interface é CGI. Pode ser Python, C, Perl e até quem sabe shell-script!
4.2. Internacionalizando os cabeçalhos da tabela
O que me deu um impulso para escrever este tutorial foi a pergunta de como traduzir o cabeçalho da tabela, ou seja, as palavras Name, Last Modified, Size, Description. Procurando uma solução, não consegui achar uma muito robusta, pois na verdade o próprio mod_autoindex não permite fazer isso a não ser modificando seu código-fonte.
A solução que eu achei (e até apliquei no exemplo do tutorial) foi colocar um CSS que esconde este cabeçalho, sendo assim possível criar um outro cabeçalho! Infelizmente isso não iria funcionar em navegadores que não suportam CSS, como alguns navegadores em modo texto/terminal.
De qualquer forma, o seguinte CSS foi responsável por esconder o cabeçalho:
table tr th { display: none; }
Talvez haja uma solução mais robusta, mas quem sabe?
5. Referências
A principal referência sobre o assunto é a própria documentação do mod_autoindex, onde podemos encontrar uma descrição de todas as diretrizes possíveis:
- http://httpd.apache.org/docs/1.3/mod/mod_autoindex.html (Apache 1.3)
- http://httpd.apache.org/docs/2.0/mod/mod_autoindex.html (Apache 2.0)
- http://httpd.apache.org/docs/2.2/mod/mod_autoindex.html (Apache 2.2)