という悩みに回答していきます。
Content Delivery APIには、Entriesを取得するための検索パラメータとしてlinks_to_entryというパラメータがあります。これを使っていきます。
本サイト『applis』はNext.js+Contentfulで作っていて、記事や単語、本といったコンテンツからタグを参照しています。このタグに紐づいたEntryの数を取得するのに links_to_entry
を使っています。
本サイトの実装を例に説明していきますね。
この記事の内容は、次の各バージョンで動いています。本サイトはTypeScriptで書いているので、コードの例もTypeScriptとなっています。
ライブラリ | バージョン |
---|---|
typescript | 4.1.5 |
contentful.js | 8.1.7 |
links_to_entry
を使えばいいことはわかったけど、そもそも links_to_entry
ってなんだろう?
まず links_to_entry
についてまとめますね。これはContent Delivery APIでEntriesに対する検索パラメータのひとつです。
ドキュメントには次のように書かれています:
あるエントリにリンクするフィールドをもつエントリを検索するには、links_to_entry という検索パラメータを用います。値にはエントリのIDを設定します。
ドキュメントのコード例そのままですが、JavaScriptの場合は次のようにして取得します:
client
.getEntries({
links_to_entry: '<entry_id>',
})
.then((response) => console.log(response.items))
.catch(console.error)
では実装例の方を見ていきますね。本サイトのようにタグがあり、タグを参照する記事、単語、本という3つのContent Modelがあるアプリケーションを想定します。
それぞれ、次のような構造であると仮定します。単語と本は記事とだいたい同じ構造なので省略します:
Content Model | Field Name | Field Type |
---|---|---|
Tag | Name | Short Text |
Slug | Short Text |
Content Model | Field Name | Field Type |
---|---|---|
Post | Title | Short Text |
Slug | Short Text | |
Content | Long Text | |
Tag | Reference |
このときの型定義は次のようになります。タグには自身を参照しているエントリの数を格納する count
も定義しています:
export type Tag = {
name: string
slug: string
count: number
}
export type Post = {
title: string
slug: string
content: string
tag: Entry<Tag>
}
まず、タグの一覧を取得します。パラメータの型は any
にしていますが、実際は許容する検索パラメータの型を指定します:
export async function getTags(params?: any): Promise<Entry<Tag>[]> {
const entries = await client.getEntries<Tag>({
content_type: 'tag',
...params,
})
return entries.items
}
次に、取得したそれぞれのタグへの参照数を取得していきます:
export async function withLinksCountToTag(
tags: Entry<Tag>[]
): Promise<Entry<Tag>[]> {
await Promise.all(
tags.map(async (tag) => {
const entries = await client.getEntries({
links_to_entry: tag.sys.id,
})
tag.fields.count = entries.total
return tag
})
)
return tags
}
参照数はJSONオブジェクトの total
プロパティに格納されているので、これを使います。また、このコード例のように getTags
をラップするようにして使うことで、参照数が必要ないときに getTags
のみを使えるようになります。
この二つの関数を使うと、次のようにしてタグの一覧と、それぞれのタグへの参照数を取得できます:
const tags = await withTagEntriesCount(await getTags())
あるエントリを参照する複数のContent Modelがあるとき、参照されるエントリの参照数を取得するのに links_to_entry
を使うといいです。
特定のContent Modelを対象に参照数を取得するときは、 links_to_entry
ではなくContent Typeを指定する方がよいパフォーマンスを期待できます。
Contentfulで、あるEntryへのLinkの数はどうやって取得すればいいの? いくつかのContent Modelから参照している合計の数を取得したいな。