Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

posted at

updated at

baserCMS 4系でアイキャッチ画像も使って、OGPタグをいい感じで出力する

OGPタグの出力は、実の所もっとシンプルでいいような気もするけれど、せっかくbaserCMSにはコンテンツごとのアイキャッチ画像登録機能が備わっているのだから、コンテンツごとに個別のアイキャッチがOGP画像に出力された方が楽しいに決まっている。
と言うわけで、コンテンツ毎に登録されたアイキャッチ画像をog:imageタグに出力する、併せて<head>タグ周りのOGPタグをいい感じで出力するコードをまとめてみました。
おそらく多分に冗長的なコードになっているように思いますが。。。

ポイント

  • コンテンツ毎(固定ページ、ブログ、メールフォームなど)に登録したアイキャッチ画像をog:imageタグに出力する
  • ブログ記事の場合、記事自体にアイキャッチ画像があれば(記事内に画像があれば)優先して表示する
  • Twitter、FacebookのOGPタグは、ほぼ対応。
  • prefix属性記述の出し分け

事前準備

  • コンテンツ毎に表示させたいアイキャッチ画像が登録されていない場合に表示するデフォルト画像を以下のようにアップロードしておく。
    https://○○○.com/theme/利用中のテーマ/img/ogp/web_1200.jpg
  • コンテンツ毎に表示させたいアイキャッチ画像がある場合、事前に管理画面の各コンテンツ>設定>オプションから登録する。 スクリーンショット 2021-10-13 12.40.13.png

今更ですが、登録するアイキャッチ画像は、1200px × 1200pxを推奨します。(retinaディスプレイに対応するため) Twitter、Facebookなどは、画像中央合わせで、1200px × 1200px  →  600px × 600px  →  幅600px × 高さ315px に縮小、トリミングして表示されるため、アイキャッチ画像にテキストなどをレイアウトする場合は、中央の高さ630px(表示上の中央315px範囲)範囲に収まるように配置すれば見切れません。 正方の画像を推奨するのは、特にトリミングされずそのままのアスペクト比で縮小表示されるSNS(LINEのタイムラインなど)もあるからです。

sns.jpg

詳細

利用中のテーマのレイアウトファイルの<head>タグ内に以下の記述を加える(あるいは、差し替え)
レイアウトファイルをコンテンツ毎に分けている場合でも、基本は、すべて同様に記述します。

theme/利用中のテーマ/Layouts/default.php
    //prefix属性を(HOME、固定ページ)はwebsite、ブログ記事の場合はarticleとなるよう条件分岐==========
    <?php if (!empty($post)) { ?>
    <head prefix="og: https://ogp.me/ns# fb: https://ogp.me/ns/fb# article: https://ogp.me/ns/article#">
    <?php } else { ?>
    <head prefix="og: https://ogp.me/ns# fb: https://ogp.me/ns/fb# website: https://ogp.me/ns/website#">
    <?php } ?>

    //基本のタグ出力(ページタイトル、概要、キーワードなど)==========
    <?php $this->BcBaser->charset() ?>
    <?php $this->BcBaser->title() ?>
    <?php $this->BcBaser->metaDescription() ?>
    <?php $this->BcBaser->metaKeywords() ?>

    <?php
    //OGP==========
    //HOME、固定ページの場合
    $siteName = $siteConfig["name"];
    $num = 297; //サイト説明文の文字数制限(本文から297文字抜き出し)
    $str = strip_tags($this->BcBaser->getDescription()); //タグ除去
    $str = str_replace(array("\r\n","\n","\r"), '', $str); //改行除去
    if(mb_strlen($str) >= $num) {
        $description = mb_substr($str, 0,$num-1)."…";
    } else {
        $description = $str;
    }
    $title = $this->BcBaser->getTitle(); //ページタイトル95文字以内
    $type ="website"; //(HOME、固定ページ)はwebsite、ブログ記事の場合はarticle
    $url =$this->BcBaser->getUri($this->BcBaser->getHere());
    $publisher = ""; //Facebookページがある場合、URLあるいはID(FacebookページのFollowボタンを表示できるようになる)
    $eyeCatch = $this->BcUpload->uploadImage('Content.eyecatch',
        $this->request->params['Content']['eyecatch'],
            [
            'imgsize' => '',
            'alt' => '',
            'noimage' => 'theme/利用中のテーマ/img/ogp/web_1200.jpg',
            'output' => 'url',
            'link' => false,
            ]
        ); //固定ページのアイキャッチ画像のURLを出力
    $trim = "?";
    $eyeCatch = $this->BcBaser->getUri(substr($eyeCatch, 0, strcspn($eyeCatch, $trim))); //取得したURLのクエリー文字列(特定文字「?」以降)を除去し、URIで出力

    //ブログ記事の場合(ブログ記事のアイキャッチURIを出力)
    if (!empty($post)) {
        $type ="article"; //ブログ記事なのでarticle
        $title = $this->Blog->getPostTitle($post,false)." – ".$siteConfig["formal_name"]; //ページタイトル95文字以内(サイトタイトルを含めない)
        $baseCurrentID = $this->Blog->getcurrentBlogId(); //アイキャッチ画像の保存先Urlを構成するためにブログ実体IDを取得
        $baseCurrentImgUrl = "/files/blog/" . $baseCurrentID . "/blog_posts/";
        if($this->Blog->getEyeCatch($post)) {
            $eyeCatch = $this->BcBaser->getUri( $baseCurrentImgUrl . $post["BlogPost"]["eye_catch"]);
        } else {
    $eyeCatch = $this->BcUpload->uploadImage('Content.eyecatch',
        $this->request->params['Content']['eyecatch'],
            [
            'imgsize' => '',
            'alt' => '',
            'noimage' => 'theme/利用中のテーマ/img/ogp/web_1200.jpg',
            'output' => 'url',
            'link' => false,
            ]
        ); //ブログ設定のアイキャッチ画像のURLを出力
    $trim = "?";
    $eyeCatch = $this->BcBaser->getUri(substr($eyeCatch, 0, strcspn($eyeCatch, $trim))); //取得したURLのクエリー文字列(特定文字「?」以降)を除去し、URIで出力
        }//ブログ記事にアイキャッチ画像がない場合(ブログ設定のアイキャッチ画像のURIを出力)
    } ?>

    <meta property="article:publisher" content="<?php echo $publisher; ?>">
    <meta property="og:type" content="<?php echo $type; ?>">
    <meta property="og:locale" content="ja_JP">
    <meta property="og:site_name" content="<?php echo $siteName; ?>">
    <meta property="og:title" content="<?php echo $title; ?>">
    <meta property="og:description" content="<?php echo $description; ?>">
    <meta property="og:url" content="<?php echo $url; ?>">
    <meta property="og:image" content="<?php echo $eyeCatch; ?>">
    <meta property="og:image:width" content="1200"><!-- /Retinaを意識して倍解像度 -->
    <meta property="og:image:height" content="630"><!-- /Retinaを意識して倍解像度 -->
    <meta name="twitter:card" content="summary"><!-- /Twitter使ってる場合、見せたいカードの種類 -->
    <meta name="twitter:site" content="@ユーザー名"><!-- /Twitterのユーザー名 -->

    //中略。それぞれのテーマごと必要なタグが入ります(トップスライダー、js、cssの読み込み などなど)==========

    </head>

ブログ記事にアイキャッチ画像がない場合(記事内に画像があれば、そのURIを出力)

こういうパターンもニーズはあるかもしれません。

   //ブログ記事の場合(ブログ記事のアイキャッチURIを出力)
    if (!empty($post)) {
        $type ="article"; //ブログ記事なのでarticle
        $title = $this->Blog->getPostTitle($post,false)." – ".$siteConfig["formal_name"]; //ページタイトル95文字以内(サイトタイトルを含めない)
        $baseCurrentID = $this->Blog->getcurrentBlogId(); //アイキャッチ画像の保存先Urlを構成するためにブログ実体IDを取得
        $baseCurrentImgUrl = "/files/blog/" . $baseCurrentID . "/blog_posts/";
        if($this->Blog->getEyeCatch($post)) {
            $eyeCatch = $this->BcBaser->getUri( $baseCurrentImgUrl . $post["BlogPost"]["eye_catch"]);
        } else if(!empty($this->Blog->getPostImg($post))) {
                //ブログ記事にアイキャッチ画像がない場合(記事内に画像があれば、そのURIを出力)
                //画像のリンクを取得する。
                $imgLink = $this->Blog->getPostImg($post);
                //IMGタグのSRCから画像URLを取り出すための正規表現
                $searchPattern = '/<img.*?src=(["\'])(.+?)\1.*?>/i';
                //正規表現とマッチするパターンを探す
                if(preg_match($searchPattern, $imgLink, $imgurl)){
                    $eyeCatch = $this->BcBaser->getUri($imgurl[2]);
                }
            } else {
                $eyeCatch = $this->BcUpload->uploadImage('Content.eyecatch',
                    $this->request->params['Content']['eyecatch'],
                    [
                        'imgsize' => '',
                        'alt' => '',
                        'noimage' => 'theme/利用中のテーマ/img/ogp/web_1200.jpg',
                        'output' => 'url',
                        'link' => false,
                    ]
                ); //ブログ設定のアイキャッチ画像のURLを出力
                $trim = "?";
                $eyeCatch = $this->BcBaser->getUri(substr($eyeCatch, 0, strcspn($eyeCatch, $trim))); //取得したURLのクエリー文字列(特定文字「?」以降)し、URIで出力
            } //ブログ記事にアイキャッチ画像、記事内の画像、いずれもない場合(ブログ設定のアイキャッチ画像のURIを出力)
        } ?>

本記事は、baserCMSユーザーズフォーラムに投稿した記事を再校正して作成しました。
また、コードのベースは、@mune_noriさんのOmotenashi-2テーマを参考にさせていただきました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?