Contentfulの小技

 javascript contentful

※Javascript SDK を例に挙げているので、自分の環境に合わせて適宜読み替えてください。

id ではなく slug で取得する

contentful で単一のエントリーを取得するときに ID を使うとおもいますが、そのIDが r1nuKtGooIVlVGyhoOjbK3 みたいなあまりイケてない文字列になっています。もしWebページでこのIDをそのままURLに使おうとすると、以下のようになります。

https://example.com/posts/r1nuKtGooIVlVGyhoOjbK3

URLで何の投稿だがわかららないですよね。でもこのURLが以下のようになってたらイケてませんか。

https://example.com/posts/awesome-post

このようなURLでエントリーを取得できるようにします。

まずは対象となるContent model(今回は post)にフィールドを追加します。(ここでは slug とします。)

URL部分に使いたいので、フィールドのバリデーションに以下を設定します。

  • Required Field (必須項目)
  • Unique Field (content model内で同じ値を使用できなくする)
  • Match a specific pattern (正規表現による入力規則)
    • 英数字とハイフンを許可したい場合は以下のような正規表現を指定します。
      • ^[-A-Za-z0-9]*$

chrome 2020-03-05 05-57-52

そしてこの slug を利用して投稿を取得したい場合は以下のようにします。

const response = await client.getEntries({
  content_type: 'post',
  'fields.slug': 'awesome-post',
  limit: 1
})

if (response.total === 0) {
  throw new Error('投稿が見つかりません')
}

const post = response.items[0]

タグをつける

エントリーに対して、タグをつけ、特定のタグで検索できるようにしたいという要件があるとします。

ContentfulにはReferences Fieldが存在し、あるContent modelから別のContent modelへ参照を貼ることができます。この参照は一つのフィールドで複数持つこともできるのでこれを利用します。

まずはタグを管理する tag Content modelをつくります。フィールドはタグの名前を保持する name だけ入れておきます。nameは Unique Fieldにしておくと良いでしょう

次にタグを付ける対象の Content model (例えば post) に References Fieldを追加します。名前は tags にしておきます。タグを複数つけたい場合は Many References を選択してください。

chrome 2020-03-05 05-56-33

それに対して以下のバリデーションをつけておきます。

  • Accept only specified entry type (特定の種類のエントリーのみ許可する)
    • tag にチェックをいれる

chrome 2020-03-05 05-57-11

これで準備は完了です。エントリーを作る時に新規のタグを作ったり既存のタグを追加したりできます。

特定のタグのエントリーを取得したい場合はソースコードは以下のようになります。

// タグ情報の取得
const tagResponse = await client.getEntries({
  content_type: 'tag',
  'fields.name': '<タグ名>',
  limit: 1
})

if (tagResponse.total === 0) {
  throw new Error('タグが存在しません。')
}

const tag = tagResponse.items[0]

// タグより取得
const postsResponse = await client.getEntries({
  content_type: 'post',
  'fields.tags.sys.id': tag.sys.id,
)

'fields.tags.sys.id': tag.sys.id が関連付けされているタグのうち、指定されたタグのIDのものを取得するという意味になります。

全文検索

エントリーの全文検索がAPIで実装されています。

const response = await client.getEntries({
  content_type: '<content_type>',
  query: 'cat', // 検索したい文字列
})

Published at 2020-03-04 21:05