このブログを始めてまだ間もないのだけど、一応Googleのウェブマスターツールをいろいろいじって勉強しています。

気になったのはウェブマスターツールの検索のデザイン>構造化データでエラーが出ていることです。microformatsのhcardやらでupdatedとかauthorのnが空とかよくわからないエラーが出ています。ネットを調べると深刻なエラーではないようでそのままでも問題ないみたいなんですが、やっぱり気持ち悪いので、対策できないか勉強をかねて調べた結果を記録しておきます。

エラーの原因

このブログのテーマは WorePressのtwentythirteen の子テーマとしてつくっています。 (2017/02/21 現在 Jekyllへ移行しています) 今回、確認できたエラーはtwentythirteenのソースに原因があるようです。microformatsの規格であるhAtomとhCardが正しく実装されていないためにGoogleでエラーにされてしまったようです。

Updatedがない – hAtomのエラー

一つ目はhAtomのエラーです。公式サイト http://microformats.org/wiki/hatom を確認したところ、Updatedとは、hAtomに含まれるhEentyのプロパティで、更新日付を表します。問題はこれが必須項目になっているため、本来省略できないのですが、twentythirteen では実装されていません。

hEntryの必須項目は、entry-title, updated, authorの3つ。他のentry-contentやpublished等は省略可能です。

twentythirteenで、updateを設定しているのは wp-content/themes/twentythirteen/functions.phpfunction twentythirteen_entry_date() です。次の該当部分

        $date = sprintf( '<span class="date"><a href="%1$s" title="%2$s" rel="bookmark"><time class="entry-date updated" datetime="%3$s">%4$s</time></a></span>', (fix-point)
                esc_url( get_permalink() ),
                esc_attr( sprintf( __( 'Permalink to %s', 'twentythirteen' ), the_title_attribute( 'echo=0' ) ) ),
                esc_attr( get_the_date( 'c' ) ),
                esc_html( sprintf( $format_prefix, get_post_format_string( get_post_format() ), get_the_date() ) )
        );

fix-pointのtimeタグのclass属性にUpdatedを追加することにしました。こうすることでdatetime属性がUpdatedの値になるはずです。

ノードが空です - hCard のエラー

/assets/2015/wordpress-how-to-fix-data-structure-error/node-empty-error.png

二つ目のエラーはhCardのエラーです。http://microformats.org/wiki/hcard によると hCard もmicroformatsの規格の一つで、いわゆる名刺を電子データ化したものと言えます。この中で名前を表す nプロパティ というのがあります。

この nプロパティ は人の名前を構造的に表現します。子プロパティとして、ファーストネーム、ミドルネーム、ファミリーネーム等の別々に定義する必要があります。

上のサイトにはこんな感じの例がのっています。

<span class="vCard">
  <span class="fn">Sally Ride</span>
  <span class="n">
    <span class="honorific-prefix">Dr.</span>
    <span class="given-name">Sally</span>
    <abbr class="additional-name">K.</abbr>
    <span class="family-name">Ride</span>
    <span class="honorific-suffix">Ph.D.</span>
  </span>
</span>

n の中に子タグが定義されていますね。この例は正しいhCardだと思います。

一方、こっちは間違い。

<span class="vCard">
  <span class="fn">Sally Ride</span>
  <span class="n">Sally Ride</span>
</span>

class=”n”のタグの内容が単なるテキストはNGみたいです。

ちなみに hCard の必須項目は fnプロパティ だけですので、nプロパティを省略しても有効な hEntry として見なされます。

これを前提に、エラーの原因を回避する方法を探したところ、こちらも twentythirteen のソースの中に該当箇所がありました。

wp-content/themes/twentythirteen/author.php のなかの

                        <header class="archive-header">
-                                <h1 class="archive-title"><?php printf( __( 'All posts by %s', 'twentythirteen' ), '<span class="vcard"><a class="url fn n" href="' . esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ) . '" title="' . esc_attr( get_the_author() ) . '" rel="me">' . get_the_author() . '</a></span>' ); ?></h1>
                        </header><!-- .archive-header -->

wp-content/themes/twentythirteen/functions.php関数 function twentythirteen_entry_meta()

        // Post author
        if ( 'post' ~= get_post_type() ) {
-                printf( '<span class="author vcard"><a class="url fn n" href="%1$s" title="%2$s" rel="author">%3$s</a></span>',
                        esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
                        esc_attr( sprintf( __( 'View all posts by %s', 'twentythirteen' ), get_the_author() ) ),
                        get_the_author()
                );
        }

この二つのソースはどちらも共通して、vcardの子要素でclass=”url fn n”と定義しています。ここが問題の箇所です。

単純化すると次のような状態なのですが、

<span class="vcard">
  <a class="fn n">山田太郎</a>
</span>

本来は次のようなことを要求されている訳です。

<span class="vcard">
  <a class="fn">山田太郎</a>
  <span class="n">
    <span class="family-name">山田</a>
    <span class="given-name">太郎</a>
  </span>
</span>

しかし、このままレンダリングされると、おかしなことになりますね。この仕様に疑問を感じました。

なので修正するとすれば、手取り早く nプロパティ を削除するのがいいでしょう。 nプロパティ を使う場合は、いろいろ書き換えが必要な感じもしますし、そこまでして nプロパティ を使う必要はないでしょう。

実際の修正は、子テーマを使っていますので、子テーマのfunctions.phpで、オーバーライドするように定義しました。上の関数をまるごとコピペして一部修正するだけですが、うーん、こういう修正の仕方すると子テーマを使うメリットあるのかな。。。

本題 microformatsとは何か

実はここからが本題だったりします。。。このエントリーの目的は、エラーの修正がメインではありません。 今回、私が知りたかったのはmicroformatsとは何ぞや?ということを調べたところ、その内容がおもしろかったので、それについて書きたいと思います。

結局のところ、microformatsとは、そういう名前の規格があるわけではありません。

hAtomやhCardといった各種規格はもちろんありますが、それよりもmicroformats.orgが提唱している理念がおもしろいです。

詳しくはAbount microformats を見ていただくといいのですが http://microformats.org/about

要するには、データやフォーマットに関する考えたなのだそうです。 新しいことを生み出す代わりに、既存の枠組みをうまく再利用しましょう、ということです。

独特のネーミングがおもしろい。

すでに広く使われているスタンダードな規格を再利用することで問題を解決しようという試み、というところに感心してしまったのです。特徴が一番表れているのは命名規約でしょう。

hAtomは “Atom Syndication Format” のネーミングを拝借し、 hCardは、vCard のネーミングを拝借していますので、

hAtomでは、entry-titleやentry-summaryのような割とモダンな?感じなのに、 hCardでは、fn、n、とか2世代ぐらい昔のITって感じです(笑)

こういう命名規則は流用しつつ、その使い方を、さらに既存のHTMLの枠組みの中で利用するという、不思議なアプローチがすごく感心したのです。

独特のフォーマットがおもしろい。

次のコードは、普通のHTMLにしか見えないのだけど、実はhAtomとhCardに準拠したデータとしても扱える(はず)

<p class="hentry">
  <h1 class="entry-title">エントリーのタイトル</h1>
  <span class="updated" datetime="2015-01-01">2015年1月1日</span>
  <span class="vcard">
    <span class="fn">作者のフルネーム</span>
  </span>
</p>

タグ名は何でもよくて、pタグ の代わりに divタグ でもよく、要するに表示目的であるHTMLをデータとして扱いやすいようにclass属性でマーキングしているだけですね。XMLデータをXSLTにレンダリングするのと逆ですね。

新しいものはほとんどなくて、ちょっとした工夫をした、というところです。

ちょっと違うかもしれませんが、Ruby on Railsがブレイクした時に「設定より規約」(Convention over Configuration)というコンセプトに感動した時のことを思い出しました。

気になった点

hAtom の h は何?

hCard と言いながら、クラス名にvCardを使うのもへんてこなんですが、そこがまたある意味、美しいこだわり感全開ですよね。ちょっとおもしろくないですか?

で、hCard とか hAtom の先頭の h とは何の略なんだろうか?と思うのですが、これはずばり HTML の H なんでしょうか?? vCardの V はこの規格を策定したVersit Consortiumの頭文字かなと勝手に思っているけれど、どこかに説明されていないかな?

最後に

エラーの修正に関しては、Googleの構造化データ テスト ツールで検証してエラーはでなくなったものの、これで正解なのかは、今後、Webマスターツールでの構造化エラーが減るのかどうか見届けていきたいと思います。

mciroformatsには感心しましたが、実際どの程度、活用されているのかまでは調べていません。正直、うまい使い所があるのかはピンとは来てません。

結局、Googleウェブマスターがエラーを出すためだけにしか使われていなかったらどうしょう。。。

参考サイト

次のサイトを参考にさせていただきました。ありがとうございました。 WordPress で構造化データエラー(entry-title, updated, author)にハイブリッド対応 – セルティスラボ