先日、弊社採用サイトに本ブログのRSSを表示させる機能を追加したのですが、その実装がとてもお手軽だったので共有します。
YQL API Consoleのざっくりトリセツ
昨年から定番として使われてきたgoogleのAPIが廃止になったので、代替としてYQL APIを使います。 RSSの取得、確認にはYQL API Consoleが便利です。 左サイドバーの各リンクをクリックすると、それぞれ対応したサンプルのステートメントが表示されるので、ここではData→RSSをクリック。
select * from rss where url='http://lab.astamuse.co.jp/rss/category/'
'url'の箇所に本ブログのURLをいれてtestすると下記のようなjsonが返ってきます。
{ "query": { "count": 30, "created": "2017-10-18T02:38:53Z", "lang": "en-US", "diagnostics": { "publiclyCallable": "true", "url": { "execution-start-time": "1", "execution-stop-time": "1112", "execution-time": "1111", "content": "http://lab.astamuse.co.jp/rss/category/" }, "user-time": "1130", "service-time": "1111", "build-version": "2.0.187" }, "results": { "item": [ { "title": "データクレンジングとかクォリティチェックとかの話", "link": "http://lab.astamuse.co.jp/entry/2017/10/11/114500", "description": "<p>いつもご覧いただき誠にありがとうございます。", "pubDate": "Wed, 11 Oct 2017 11:45:00 +0900", "guid": { "isPermalink": "false", "content": "hatenablog://entry/8599973812305032728" }, "category": [ "Big Data", "データ開発エンジニア", "データ分析", "データクレンジング", "Data preparation" ], "enclosure": { "length": "0", "type": "image/png", "url": "https://cdn-ak.f.st-hatena.com/images/fotolife/a/astamuse/20171006/20171006150137.png" } } ] } } }
パパっと整形
今回フィードリストで表示させたいのは
- タイトル
- 日付
- 記事へのリンク
- 記事のサムネイル画像
なので 、
select * from rss where url='http://lab.astamuse.co.jp/rss/category/'
こちらのワイルドカードになっている箇所に
title,link,pubDate,enclosure.url
をいれて、さらに、最新の4件だけにしたいので、rss
の箇所をrss(4)
に変更し再度テストすると下記のようなデータが返ってくる。
{ "query": { "count": 4, "created": "2017-10-18T03:17:40Z", "lang": "en-US", "diagnostics": { "publiclyCallable": "true", "url": { "execution-start-time": "1", "execution-stop-time": "995", "execution-time": "994", "content": "http://lab.astamuse.co.jp/rss/category/" }, "user-time": "1010", "service-time": "994", "build-version": "2.0.187" }, "results": { "item": [ { "title": "データクレンジングとかクォリティチェックとかの話", "link": "http://lab.astamuse.co.jp/entry/2017/10/11/114500", "pubDate": "Wed, 11 Oct 2017 11:45:00 +0900", "enclosure": { "url": "https://cdn-ak.f.st-hatena.com/images/fotolife/a/astamuse/20171006/20171006150137.png" } }, { "title": "Spark3分クッキング HBaseで作る100万通りの文書分類器", "link": "http://lab.astamuse.co.jp/entry/2017/10/04/114500", "pubDate": "Wed, 04 Oct 2017 11:45:00 +0900", "enclosure": { "url": "https://cdn-ak.f.st-hatena.com/images/fotolife/a/astamuse/20171004/20171004104538.jpg" } }, { "title": "データドリブンな企業とは何か~アスタミューゼ流宴会術~", "link": "http://lab.astamuse.co.jp/entry/data-driven-company", "pubDate": "Wed, 27 Sep 2017 11:50:00 +0900", "enclosure": { "url": "https://cdn-ak.f.st-hatena.com/images/fotolife/a/astamuse/20170925/20170925115807.png" } }, { "title": "デザインの良し悪しを語るのに必要な「分解」について【書体編】", "link": "http://lab.astamuse.co.jp/entry/2017/09/20/120000", "pubDate": "Wed, 20 Sep 2017 12:00:00 +0900", "enclosure": { "url": "https://cdn-ak.f.st-hatena.com/images/fotolife/a/astamuse/20170920/20170920112706.png" } } ] } } }
これでYQLのほうの準備は完了。URLはページ下にある「THE REST QUERY」の箇所に生成されます。
https://query.yahooapis.com/v1/public/yql?q=select%20title%2C%20pubDate%2C%20link%2C%20enclosure.url%20from%20rss(4)%20where%20%0A%20%20url%3D'http%3A%2F%2Flab.astamuse.co.jp%2Frss%2Fcategory%2F'&format=json&diagnostics=true&callback=
Vue.jsで実装
今回Vueでajaxを扱うためのライブラリはvue-resoueceを使用しています。
採用サイトでは各ページに対応した職種(カテゴリー)のブログ記事を表示させたかったので、カスタムコンポーネントのpropsにカテゴリー名を入れて各カテゴリ一覧ページを読みにいかせるようにしました。
設置例)
<v-gethatena category="webデザイナー"></v-gethatena>
ソース例
templates
<div> <ul> <li v-for="item in items"> <a :href="item.link" target="_blank"> <div class="feed-thumbnail"><img :src="item.enclosure.url"></div> <div class="feed-header"> <span class="feed-date">{{item.pubDate}}</span> <h3 class="feed-title">{{item.title}}</h3> </div> </a> </li> </ul> </div>
js
data() {
return {
items: [],
isLoading: true
};
},
props:{
category : { required: true }
},
created: function(){
let yql = "https://query.yahooapis.com/v1/public/yql?q=select%20title%2Clink%2Cdescription%2CpubDate%2Cenclosure.url%20from%20rss(4)%20where%20url%3D";
let lab = "http://lab.astamuse.co.jp/rss/category/";
let requestURL = yql + "'" + lab + this.category+ "'" + "&format=json&diagnostics=true&callback="
this.$http.get(requestURL).then(response => {
for (var i = 0; i < response.body.query.results.item.length; i++) {
this.items = response.body.query.results.item;
}
}, response => {
// error callback
});
}
これだけでとりあえずRSSフィードは実装完了です! (採用サイトで実装している実際のソースは最後に書いておきます。違いはローディングやデータフォーマットくらいですが。。。)
ホントお手軽にRSSフィード実装できちゃうので、まだ触ったことない人はぜひVue.jsとYQL触ってみてください~ (ただ、YQLはこの前2,3週間ほどサービスダウンしてたので、大事な箇所に利用するのはちょっと怖いw)
Vue.component('v-gethatena', {
template: `
<div>
<div v-if="isLoading">
<slot></slot>
</div>
<div v-else>
<transition-group name="v-gethatena" tag="ul" class="mod-list-feed" appear
@before-enter="beforeEnter"
@after-enter="afterEnter"
@enter-cancelled="afterEnter">
<li v-for="(item, index) in items" :key="index" :data-index="index">
<a :href="item.link" target="_blank">
<div class="feed-thumbnail"><img :src="item.enclosure.url"></div>
<div class="feed-header">
<span class="feed-date">{{item.pubDate}}</span>
<h3 class="feed-title">{{item.title}}</h3>
</div>
</a>
</li>
</transition-group>
</div>
</div>
`,
data() {
return {
items: [],
isLoading: true
};
},
props:{
category : { required: true }
},
created: function(){
let yql = "https://query.yahooapis.com/v1/public/yql?q=select%20title%2Clink%2Cdescription%2CpubDate%2Cenclosure.url%20from%20rss(4)%20where%20url%3D";
let lab = "http://lab.astamuse.co.jp/rss/category/";
let requestURL = yql + "'" + lab + this.category+ "'" + "&format=json&diagnostics=true&callback="
var
this.$http.get(requestURL).then(response => {
for (var i = 0; i < response.body.query.results.item.length; i++) {
this.items = response.body.query.results.item;
this.items[i].pubDate = this.dateFormat(this.items[i].pubDate);
}
setTimeout(function() {
this.isLoading = false;
}.bind(this), 1500);
}, response => {
// error callback
});
},
methods: {
beforeEnter: function(el) {
el.style.transitionDelay = 250 * el.dataset.index + 'ms'
},
afterEnter: function(el) {
el.style.transitionDelay = ''
},
dateFormat: function(str){
var my_date = new Date(str);
var year = my_date.getFullYear();
var month = my_date.getMonth() + 1;
var date = my_date.getDate();
var format_date = year + "/" + month + "/" + date;
return format_date;
};
}
});
new Vue({
el: '#v-root'
});