3@TECH BLOG

日々の業務で得た知見やノウハウ、技術情報などを発信します。

ブログのフィードを埋め込む (Google Feed APIの代替手段)

ブログのフィードを埋め込む (Google Feed APIの代替手段)

2017-03-03 プログラム / JavaScript / PHP

2016年12月15日、Google Feed APIが猶予期間を終えて、ついにサービスを停止しましたね。 クライアントのサイトで使用していた人も多いのではないでしょうか。 私の周りでも「どうしよう。。。」と困っている人をよく見かけます。 そこで今回は、その代替方法としてJavaScriptとPHPを使ってフィードを取得する方法をサンプルコードと共にご紹介します。

サンプルコードと設置方法

<aside>
    <section>
        <h1>ブログ新着記事</h1>
        <dl id="feed" data-feed-url="https://www.sunatmark.co.jp/blog/tech/feed/" data-feed-count="5">
        </dl>
    </section>
</aside>

<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
<script src="https://code.jquery.com/jquery-migrate-3.0.0.js"></script>
<script src="assets/js/feed.js"></script>

取得したフィードを埋め込む要素とJavaScriptの読み込みです。 埋め込む要素は、今回はdl要素にしています。 data-feed-url属性にフィードのURL、data-feed-countに表示件数を入れてください。 jQueryを使用しますのでjQueryも読み込んでいます。

jQuery(function ($) {
    var $feedElement = $('#feed'),
        feedUrl = $feedElement.data('feedUrl'),
        feedCount = $feedElement.data('feedCount');

    // フィードの取得
    $.ajax('/assets/js/feed.php', {
        type: 'POST',
        dataType: 'json',
        async: true,
        processData: true,
        timeout: 10000,
        data: {url: feedUrl}
    })
    .done(function (data) {
        var html = '';

        // 取得した投稿データごとに繰り返す
        for (var i = 0; i < data.length; i++) {
            var entry = data[i];

            // 投稿日
            var pubDate = new Date(entry.pubDate);

            html += '<dt>' +
                pubDate.getFullYear() + '/' +
                ('0' + (pubDate.getMonth() + 1)).slice(-2) + '/' +
                ('0' + pubDate.getDate()).slice(-2) +
                '</dt>';

            // タイトル、リンク
            html += '<dd><a href="' +
                entry.link +
                '">' +
                entry.title +
                '</a></dd>';

            if (!(--feedCount)) {
                break;
            }
        }

        $feedElement.html(html);
    });
});

7行目

PHPファイルのパスを入れてください。

21~26行目

埋め込むフィードを整形します。 今回はdl要素に埋め込むため、dt要素とdd要素にしています。 必要に応じて変更してください。

取得した値を使用するのに「pubDate」「link」「title」としていますが、これはブログによって異なることがあります。 ほとんどの場合は

タイトルtitle
URLlink
投稿日時pubDate
抜粋もしくは本文description

でいけると思いますが、投稿日時が「date」だったり「published」だったり「issued」だったりします。 本文が「encoded」だったり「content」だったりもします。 うまくいかない場合はこれらを試してみて、それでもダメなら「entry」の中身を見て変更してください。 20行目辺りで

console.log(entry);

とすれば開発者ツールで中身を見ることができます。

<?php

class AjaxFeed
{
    protected $feed = null;

    public function __construct()
    {
        // フィード取得
        $this->feed = $this->getFeed($_POST['url']);
        $result = $this->parseFeed();

        // JSONで返す
        $this->sendJson($result);
    }

    protected function getFeed($url)
    {
        // フィードを取得する
        $res = file_get_contents(
            $url,
            false,
            stream_context_create($this->buildOptions())
        );

        // オブジェクトに変換する
        // CDATAを取得できるようにLIBXML_NOCDATAを指定する
        $feedData = simplexml_load_string(
            $res,
            'SimpleXMLElement',
            LIBXML_NOCDATA
        );

        return $feedData;
    }

    protected function buildOptions()
    {
        $options = array(
            'http' => array(
                'method' => 'GET',
                'header' => implode("\r\n", array(
                    'Content-Type: application/x-www-form-urlencoded'
                ))
            )
        );

        return $options;
    }

    protected function parseFeed()
    {
        $items = $this->getItems();

        // 値を取得
        // 配列として返す
        $entries = array();

        foreach ($items as $item) {
            $entries[] = get_object_vars($item);
        }

        return $entries;
    }

    protected function getItems()
    {
        $name = $this->feed->getName();

        switch ($name) {
            case 'RDF':     // RDF
                $items = $this->feed->item;
                break;

            case 'rss':     // RSS2.0
                $items = $this->feed->channel->item;
                break;

            case 'feed':    // Atom
                $items = $this->feed->entry;
                break;

            default:
                $items = array();
                break;
        }

        return $items;
    }

    protected function sendJson($data = array())
    {
        // JSON形式
        header('Content-Type: application/json; charset=UTF-8');

        // IEがContent-Typeヘッダーを無視して
        // コンテンツの内容を解析するのを防ぐ
        header('X-Content-Type-Options: nosniff');

        // エスケープしてJSONで出力する
        echo json_encode(
            $data,
            JSON_HEX_TAG |
            JSON_HEX_AMP |
            JSON_HEX_APOS |
            JSON_HEX_QUOT
        );

        exit;
    }
}

new AjaxFeed();

通常変更することはありません。 feed.jsの7行目で指定した場所にそのまま置いてください。

デモ

デモページを用意しました。 デモページ

サムネイル画像について

フィードの中にサムネイル画像を入れたいと思う人もいるかと思います。 でも対応しているブログサービスは少ないです。 知っているところでは「はてなブログ」と「Blogger」ぐらいでしょうか。 それも少し癖があり難しいと思いますので、ここでは説明を省きます。

まとめ

以上でほとんどのフィードを取得できます。 見たとおり、JavaScript・PHPともにコード量としては非常に少ないです。 変更が必要なところも少ないですので使ってみてください。

Contact お問い合わせ

お気軽にお問い合わせください。

PageTop