Astro からヘッドレスCMSとしてWordPressを使う

前回までで、Astroを使ってWebサイトを構築しましたが、ニュース部分についてはWordPressを使いたいと思いました。

WordPressにはREST APIがあらかじめ存在しますので、ちょっと試してみたくなりました。

WordPress側の準備

適当にWordPressをローカルPCにインストールし、投稿を4つほど作成しました。

(公開日が日本時間になっていませんでした。。。)

また、カテゴリー名を表示させたかった為、functions.phpにも必要なコードを追記しています。

WordPressのデフォルトのREST API ではカテゴリーIDしか取得出来ないようです。

add_action( 'rest_api_init', 'registerCategoryName' );
function registerCategoryName() {
    register_rest_field( 'post', 'category_name', array('get_callback' => 'getCategoryName'));
}
function getCategoryName( $object ) {
    $category = get_the_category($object['id']);
    $cat_name = $category[0]->cat_name;
    return $cat_name;
}

これにより、取得した投稿の中に、「category_name」を追加出来ます。

そして、APIで取得できる情報には多数の不要な項目も含まれるため、今回必要な項目のみに絞ります。

add_action('rest_prepare_post', 'remove_post_links', 10, 3);

function remove_post_links($response, $post, $request) {
  
  foreach($response->data as $key => $value) {
	if($key == 'id' || $key == 'category_name' || $key == 'date') {

	} else if($key == 'title' || $key == 'content') {
		$response->data[$key] = $response->data[$key]['rendered'];
	} else {
		unset($response->data[$key]);
	}
  }
  $links = $response->get_links();
  foreach ( $links as $key => $value) {
    $response->remove_link($key);
  }
  
  return $response;
}

これにより、ID, date, title, content, category_name のみ取得するように出来ました。

Astro側の改修

インターフェースをAPIから取得する項目に合わせました。

export interface News {
    id: number;
    date: string;
    title: string;
    content: string;
    category_name: string;
}

ニュースを、WordPressのREST APIから取得するようにしました。


import type {News} from "@/interfaces";

// WordPressから投稿を取得
const res = await fetch("http://test.local/wp-json/wp/v2/posts/");
export const newsList: Array<News> = await res.json();

// idを指定してニュース1件を取得
export function getNews(id: number): News {
    const result: News = newsList.find((news) => news.id == id);
    return result;
}

// 日付文字列の整形
export function getDate(dateString: string): string {
        
    const date = new Date(dateString);
    const yy = date.getFullYear();
    const mm = date.getMonth() + 1;
    const dd = date.getDate();

    return yy + "年" + mm + "月" + dd + "日";
}

// URLを取得
export function getUrl(id: number): string {
    const url = `/news/news-${id}`;
    return url;
}

ニュースの一覧表示を変更しました。

---
import type {News} from "@/interfaces";
import { getDate, getUrl } from "@/newsList";

interface Props {
    news: News;
}

const {news} = Astro.props;
---

<li class="item">
	<span class="date">{getDate(news.date)}</span>
	<span class="category">{news.category_name}</span>
	<span class="newsTitle"><a href={getUrl(news.id)}>{news.title}</a></span>
</li>

<style>
    
	li {
		line-height: 2.5em;
		border-bottom: 1px dashed;
	}
	li span:not(:last-child) {
		margin-right: 20px;
	}
	.category {
	    width: 3em;
	    display: inline-block;
	}
</style>

出来上がり

まとめ

フロントエンドには、モダンなJSフレームワークであるAstroを利用し、コンテンツ管理には利用者の多く使い慣れたWordPressを使うという組み合わせを試してみました。

Astroの部分は他のフレームワークでも良いのですが、スピードが売り、という事で利用しています。

コンテンツ制作という意味では、現状でWordPressが使われなくなる未来はなかなか考えられない為、使い続けるのかなと思っています。

今回は大した変更なく対応出来たのでこの組み合わせは、ありな気がしています。

\ 最新情報をチェック /

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA