リンクカード作りました

リンクカード作りました


ブログでよく見るリンクカード(ブログカード)。Wordpress でも搭載されていたり、はてなの奴だったり、PzLinkCard だったり、Embedly だったり、様々ありますが、どうも自分的にしっくり来るものがない。。。

macoblog さんのサイトで紹介されているコードについては、「これいいかも!」と喜び勇んで試してみたところ、内部リンクにしか対応していない。。。

GRANFAIRS さんのサイトで紹介されているブックマークレットのソリューションは、結局のところ HTML タグを生成するソリューションであり、どうも自分の中でしっくりこない。。。

というわけで、自作してしまいました。
といいつつもゼロからコードを書けるほどエンジニア力は高くないので、いろいろなところから情報をいただき、つぎはぎでの構築です。

そしてショートコードで利用するので WordPress 専用です。

ベースの PHP は上述の macoblog さんのコードを利用させていただき、参照情報を Open Graph から持ってくる仕様に変更しました。
PHP で OGP 情報を取得する方法はこちらを参照しました

CSS はなんとなく自作したものですので表示バグがあるかもしれませんが、カスタマイズしてみてください。
※ URL の箇所で Font Awesome を使ってますので適宜こちらもお好みで。

実装

以下のショートコードを記述すると、

[linkcard url="https://avalon-studio.work/blog/azure/azure-storage-https-custom-domain/"]

以下のように表示されます。

内部リンクもフルパスで入力してください。

OGP 情報がある外部のサイトへのリンクはこちらのように表示されます。

OGP 情報がない場合、ショートコードに引数を指定することで、その文言を表示させることもできます。
引数は、url 用の url= 、タイトル用の title= 、そして説明文用の description= の3種を用意しています。

[linkcard url="https://static.avalon-studio.work/about/" title="ダミーサイトへのリンク" description="ここにはショートコードのdescriptionで指定した文言が入ります。"]

ソースコード

PHP のソースコードは以下。チャイルドテーマを作り、チャイルドテーマの functions.php に以下を記載します。

// リンクカード(ショートコード)

function linkcard_code($atts) {
	extract(shortcode_atts(array(
		'url'=>"",
		'title'=>"",
		'description'=>""
	),$atts));

	$html = file_get_contents($url);
	preg_match_all( "<meta property=\"og:([^\"]+)\" content=\"([^\"]+)\">", $html, $ogp );
	for( $i = 0; $i < count($ogp[1]); $i++ ) {
    $result[$ogp[1][$i]] = $ogp[2][$i];
	}
  
  if ($result['title']){
    $title = $result['title'];
  }else{
    $title = $atts['title'];
  }
  
  if ($result['description']){
    $description = $result['description'];
  }else{
    $description = $atts['description'];
  }
  
  if ($result['url']){
    $url = $result['url'];
  }else{
    $url = $atts['url'];
  }

	$image = $result['image'];

	$img_width ="120"; //画像サイズの幅指定
	$img_height = "100"; //画像サイズの高さ指定
	$no_image = '/wp-content/uploads/noimage.jpg'; //アイキャッチ画像がない場合の画像を指定


    if($image) {
        $img_tag = '<img src="' .$image. '" alt="{$title}" width="' .$img_width. '" height="' .$img_height. '" class="linkcard-class" />';
    }else{ 
        $img_tag = '<img src="'.$no_image.'" alt="" width="'.$img_width.'" height="'.$img_height.'" class="linkcard-class" />';
    }


	$linkcard .='
    <div class="linkcard">
      <a href="'. $url .'">
        <div class="linkcard-thumb">'. $img_tag .'</div>
        <div class="linkcard-content">
          <div class="linkcard-title">'. $title .' </div>
          <div class="linkcard-description">'. $description .'</div>
          <div class="linkcard-url"><i class="fa fa-globe" aria-hidden="true"></i>
'. $url .'</div>
        </div>
        <div class="clear"></div>
      </a>
    </div>';

	return $linkcard;
}

add_shortcode("linkcard", "linkcard_code");

// リンクカード 終了

同様に、チャイルドテーマの styles.css には以下を記載します。

.linkcard {
    padding: 15px;
    border-radius: 4px;
    position: relative;
    display: block;
    margin-top: 1em;
    margin-bottom: 1em;
    background: #fff;
    border: 1px solid #0074b4;
}

.linkcard:hover {
  background: #f5fafd;
}

.linkcard-thumb {
  float: left;
	padding-right: 15px;
  width: 120px;
  max-height: 100px;
  box-sizing: content-box;
  overflow: hidden;
}

@media screen and (max-width: 480px){
  .linkcard {
    padding: 12px;
  }
  .linkcard-thumb {
    width: 96px;
    height:auto;
  }
}

.linkcard-title{
  font-size: 120%;
  color: #337ab7;
  text-decoration: none;
  font-weight: 700;
  margin-top:-5px;
}

.linkcard-description{
  margin-top:5px;
  font-size:0.9em;
  color:#444;
  line-height: 1.5em;
}

.linkcard-url{
  margin-top:5px;
  font-size:0.8em;
  color:#03A9F4;
  line-height: 1.1em;
}

.linkcard .clear {
  clear: both;
}

取り急ぎ、当サイト内のリンクもこのショートコードで順次置き換えていく予定です。

何かフィードバックがありましたら、 @_dokuneko までお願いします。