0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ここのえAdvent Calendar 2023

Day 7

LaravelでWordPressの記事を取得して、Vueで表示する

Last updated at Posted at 2023-12-06

この記事は ここのえ Advent Calendar 2023 Day 7 の記事です。

Wordpressのブログ記事をトップページに乗せたい

Laravel + Vue環境のホームページをメインで置いているのですが、それとは別のところで動いているWordpressへの導線が欲しく、トップページに新着記事を載せてみました。

Wordpressから新着情報を取ること自体は、JSON形式で取得できるため、データ構造さえ分かっていれば必要に応じてデータ取得が可能です。

LPとかに新着情報を載せる……とかそういう需要も多いと思うので、必要に応じて試してみてください。

環境

今回サンプルに使うのはこんな感じの構成です。

  • Laravel 10.x
  • PHP 8.2
  • Vue 3 (Composition API)
  • Typescript

実装

前提の環境を構築済みとします。
また各ライブラリ・フレームワークの解説は省略します。

例として、今回のサイトのWordpressが動作しているアドレスは https://example.com/blog と仮定します。

今回の実装の目的としては、Vue側で

  • 記事タイトル
  • URL
  • 投稿日時
  • サムネイル画像

を表示することを目指します。

バックエンド

LaravelのController

Wordpress REST APIを叩いて、必要なデータを取得します。
エンドポイントは、GET /wp/v2/posts です。

https://example.com/blog/wp-json/wp/v2/posts

加えてper_pageのクエリパラメータを付けることで取得数を制限することができます。
新着記事を表示するだけなら全体を取得する必要もないので、無駄がなくて良いです (デフォルトでper_page=10なので、速度的にはあまり変わらないかも) 。

https://example.com/blog/wp-json/wp/v2/posts?per_page=5

Controllerの実装は以下の通りです。

public function index() {
    // 記事の一覧を取得
    $posts_raw = file_get_contents("https://example.com/blog/wp-json/wp/v2/posts?per_page=5");
    $posts = json_decode($posts_raw, true);

    // Viewに返すデータをまとめたArray
    $recent = [];

    foreach ($posts as $post) {
        // サムネイル画像の情報を取得
        $thumb_raw = file_get_contents($post["_links"]["wp:featuredmedia"][0]["href"]);
        $thumb_data = json_decode($thumb_raw, true);

        // 必要な情報を配列にまとめる
        $recent[] = [
            "title" => $post["title"]["rendered"],
            "url" => $post["link"],
            "date" => $post["date"],
            "thumbnail" => $thumb_data["guid"]["rendered"]
        ];
    }

    return view("index", ["recent" => $recent]);
}

サムネイルのみ、GET /wp/v2/postsで返ってくるJSONでは取得することができません。
JSON内の_links -> wp:featuredmedia[0] -> hrefのリンクに GET /wp/v2/media のエンドポイントへのリンクが入っているので、サムネイル画像の情報を取得するために file_get_contents を再度回しています。

APIの詳細については、公式のHandbookを参照してください。

フロントエンド

Blade

Controllerで取得したデータがBladeに飛んで来たら、Vueに渡します。
@jsディレクティブを使って、Vueのpropsとして飛ばします。

<div id="app">
    <index-page :recent="@js($recent)" />
</div>

Vue (Typescript, Composition API)

propsを適宜storeに保存したり、使いやすいように取り扱ってください。サンプルでは最小構成にしています。
Typescriptで記述しているため型定義が多めですが、jsの場合は適宜読み替えてください。
dateがstringになってしまうため、JSのDate型に変換したほうが取り扱い易いです。

<!-- IndexPage.vue -->

<script setup lang="ts">

// 記事のinterface
interface Post {
  title: string
  url: string
  date: Date
  thumbnail: string
}

// propsの定義
const props = defineProps<{
  recent: {
    title: string
    url: string
    date: string
    thumbnail: string
  }[]
}>()

// 記事の一覧を保持したref
const posts: ref<Post[]> = ref([])

// propsからの変換処理
onBeforeMount(() => {
  for(const p of props.recent) {
    posts.value.push({
      title: p.title,
      url: p.url,
      date: new Date(p.date),
      thumbnail: p.thumbnail,
    })
  }
})

// 日付をyyyy/mm/dd形式に変更
const getDateString = (date: Date): string => {
  return date.toLocaleDateString('ja-JP', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  })
}

</script>

<template>
  <a v-for="post of posts" :key="post.url" :href="post.url">
    <img :src="post.thumbnail" :alt="post.title" />
    <p>{{ post.title }}</p>
    <p>{{ getDateString(post.date) }}</p>
  </a>
</template>

まとめ

PHPの方である程度整形してあげれば、フロント側で取り扱うのは容易です。
Wordpressで取得できるのは記事情報に限らないので、アイデア次第で色々できそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?