Posted at

WP REST APIとvue.jsとaxiosを使ってWordPressの記事を取得して一覧を表示する

WordPressの記事一覧を、WordPress外で表示する必要があったのでメモ。


環境


  • WordPress 5.1.1

  • vue.js 2.5.16

  • axios 0.18.0

vue.jsとaxiosはCDNを使用。

WP REST APIは4.7移行から標準で使えるようになったらしい。


ブラウザ


  • Chrome(Win)

  • FireFox(Win)

  • Edge(Win)

  • IE10/11(Win)

  • Chrome(Android)

  • Safari(iOS)

IEが後々足を引っ張ることに( ^ω^)・・・


作業開始


必要なファイルをindex.htmlに呼び出し

CDNでvueとaxiosを読み込み。

今回はindex.jsを作成してそこにvueの記述をするので、それも読み込み。


index.html

<!-- 省略 -->

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="/js/index.js"></script>
</body>


index.jsにWordPerssから記事を取得するコードを作成

記事データを保存するdata.postsを作成。

インスタンス生成後にaxios使ってWordPressの記事取得して、取得したデータをdata.postsに格納。

catch書いとかないと記事が無かった時にコンソールエラーになるのでとりあえず記述。


index.js

var app = new Vue({

el: "#posts",
data: {
posts: []
},
created: function () {
var _this = this;
axios.get("http://[domain]/wp-json/wp/v2/posts/?_embed").then(function(response) { // [domain]にはドメインを指定
response.data.forEach(function (elm) {
var data = {
title: elm.title.rendered,
content: elm.excerpt.rendered,
link: elm.link,
category: elm._embedded["wp:term"],
thumb: elm._embedded["wp:featuredmedia"]
}
_this.posts.push(data);
});
})
.catch(function (error) {
console.log("記事が取得できません。");
})
}
});


取得したデータで記事のリストを表示

v-show="posts.length !== 0"で記事が無い場合はコンテンツを非表示に。

後はv-forでdata.posts内の配列を回して、いい感じに記事一覧を作成。


index.html

<div id="posts">

<div v-show="posts.length !== 0" class="posts">
<div class="posts-wrapper">
<article class="post" v-for="post in posts" :key="post.id">
<p class="post_img">
<span v-if="post.thumb" :style="{'background-image': 'url(' + post.thumb[0].source_url + ')'}" class="thumb">
</span>
<span v-else class="post_img_none">
no-image
</span>
</p>
<div class="post_contents-area">
<div v-if="post.category[0]" class="post_category-list">
<span v-for="category in post.category[0]" :key="category.id" class="post_category">
<a :href="category.link">{{ category.name }}</a>
</span>
</div>
<a :href="post.link" class="post_link">
<h3 class="post_title">{{ post.title }}</h3>
<div class="post_content sp-none" v-html="post.content">
</div>
</a>
</div>
</article>
</div>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="/js/index.js"></script>
</body>


これでいい感じに記事一覧ができましたー(^0^)♪


ところがどっこい

IEで確認したところエラーががが…

そうですよね^^

Promise対応してないですよね^^

ありがとうございます!

IEの為にpolyfill追加して完成!


polyfill.io


It's a service which accepts a request for a set of browser features and returns only the polyfills that are needed by the requesting browser.

これは、一連のブラウザ機能に対する要求を受け入れ、要求しているブラウザに必要なpolyfillのみを返すサービスです。



完成!!


index.js

var app = new Vue({

el: "#posts",
data: {
posts: []
},
created: function () {
var _this = this;
axios.get("http://[domain]/wp-json/wp/v2/posts/?_embed").then(function(response) { // [domain]にはドメインを指定
response.data.forEach(function (elm) {
var data = {
title: elm.title.rendered,
content: elm.excerpt.rendered,
link: elm.link,
category: elm._embedded["wp:term"],
thumb: elm._embedded["wp:featuredmedia"]
}
_this.posts.push(data);
});
})
.catch(function (error) {
console.log("記事が取得できません。");
})
}
});


index.html

<div id="posts">

<div v-show="posts.length !== 0" class="posts">
<div class="posts-wrapper">
<article class="post" v-for="post in posts" :key="post.id">
<p class="post_img">
<span v-if="post.thumb" :style="{'background-image': 'url(' + post.thumb[0].source_url + ')'}" class="thumb">
</span>
<span v-else class="post_img_none">
no-image
</span>
</p>
<div class="post_contents-area">
<div v-if="post.category[0]" class="post_category-list">
<span v-for="category in post.category[0]" :key="category.id" class="post_category">
<a :href="category.link">{{ category.name }}</a>
</span>
</div>
<a :href="post.link" class="post_link">
<h3 class="post_title">{{ post.title }}</h3>
<div class="post_content sp-none" v-html="post.content">
</div>
</a>
</div>
</article>
</div>
</div>
</div>

<script src="https://cdn.polyfill.io/v3/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="/js/index.js"></script>
</body>