WordPress向け、OGPベースでのブログカードの作り方

##きっかけ

[この投稿](https://wp-simplicity.com/suport/topic/%E5%A4%96%E9%83%A8%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AEogp%E3%81%8B%E3%82%89blogcard%E3%82%92%E4%BD%9C%E3%82%8B/)を見つけて、導入したかったOGPベースのブログカード。試行錯誤の末、実装できましたので完成コードを載せておきたいと思います。このコードは、データベース操作にWordPress独自の関数を用いてますので、ご了承願います。

###メリット

* iframeやscriptに頼らなくていい
* キャッシュ処理ができる
* デザインが自由自在

##下ごしらえ

[このレポジトリ](https://github.com/scottmac/opengraph)からOGP情報パース用のライブラリをダウンロード。ただ、私の環境では、[このissue](https://github.com/scottmac/opengraph/issues/38)にある[この処理](https://github.com/scottmac/opengraph/pull/39)をしなければ文字化けしました。

##PHP側の実装

```php
function make_ogp_blog_card($url){
    $cache = get_site_transient($url);
    if($cache):
        $content = $cache;
    else:
        require_once('inc/OpenGraph.php');
    	$ogp           = OpenGraph::fetch($url);
        $url           = $ogp->url;
        $share_url     = urlencode($url);
        $id_url        = mb_strtolower(str_replace(':/.','',$url));
        $img           = $ogp->image;
        $title         = $ogp->title;
        $site_name     = $ogp->site_name;
        $description   = str_replace(']]<>',']]＜＞',$ogp->description);
        $tw_acount     = '';
        $get_tw_acount = get_twitter_acount();
        if($get_tw_acount!==null){$tw_acount = '&amp;via=' . $get_tw_acount;}
        $script      = "document.getElementById('ogp-blogcard-share-" . $id_url . "').classList.toggle('none');document.getElementById('ogp-blogcard-share-" . $id_url . "').classList.toggle('block');";
        $content     =
        '<div class="ogp-blogcard">
            <div id="ogp-blogcard-share-' . $id_url . '" class="ogp-blogcard-share none">
                <a href="javascript:void(0)" class="ogp-blogcard-share-close" tabindex="0" onclick="' . $script . '">×</a>
                <ul>
                    <li><a href="https://twitter.com/share?url=' . $share_url . '&amp;text=' . $title . $tw_acount . '" target="_blank" tabindex="0"><i class="fa fa-twitter" aria-hidden="true"></i></a></li>
                    <li><a href="http://www.facebook.com/share.php?u=' . $share_url . '" target="_blank" tabindex="0"><i class="fa fa-thumbs-up" aria-hidden="true"></i></a></li>
                    <li><a href="http://getpocket.com/edit?url=' . $share_url . '&amp;title=' . $title . '" target="_blank" tabindex="0"><i class="fa fa-get-pocket" aria-hidden="true"></i></a></li>
                    <li><a href="http://b.hatena.ne.jp/add?mode=confirm&url=' . $share_url . '&amp;title=' . $title . '" target="_blank" tabindex="0">B!</a></li>
                </ul>
            </div>
            <div class="ogp-blogcard-main">
                <img class="ogp-blogcard-img" src="' . $img . '">
                <div class="ogp-blogcard-info">
                    <a href="' . $url . '" target="_blank" rel="noopener" tabindex="0" title="' . $title . '">
                        <h2 class="ogp-blogcard-title">' . $title . '</h2>
                        <p class="ogp-blogcard-description">' . $description . '</p>
                    </a>
                </div>
            </div>
            <div class="ogp-blogcard-footer">
                <a href="' . $url . '" target="_blank" rel="noopener" class="ogp-blogcard-site-name" tabindex="0">引用元 : ' . $site_name . '</a>
                <a href="javascript:void(0)" class="ogp-blogcard-share-toggle" tabindex="0" onclick="' . $script . '"><i class="fa fa-share-alt"></i></a>
            </div>
        </div>';
        if(strlen($url) > 20){$transitname = wordwrap($url,20);}else{$transitname = $url;}
        set_site_transient($transitname,$content,12 * WEEK_IN_SECONDS);
    endif;
    return $content;
}
function url_to_OGPBlogcard($atts){
   extract(
       shortcode_atts(
           array('url' => '',),
           $atts
       )
   );
   return make_ogp_blog_card($url);
}
add_shortcode('OGPBlogcard','url_to_OGPBlogcard');
```

こんな感じです。最適化とかの提案があれば、コメントにてお願いします。実際、make_ogp_blogcardにurl引数渡すだけで、動きます。ただ、あらゆる場所で使えるように、簡便に使えるようにと改変した結果です。一部にFontAwesomeを使用しているので、それが嫌な方は、そこを改変してください。主にシェア周りです。

##CSS側の実装

これはあくまでもサンプルです。

```css
.ogp-blogcard {
    display: block;
    height: 37vh;
    width: 80vw;
    padding: 2vmin 5vmin;
    border-radius: 3vmin;
    margin: 3vmin auto;
    position: relative;
    border: 1px solid #e5e5e5;
    background-color: #fff;
    box-shadow: 0 0 3vmin rgba(0, 0, 0, 0.15);
}
.ogp-blogcard-share {
    height: 37vh;
    width: 80%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    background-color: rgba(0, 0, 0, 0.3);
}
.ogp-blogcard-share-close {
    position: absolute;
    top: 1em;
    right: 2em;
    font-size: 3rem;
}
.ogp-blogcard-share > ul { list-style: none; }
.ogp-blogcard-share > ul > li {
    display: inline-block;
    padding: 1em;
    margin: 5vmin;
    border: 1px solid #fff;
    font-size: 2.2rem;
}
.ogp-blogcard-share-close,
.ogp-blogcard-share-close:visited,
.ogp-blogcard-share > ul > li > a,
.ogp-blogcard-share > ul > li > a:visited {
    color: #fff;
}
.ogp-blogcard-main {
    height: calc(37vh * .8);
    width: 80vw;
    position: absolute;
    top: 0;
    margin-bottom: 1vh;
}
.ogp-blogcard-img {
    display: inline-block;
    max-height: calc(37vh * .75);
    max-width: calc(80vw * .4);
}
.ogp-blogcard-info {
    display: inline-block;
    max-width: calc(80vw * .6);
    position: absolute;
    right: 0;
    text-align: center;
}
.ogp-blogcard-title { font-size: 2rem; }
.ogp-blogcard-footer {
    height: calc(37vh * .2);
    width: 80vw;
    position: absolute;
    bottom: 0;
    vertical-align: middle;
}
.ogp-blogcard-share-toggle {
    position: relative;
    right: 0;
    color: #03a9f4;
}
```

こんな感じです。

##まとめ

おおむね、実装としては、

1. URLを引数としたショートコードを記述
2. ショートコードが走らせる関数から処理用の関数に、引数引き渡し
3. 処理用の関数内で、データベース内のキャッシュ検索
4. あったらそれを出力、なかったら作成フェーズへ
5. 作成フェーズ内では、URLをパース用スクリプト内に引き渡し、パース結果を取得
6. パース結果をもとに、HTML作成
7. HTMLをデータベースにキャッシュ
8. HTMLを出力
9. CSSで装飾

こんな感じです。初心者が適当に実装したものなので、参考程度にお願いします。また、これは[2016-by-wkwkrnht](https://github.com/wkwkrnht/2016-by-wkwkrnht/)内のコードをなのでライセンスを守る程度にお願いします。