Ganhando visibilidade com schema.org

Ganhando visibilidade com schema.org

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.

BlogPostingArticleNewsArticleScholarlyArticleCreativeWork

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 &rarrw;</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 com itemprop="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.

<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 propriedade itemprop="datePublished". Usamos também a propriedade datetime 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 propriedade itemprop="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 propriedade itemprop="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 &rarrw;</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 propriedade itemprop="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!

#6