Seguindo à risca os padrões

Talvez vocês nem tenham reparado, mas meu site passou por uma grande mudança nos últimos dias.
A idéia era seguir de verdade os padrões web, enviando XHTML como XHTML de verdade para os browsers
que entendem. Como assim?

Vou explicar. XHTML é uma linguagem diferente do velho HTML. Na verdade é uma junção de HTML com
XML. Sendo uma linguagem diferente, o XHTML tem seu próprio MIME Type – application/xhtml+xml. Na verdade
não faz sentido usar XHTML se você o envia com o MIME Type de HTML.

Mas qual a vantagem disso?

Na verdade, não há vantagens reais perceptíveis. Pelo menos não pra mim. A única coisa interessante é que,
pelo menos na família Mozilla, um documento XHTML mal-formado não é exibido se o MIME Type correto for especificado.

Mal-formado? Não seria inválido? Não, um documento XHTML bem-formado e inválido será exibido perfeitamente. Ou seja, você precisa que todas as tags estejam devidamente fechadas e perfeitamente aninhadas, mas um id duplicado não
evitará que a página seja exibida. Caracteres como ‘&’, ‘<’, ‘>’ devem ser ser devidamente codificados na
forma de entidades HTML ‘&amp;’, ‘&lt;’, ‘&gt;’, respectivamente. Existem outros caracteres que devem
ser codificados, estou citando apenas os mais comuns.

Mas, se não há grandes vantagens em se usar esse MIME Type, por quê usá-lo? Bem, é uma questão de escolha.
Já que é pra seguir os padrões, vamos tentar seguí-los da melhor forma possível. De acordo com o
W3C, application/xhtml+xml deveria ser usado para servir documentos XHTML para user agents que entendem XHTML e os autores que quiserem suportar user agents XHTML e HTML ao mesmo tempo podem usar negociação de conteúdo (vamos chamar a partir daqui de content negotiation) para servir documentos XHTML como application/xhtml+xml e HTML como text/html.

Como vocês podem ver, não é obrigatório, mas é recomendado.

Dentre os user agents que não entendem XHTML está – adivinhem quem – o, com o perdão da má palavra, Internet Explorer. Ainda sonho com o dia que não vou precisar pensar neste “browser” ao desenvolver sites…

Existem outras complicações ao se servir documentos XHTML como manda o figurino. Por exemplo, os anúncios do google não são exibidos em páginas XHTML, já que a função javascript document.write() não funciona em XML.

Bom, mas vamos ao que interessa.

Content Negotiation

Como eu já havia citado acima, nem todos os user agents – browsers, spiders, leitores de tela, etc – reconhecem o MIME Type application/xhtml+xml. Portanto, para podermos agradar a gregos e troianos, devemos utilizar uma coisa chamada content negotiation para identificar as capacidades do user agent e entregar o conteúdo de forma que ele possa entender.

Para os usuários de PHP, este processo é bastante simples. Basta incluir algumas linhas de código no topo de seus scripts e pronto. Essas linhas eu tirei de um artigo sobre content negotiation que li no site 456 Berea Street. São elas:


<?php
if (stristr($_SERVER['HTTP_ACCEPT'], "application/xhtml+xml") || stristr($_SERVER["HTTP_USER_AGENT"],"W3C_Validator")) {
header("Content-Type: application/xhtml+xml; charset=utf-8");
header("Vary: Accept");
echo("<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>\\n");
} else {
header("Content-Type: text/html; charset=utf-8");
header("Vary: Accept");
}
?>

Vamos entender este código.

Na primeira linha verificamos se o user agent aceita application/xhtml+xml ou se o user agent é o W3C Validator – o validator não envia um header ACCEPT, mas reconhece este MIME Type. Caso positivo, enviamos um header HTTP indicando o content-type (MIME Type) application/xhtml+xml, mais um header Vary e escrevemos o prologue XML.

Vary? Sim, é interessante incluir este header para avisar a mecanismos intermediários de cache – como proxies por exemplo – que o content-type pode variar de acordo com o cliente que está fazendo a requisição.

Caso negativo – o user agent não aceita application/xhtml+xml e não é o validator – enviamos um header content-type indicando text/html e o header Vary. Perceba que neste caso não escrevemos o prologue XML, já que ele pode causar problemas, principalmente naquele programinha (o do ícone azul) daquela empresa de Redmond que muitos teimam em chamar de browser.

Este código não é completo. Além de verificar a capacidade do user agent de reconhecer application/xhtml+xml, deveríamos também levar em conta o q-rating. Q-rating é uma forma de o user agent informar suas preferências por MIME Types, charsets, etc. O artigo Content Negotiation, de Tommy Olsson explica passo a passo como reconhecer as capacidades do user agent e, levando em conta o q-rating, servir o conteúdo da forma mais adequada. Vale a pena a leitura.

E se eu tiver, além dos scripts PHP, arquivos XHTML puros? Bom, neste caso ou você deixa que eles sejam servidos como text/html ou então usa um artifício do apache para fazer como que seus arquivos .html sejam interpretados pelo PHP. Ainda tirado do artigo supracitado:


RemoveHandler .html .htm
AddType application/x-httpd-php .html

Isto deve ser incluído dentro do seu arquivo .htaccess. Para que isso funcione, é necessário que o servidor aceite este tipo de configuração nos arquivos .htaccess. Se tiver dúvidas, consulte o administrador.

E o Google Adsense?

Para quem exibe anúncios do google em seu site, servir arquivos XHTML como application/xhtml+xml pode ser uma grande dor de cabeça. Já que o google usa a um javascript, com funções document.write() para escrever o conteúdo de seus anúncios dentro de um <iframe> dentro da sua página e document.write() não funciona em XML e documentos XHTML são XML, os anúncios não são exibidos em páginas servidas com o MIME Type correto.

Mas, felizmente, existe uma maneira de contornar este problema.

O que se deve fazer é criar um documento HTML (servido com o MIME Type text/html) e incluí-lo dentro da sua página utilizando um <object>

Tirado do artigo making AdSense work with XHTML, do site Keystone Websites:

Note que o caractere » marca uma quebra de linha que foi inserida apenas por questões de espaço e deve ser desconsiderada


<?php header("Content-Type: text/html;charset=utf-8"); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="pt">
  <head>
    <title>Anúncios</title>
    <style type="text/css">
      body { margin: 0; padding: 0; }
    </style>
  </head>
  <body>
    <script type="text/javascript">
      Parâmetros normais do AdSense
    </script>
    <script type="text/javascript" src="http://pagead2.googlesyndication.com/ »
pagead/show_ads.js">
</script>
  </body>
</html>

A primeira linha envia um header content-type text/html. E o restante é HTML comum, com o código que você pega do google para incluir na sua página.

Salve este arquivo, por exemplo, como adsense.php e inclua no local desejado na sua página da seguinte forma:


<object data="/adsense.php" type="text/html"></object>

Se você quiser usar content negotiation, inclua as seguintes linhas, em PHP:


<div class="adsense">
<?php
if($mime == "application/xhtml+xml") {
    print "  <object data=\"/adsense.php\" type=\"text/html\"></object>\n";
} else {
?>
  <script type="text/javascript">
    Parametros normais do AdSense
  </script>
  <script type="text/javascript"
src="http://pagead2.googlesyndication.com/ »
pagead/show_ads.js">
</script>
<?php
}
?>
</div>

Note que usamos uma variável $mime, para verificar o MIME Type. cabe a você usar o que aprendeu neste artigo para atribuir o valor certo a esta variável.

Problema resolvido. Mas tem uma outra questão. Se você usar mais de um bloco de anúncios na sua página, pode acontecer de anúncios que foram exibidos no primeiro bloco, se repetirem nos próximos, já que usando o <object> o google não vai conseguir determinar a ordem dos blocos na sua página. Na verdade ele nem vai conseguir saber que você está usando mais de um bloco. Não é nada demais, mas é bom avisar.

Conclusão

Se você estiver afim de seguir os padrões de verdade, mesmo que não tenha de início nenhuma vantagem aparente, acredito que este artigo pode ajudá-lo bastante nesta tarefa.

Recomendo a leitura dos artigos linkados aqui. Eles são em inglês mas serviram como base para que eu pudesse usar estas técnicas e também para a elaboração deste artigo.

Outras mudanças foram feitas no site além do MIME Type. Agora estou usando UTF-8 ao invés de ISO-8859-1, dei uma enxugada no código XHTML para que ficasse mais legível e mais fácil de manter e também estou usando um esquema de templates e um arquivo PHP apenas para cuidar da manipulação de todas as URLs e gerenciar o conteúdo. Mas explicações sobre estas mudanças ficam para um artigo posterior.

Espero que este artigo os ajude. Infelizmente os comentários ainda estão desabilitados. Esta semana ainda devo reabilitá-los.

Leia também:

11 Comentários sobre “Seguindo à risca os padrões”

Faça um comentário

#1 | Hugo

Engraçado acabar de ler um artigo que exalta tanto o Gmail (do Google) por ser Web 2.0 e em seguida ler outro cujo principal empessilho de se adotar XHTML (que é uma das tecnologias na Web 2.0) seja justamente o Google Adsense (do Google). :D

Acho que as grandes vantagens no XHTML são:
A capacidade que o XML tem em usar outros padrões e trabalhar com AJAX. :-\

Quanto ao “E” demoníaco, acho que esta na hora dos webmaster começarem a boicotear aquela coisa. E se algum usuário reclamar alegue que é para o proprio bem dele. ;)


#2 | Wladmyr

Sua página inicial,
Seguindo Padrões?
apresenta 21 erros de validação.
Incoerente não acha?


Meu site foi bloqueado pelo google, não consigo mais mostrar o anuncio em meu site.

Vocês tem alguma ideia de como eu driblo esse bloqueio. Não consigo nem usar um iframe de outro endereço contendo os anúncios.


[...] Até o Google Adsense está funcionando corretamente, falo assim porque o Google utiliza um iframe para exibir seus anúncios e uma chamada document.write(), que não funciona em xml e graças ao post seguindo à risca os padrões, arrumei o script e esta tudo funcionando. [...]


#5 | Leonardo

bom o artigo!!
Deu p/dar uma idéia do que estou precisando!
Valeu!


Muito bom o artigo, me ajudou a usar o “application/xhtml+xml” somente nos browsers que o aceitavam, apesar d que testei com este contenttype no IE 6 e funfo do mesmo jeito (=D)…

Só uma dica, caso alguém precise fazer isso em ASP, como eu precisei (contra minha vontade), vai aí o código:

<%
Response.Charset = “utf-8″
If InStr(Request.ServerVariables(“HTTP_ACCEPT”), “application/xhtml+xml”) > 0 Or InStr(Request.ServerVariables(“HTTP_USER_AGENT”), “W3C_Validator”) > 0 Then
Response.ContentType = “application/xhtml+xml”
Response.AddHeader “Vary”, “Accept”
Response.Write “” & vbCrLf
Else
Response.ContentType = “text/html”
Response.AddHeader “Vary”, “Accept”
End If
%><!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

Tive que por o Doctype na mesma linha que fechava o código em ASP, pra que não pulasse uma linha no começo…

PS: Só fiz a tradução de PHP para ASP, mais nada…

t+


ops…
No comentário acima na 5ª linha do código (Response.Write “” & vbCrLf) deve ficar:

Response.Write "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf

Bruno, se possível edite o de cima e apague este…vlw


[...] Os editores de html sobem o arquivo geralmente em alguma codificação dentro do padrão ISO (Leia mais sobre isso nesse artigo bacana). Um bom editor deve ler diversos padrões UTF-8, ISO, ANSI, o meu é o PsPad; veja as opções que [...]


#9 | João Rodrigo Moreira

Bruno, obrigado pelas explanações. Sempre que tenho alguma dúvida acabo por cair por aqui, e sempre acabo aprendendo um pouco a mais. Realmente padrão padrão mesmo é um pouco + complicado do que parece. Gostaria que você fizesse um artigo a respeito do encoding UTF-8, pois lí que você mudou o seu site e tenho dúvidas a respeito. Obrigado!


Ainda não entendi por que não consigo abrir meus e-mails e só aparece esta janela no lugar de abrir meus e-mails. O QUE DEVO FAZER?


#11 | maria silva

não entendi muito este conteúdo


«

»

Deixe seu comentário


Veja as estatísticas