Ontem finalmente saímos da teoria e realizamos a marcação semântica do nosso blog usando microdata e os vocabulários schema.org.
Hoje explicarei passo a passo como fiz isto aqui no Loop Infinito. A qualquer momento você pode visualizar nosso código fonte e observar estas mesmas marcações lá.
Aconselho a leitura dos meus últimos 2 posts sobre o assunto, em especial do último onde explico como usar microdata e schema.org detalhadamente.
Identificando as entidades
O primeiro passo é identificar as entidades na página que desejamos marcar semanticamente. Aqui no Loop Infinito, apliquei as marcações em 3 páginas diferentes: a página inicial, a página interna do post (onde você está agora) e a página Sobre (a página Projetos ainda não fizemos).
Irei mostrar como realizei as marcações semânticas apenas na página inicial, onde aparece a listagem dos posts resumidos com links para suas versões completas. Caso você deseje saber como ficaram os códigos fontes das outras páginas, basta abri-los no seu navegador, o princípio de marcação é o mesmo. Abaixo segue um print screen de um destes posts resumidos da página inicial:
A primeira entidade que podemos identificar nesta página é o próprio Post, ou seja, um Artigo ou coisa parecida. Navegando pelo site do schema.org pude achar o vocabulário Article, que corresponde a Artigo. Percebi também que há mais 3 vocabulários que estendem de Article, ou seja, são vocabulários Article mais específicos, e estes são BlogPosting, NewsArticle e ScholarlyArticle.
Obviamente os nossos posts se encaixam na categoria BlogPosting, então este será o primeiro vocabulário a ser utilizado no nosso caso.
Antes
O trecho de código abaixo mostra como era o código fonte de um resumo de post (o exemplo abaixo ilustra o print screen acima). Dividi o código em blocos para facilitar a leitura (acho que ninguém gosta de ficar olhando para um monte de linhas de código de uma vez, né).
<!-- bloco do post -->
<section class="post-container">
<!-- menu da lateral direita -->
<aside class="post-meta"> ... </aside>
<!-- área principal do post -->
<article> ... </article>
</section>
Menu da lateral direita detalhadamente:
<aside class="post-meta">
<ul>
<!-- data da publicação -->
<li class="post-data">04/05/2012</li>
<!-- autor do post -->
<li class="post-autor">
<a href="...">Caio Gondim</a>
</li>
<!-- quantidade de comentarios -->
<li class="post-comentarios">
<a href="...">1 Comentário e 4 Reações</a>
</li>
<!-- tags do post -->
<li class="post-tags">
<ul>
<li><a href="..."><span>#</span>javascript</a></li>
</ul>
</li>
</ul>
</aside>
Área principal do post detalhadamente:
<article>
<!-- título do post -->
<header>
<h1><a href="...">Herança em JavaScript parte I</a></h1>
</header>
<!-- conteúdo do post -->
<section>
<!-- imagem principal -->
<p><img src="..." /></p>
<!-- texto (o post de fato) -->
<p>Uma das coisas que mais assusta programadores vindos de...</p>
<!-- link para o post completo -->
<a href="..." class="leia-mais">Continue lendo ↝</a>
</section>
</article>
OK, nada de mais. Basicamente uma marcação simples HTML5.
Depois
Agora vamos ver como ficou o código fonte depois da marcação semântica, percebam o uso das propriedades itemscope
, itemtype
e itemprop
. Mesmo esquema aqui, dividi o código em blocos:
Elemento geral
<!-- adicionamos as propriedades itemscope e itemtype para BlogPosting -->
<section class="post-container" itemscope="itemscope" itemtype="http://schema.org/BlogPosting">
<!-- adicionamos esta tag <span> para o publicador do post -->
<span class="hidden" itemprop="publisher">Loop Infinito</span>
<aside class="post-meta"> ... </aside>
<article> ... </article>
</section>
- Definimos a entidade principal (BlogPosting) no elemento que engloba todos os dados sobre o post;
- O elemento
<span>
não é visível para o leitor (classe.hidden
), pois foi adicionado apenas para podermos especificar que este post foi publicado pelo Loop Infinito comitemprop="publisher"
; - Os outros 2 elementos principais ainda permanecem inalterados por enquanto.
Obs.: A aplicação da propriedade itemscope="itemscope"
pode ser feita apenas colocando itemscope
dentro da tag, pois é uma propriedade que não contém valor explícito associado, e a especificação HTML permite seu uso desta maneira. Apenas usamos assim porque estamos obedecendo à sintaxe XHTML – também permitida no HTML5 – neste exemplo.
Menu lateral direito
<aside class="post-meta">
<ul>
<li class="post-data">
<!-- data de publicação do post -->
<time itemprop="datePublished" datetime="2012-05-06">
06/05/2012
</time>
</li>
<li class="post-autor">
<!-- autor do post -->
<a href="..." rel="author" itemprop="author">Caio Gondim</a>
</li>
<li class="post-comentarios">
<!-- contagem de comentários do post -->
<a href="..." itemprop="interactionCount">
1 Comentário e 4 Reações
</a>
</li>
<li class="post-tags">
<ul>
<li><a href="..."><span>#</span>javascript</a></li>
</ul>
<!-- palavras-chave do post -->
<span class="hidden" itemprop="keywords">javascript, ...</span>
</li>
</ul>
</aside>
- Envolvemos a data de publicação com um elemento
<time>
(novo no HTML5) para usar a propriedadeitemprop="datePublished"
. Usamos também a propriedadedatetime
para podermos especificar a data no formato padrão (aaaa-mm-dd); - Em autor, é aconselhável o uso da propriedade HTML
rel="author"
(leia sobre), além de especificar a propriedadeitemprop="author"
; - Na contagem de comentários, usei a propriedade
itemprop="interactionCount"
; - Adicionei um elemento
<span>
invisível para colocar todas as palavras-chave dentro, já de que as tags do post estão separadas por elementos<li>
acima. Usamos a propriedadeitemprop="keywords"
.
Área principal do post
<article>
<header>
<!-- título do post -->
<h1>
<a href="..." itemprop="headline">
Herança em JavaScript parte I
</a>
</h1>
</header>
<section>
<!-- imagem principal do post -->
<p><img itemprop="thumbnailUrl" src="..." /></p>
<!-- envolvemos o resumo com uma <div> a descrição do post -->
<div itemprop="description">
<p>Uma das coisas que mais assusta programadores...</p>
</div>
<!-- url do post -->
<a href="..." class="leia-mais" itemprop="url">Continue lendo ↝</a>
</section>
</article>
- Definimos o título do post com a propriedade
itemprop="headline"
; - A propriedade
itemprop="thumbnailUrl"
serve para especificar uma imagem associada ao post; - Adicionamos um elemento
<div>
para envolver o resumo do post, que servirá para definir a descrição do post através da propriedadeitemprop="description"
; - O link “Continue lendo” contém a URL do post, que pode ser usada para definir a URL da entidade através da propriedade
itemprop="url"
.
Testando
Bem, com isto terminamos a marcação semântica da página inicial do Loop Infinito usando o padrão HTML5 Microdata com os vocabulários schema.org.
Agora podemos testar se está tudo beleza com o Rich Snippets Testing Tool do Google. Basta informar uma URL que o crawler do Google realizará uma visita ao endereço informado, irá procurar por informações semânticas e depois irá exibir o resultado da varredura.
Fiz um teste com a URL da página inicial do blog (loopinfinito.com.br) e apareceram 5 itens BlogPosting (sem contar com este post). Eis um destes itens:
Item Type: http://schema.org/blogposting publisher = Loop Infinito datepublished = 2012-05-04 author text = Caio Gondim href = http://twitter.com/caio_gondim interactioncount text = Carregando... href = http://loopinfinito.com.br/2012/05/04/heranca-em-javascript-parte-1/#disqus_thread keywords = javascript, js, web development, desenvolvimento web, html5, front-end, programação, oop, orientação a objetos, herança, orientação a protótipos, java headline text = Herança em JavaScript parte I href = http://loopinfinito.com.br/2012/05/04/heranca-em-javascript-parte-1/ thumbnailurl = http://loopinfinito.com.br/images/posts/2012-05-04-heranca-em-javascript.jpg description = Uma das coisas que mais assusta programadores vindos de linguagens orientadas a objeto, como Java e C++, é a falta de classes em JavaScript. Muitos, inclusive, tentam simular este comportamento... url text = Continue lendo ↝ href = http://loopinfinito.com.br/2012/05/04/heranca-em-javascript-parte-1/
Com isto, vemos que o Google está extraindo nossos metadados de forma correta. Aconselho que façam o mesmo teste com as nossas outras páginas marcadas com schema.org (interna do post e Sobre) para quem possam ver as direfenças entre elas. A diferença entre a página inicial e a interna do post é mínima: no resumo da página inicial temos as propriedades thumbnailurl
, description
e url
, enquanto que na interna temos a propriedade articleBody
substituindo essas 3. Por hoje é só, até a próxima!