---
import { Post } from '../../lib/interfaces.ts'
import { getPostByPageId } from '../../lib/notion/client'
import { getPostLink } from '../../lib/blog-helpers.ts'
import '../../styles/notion-color.css'
import arrow from '../../images/icon-arrow-link.svg'
export interface Props {
pageId: string
}
const { pageId } = Astro.props
let post: Post = null
if (pageId) {
post = await getPostByPageId(pageId)
}
---
{
post ? (
<a href={getPostLink(post.Slug)} class="link">
<>
<span class="icon">
{post.Icon && post.Icon.Type === 'emoji' ? (
post.Icon.Emoji
) : post.Icon && post.Icon.Type === 'external' ? (
<img src={post.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{post.Title}</span>
</>
</a>
) : (
<a class="link">
<span class="icon">
🚫
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text not-found">Post not found</span>
</a>
)
}
astro.jsでブログを開発しています。
記事を管理するDBを2つ用意しています。
1つのバージョンはできているところにこれから2つ目も対応しようとしています。
ifの記述の仕方を教えてください
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
post = await getPostByPageId(pageId)
}
次のバージョンで2つ目の記事を管理するために、条件分岐を追加する必要があります。以下は、if
文を使用して2つ目の記事(subPost
)を取得する方法の一例です。
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
if (/* 2つ目の記事の条件 */) {
subPost = await getSubPostByPageId(pageId)
} else {
post = await getPostByPageId(pageId)
}
}
上記のコードでは、最初に pageId
が存在するかどうかをチェックしています。その後、2つ目の記事を取得するための条件を追加しました。条件式の部分は、実際の要件に合わせて記述する必要があります。もし2つ目の記事の条件が /* 2つ目の記事の条件 */
の部分に複雑な条件式として記述される場合は、具体的な要件を教えていただければ、より具体的なコードを提供することができます。
この例では、subPost
と post
の初期値を null
に設定しています。条件分岐の結果、2つ目の記事が取得できれば subPost
に代入され、そうでなければ post
に代入されます。
> 2つ目の記事の条件
という部分が分からないので、もう少し前の部分からお伝えします。
import { Post,SubPost } from '../../lib/interfaces.ts'
import { getPostByPageId,getSubPostByPageId } from '../../lib/notion/client'
import { getPostLink,getSubPostLink } from '../../lib/blog-helpers.ts'
import '../../styles/notion-color.css'
import arrow from '../../images/icon-arrow-link.svg'
export interface Props {
pageId: string
}
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
post = await getPostByPageId(pageId)
}
おっしゃる内容から、getPostByPageId
関数とgetSubPostByPageId
関数を使用して、それぞれ異なる条件で記事を取得する必要があるようですね。
以下は、前提としているモジュールのインポート部分を含むコードです。
import { Post, SubPost } from '../../lib/interfaces.ts'
import { getPostByPageId, getSubPostByPageId } from '../../lib/notion/client'
import { getPostLink, getSubPostLink } from '../../lib/blog-helpers.ts'
import '../../styles/notion-color.css'
import arrow from '../../images/icon-arrow-link.svg'
export interface Props {
pageId: string
}
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
post = await getPostByPageId(pageId)
}
この場合、getPostByPageId
関数とgetSubPostByPageId
関数は、それぞれPost
型とSubPost
型のデータを返すと想定されているようです。記事の取得方法については、それぞれの関数がどのように実装されているかに依存します。
それぞれの関数が異なる条件で記事を取得する場合、以下のようなコードになるかもしれません。
import { Post, SubPost } from '../../lib/interfaces.ts'
import { getPostByPageId, getSubPostByPageId } from '../../lib/notion/client'
import { getPostLink, getSubPostLink } from '../../lib/blog-helpers.ts'
import '../../styles/notion-color.css'
import arrow from '../../images/icon-arrow-link.svg'
export interface Props {
pageId: string
}
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
const isSubPost = /* 2つ目の記事の条件判定 */;
if (isSubPost) {
subPost = await getSubPostByPageId(pageId);
} else {
post = await getPostByPageId(pageId);
}
}
上記のコードでは、isSubPost
という変数を使って、2つ目の記事の条件判定を行っています。isSubPost
がtrue
であればgetSubPostByPageId
関数を呼び出し、subPost
に記事を代入します。それ以外の場合は、getPostByPageId
関数を呼び出し、post
に記事を代入します。
実際の条件判定の方法について、具体的な要件を教えていただければ、より具体的なコードを提供することができます。
const isSubPost = /* 2つ目の記事の条件判定 */;
の部分がわかりません。
記事のDBは2つに分けていてそれに関する関数をsubを付けて拡張しています。
申し訳ありません、理解に誤りがありました。記事のデータベースが2つに分かれており、関数もそれに応じて拡張されているとのことですね。
以下のコードは、記事データベースが2つに分かれており、getPostByPageId
とgetSubPostByPageId
という関数がそれぞれ対応している場合の例です。
import { Post, SubPost } from '../../lib/interfaces.ts'
import { getPostByPageId, getSubPostByPageId } from '../../lib/notion/client'
import { getPostLink, getSubPostLink } from '../../lib/blog-helpers.ts'
import '../../styles/notion-color.css'
import arrow from '../../images/icon-arrow-link.svg'
export interface Props {
pageId: string
}
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
const isSubPost = /* 2つ目の記事の条件判定 */;
if (isSubPost) {
subPost = await getSubPostByPageId(pageId);
} else {
post = await getPostByPageId(pageId);
}
}
上記のコードでは、isSubPost
という変数を使って、2つ目の記事を取得するかどうかを判定します。isSubPost
の条件判定方法については、具体的な要件によって異なるでしょう。以下は、isSubPost
を判定する一般的な例です。
const isSubPost = pageId.startsWith('sub');
上記の例では、pageId
が 'sub'
で始まる場合には2つ目の記事とみなしています。具体的な条件は、実際の要件に合わせて変更してください。
もし具体的な条件判定の要件を教えていただければ、より具体的なコードを提供することができます。
const { pageId } = Astro.props
はどういう内容なのかがわかりません。
すみません、説明が不十分でした。
const { pageId } = Astro.props`は、Astroフレームワークで使用されているプロパティ(`props`)から`pageId`を取り出すためのコードです。Astroでは、ページのプロパティやデータを`props`としてアクセスすることが一般的です。
Astro.propsは、現在のページのプロパティオブジェクトを表しています。その中から
pageId`というプロパティを取り出しています。
例えば、以下のようなAstro.props
の例を考えてみましょう:
{
title: "My Blog Post",
author: "John Doe",
pageId: "12345"
}
この場合、Astro.props
は上記のオブジェクトを表しており、const { pageId } = Astro.props
によってpageId
変数に値"12345"
が代入されます。
このpageId
は、後続のコードで記事のデータベースから記事を取得するために使用されます。
Astro.propsの中身を確認する方法を教えてください
Astro.props
の中身を確認するには、console.log
を使用することができます。以下はその例です。
console.log(Astro.props);
上記のコードを実行すると、コンソールにAstro.props
の内容が表示されます。
また、Astroフレームワークでは、Astroプレビューページの@astro
ディレクティブでdebug
オプションを指定することもできます。これにより、ブラウザの開発者ツールのコンソールにAstro.props
の内容が表示されます。
---
astro: debug
---
上記のように、Astroプレビューページの先頭にastro: debug
というディレクティブを追加することで、デバッグ情報が表示されます。
これらの方法を使用して、Astro.props
の中身を確認することができます。
pageIDでは2つあるDBの判断ができないので、DB IDで判断するようにしたいです。
了解しました。pageId
ではなく、DBのIDを使用して判断する方法に変更する場合は、以下のようなコードになります。
import { Post, SubPost } from '../../lib/interfaces.ts'
import { getPostByPageId, getSubPostByPageId } from '../../lib/notion/client'
import { getPostLink, getSubPostLink } from '../../lib/blog-helpers.ts'
import '../../styles/notion-color.css'
import arrow from '../../images/icon-arrow-link.svg'
export interface Props {
dbId: string // DBのIDを指定するプロパティ
}
const { dbId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (dbId) {
const isSubPost = (dbId === 'サブ記事DBのID'); // サブ記事DBのIDを指定
if (isSubPost) {
subPost = await getSubPostByPageId(pageId);
} else {
post = await getPostByPageId(pageId);
}
}
上記のコードでは、Astro.props
内のdbId
を使用して、サブ記事のDBかどうかを判断しています。具体的なDBのIDは、isSubPost
の条件判定部分で指定する必要があります。もしサブ記事のDBのIDが分かっている場合は、そのIDを指定してください。
また、DBのIDは一意の識別子であるため、他の記事と区別するために使用することができます。該当の記事DBのIDが分かっていれば、そのIDを適切な箇所に指定してください。
保守しやすくしたいので、やっぱり辞めます。
必ずpageIDはgetPostByPageIdかgetSubPostByIdのどちらかに接続でき、もう一方は取得できずエラーになります。
エラーにならない方を変数に登録するように書き換えてください。
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
post = await getPostByPageId(pageId)
}
了解しました。指定された要件に基づいて、エラーが発生しない方の関数結果を変数に代入するようにコードを書き換えます。
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
try {
post = await getPostByPageId(pageId)
} catch (error) {
subPost = await getSubPostByPageId(pageId)
}
}
上記のコードでは、getPostByPageId
関数の呼び出しをtry-catch
ブロックで囲みます。もしgetPostByPageId
関数でエラーが発生した場合(例えば、記事が見つからない場合など)、catch
ブロック内のgetSubPostByPageId
関数を呼び出して、subPost
に結果を代入します。
このように書き換えることで、getPostByPageId
とgetSubPostByPageId
のいずれかが成功することを保証し、エラーが発生しない方の結果が変数に代入されるようになります。
これを使います!!
この場合に、getPostLinkの部分の条件分岐を追加したいです。
post ? (
<a href={getPostLink(post.Slug)} class="link">
<>
<span class="icon">
{post.Icon && post.Icon.Type === 'emoji' ? (
post.Icon.Emoji
) : post.Icon && post.Icon.Type === 'external' ? (
<img src={post.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{post.Title}</span>
</>
</a>
) : (
<a class="link">
<span class="icon">
🚫
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text not-found">Post not found</span>
</a>
)
getPostLink
の部分で条件分岐を追加して、post
が存在する場合と存在しない場合で異なるリンクを生成することができます。以下に修正例を示します。
post ? (
<a href={getPostLink(post.Slug)} class="link">
<>
<span class="icon">
{post.Icon && post.Icon.Type === 'emoji' ? (
post.Icon.Emoji
) : post.Icon && post.Icon.Type === 'external' ? (
<img src={post.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{post.Title}</span>
</>
</a>
) : (
<a class="link">
<span class="icon">
🚫
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text not-found">Post not found</span>
</a>
)
上記のコードでは
postのときはgetPostLinkを使い、subPostの時はgetSubPostLinkを使うようにしてください
了解しました。post
の場合には getPostLink
を使用し、 subPost
の場合には getSubPostLink
を使用するように、条件分岐を修正します。
post ? (
<a href={getPostLink(post.Slug)} class="link">
<>
<span class="icon">
{post.Icon && post.Icon.Type === 'emoji' ? (
post.Icon.Emoji
) : post.Icon && post.Icon.Type === 'external' ? (
<img src={post.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{post.Title}</span>
</>
</a>
) : (
<a href={getSubPostLink(subPost.Slug)} class="link">
<>
<span class="icon">
{subPost.Icon && subPost.Icon.Type === 'emoji' ? (
subPost.Icon.Emoji
) : subPost.Icon && subPost.Icon.Type === 'external' ? (
<img src={subPost.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{subPost.Title}</span>
</>
</a>
)
上記のコードでは、post
の場合には getPostLink(post.Slug)
を使用し、 subPost
の場合には getSubPostLink(subPost.Slug)
を使用しています。それぞれの条件に応じて、適切なリンクを生成するようになりました。
修正後のコードをご確認ください。もし他の条件や修正が必要であれば、具体的な要件をお教えいただければ幸いです。
上記に加えて、postもSubPostも該当しなかった場合に以下のコードを入れてください
<a class="link">
<span class="icon">
🚫
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text not-found">Post not found</span>
</a>
了解しました。post
も subPost
も該当しない場合に、"Post not found" のメッセージを表示するコードを追加します。
修正後のコードは以下のようになります。
{post ? (
<a href={getPostLink(post.Slug)} class="link">
<>
<span class="icon">
{post.Icon && post.Icon.Type === 'emoji' ? (
post.Icon.Emoji
) : post.Icon && post.Icon.Type === 'external' ? (
<img src={post.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{post.Title}</span>
</>
</a>
) : subPost ? (
<a href={getSubPostLink(subPost.Slug)} class="link">
<>
<span class="icon">
{subPost.Icon && subPost.Icon.Type === 'emoji' ? (
subPost.Icon.Emoji
) : subPost.Icon && subPost.Icon.Type === 'external' ? (
<img src={subPost.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{subPost.Title}</span>
</>
</a>
) : (
<a class="link">
<span class="icon">
🚫
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text not-found">Post not found</span>
</a>
)}
上記の修正により、post
や subPost
が存在しない場合に、"Post not found" のメッセージを表示するコードが追加されました。
修正後のコードをご確認ください。ご要望があれば遠慮なくお知らせください。
表示されなかったので原因を考えました。
try catch文のところでエラーになったらsubPostに入れるという流れは、pageID自体がエラーを起こしておらず全てpostに入ってしまっているということに気づきました。
DBが2つあるものの、Astro.propsではその判定ができないので、苦肉の策で、以下のコードに修正しました。
import { Post,SubPost } from '../../lib/interfaces.ts'
import { getPostByPageId,getSubPostByPageId } from '../../lib/notion/client'
import { getPostLink,getSubPostLink } from '../../lib/blog-helpers.ts'
import '../../styles/notion-color.css'
import arrow from '../../images/icon-arrow-link.svg'
export interface Props {
pageId: string
}
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
post = await getPostByPageId(pageId)
subPost = await getSubPostByPageId(pageId)
}
---
{post ? (
<a href={getPostLink(post.Slug)} class="link">
<>
<span class="icon">
{post.Icon && post.Icon.Type === 'emoji' ? (
post.Icon.Emoji
) : post.Icon && post.Icon.Type === 'external' ? (
<img src={post.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{post.Title}</span>
</>
</a>
) : subPost ? (
<a href={getSubPostLink(subPost.Slug)} class="link">
<>
<span class="icon">
{subPost.Icon && subPost.Icon.Type === 'emoji' ? (
subPost.Icon.Emoji
) : subPost.Icon && subPost.Icon.Type === 'external' ? (
<img src={subPost.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{subPost.Title}</span>
</>
</a>
) : (
<a class="link">
<span class="icon">
🚫
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text not-found">Post not found</span>
</a>
)}
開発環境での確認はできていて動いてはいるんですが、postとsubPostに両方入れてしまうのはプログラム的になにか不具合を起こす原因にならないかと不安です。
申し訳ありません、以前の回答で混乱を招いたようです。ご指摘いただき、誤りに気づきました。
post` と `subPost` の両方にデータが入るという問題が発生しないよう、修正を行います。以下の修正済みのコードをご確認ください。
import { Post, SubPost } from '../../lib/interfaces.ts'
import { getPostByPageId, getSubPostByPageId } from '../../lib/notion/client'
import { getPostLink, getSubPostLink } from '../../lib/blog-helpers.ts'
import '../../styles/notion-color.css'
import arrow from '../../images/icon-arrow-link.svg'
export interface Props {
pageId: string
}
const { pageId } = Astro.props
let post: Post = null
let subPost: SubPost = null
if (pageId) {
post = await getPostByPageId(pageId)
if (!post) {
subPost = await getSubPostByPageId(pageId)
}
}
---
{post ? (
<a href={getPostLink(post.Slug)} class="link">
<>
<span class="icon">
{post.Icon && post.Icon.Type === 'emoji' ? (
post.Icon.Emoji
) : post.Icon && post.Icon.Type === 'external' ? (
<img src={post.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{post.Title}</span>
</>
</a>
) : subPost ? (
<a href={getSubPostLink(subPost.Slug)} class="link">
<>
<span class="icon">
{subPost.Icon && subPost.Icon.Type === 'emoji' ? (
subPost.Icon.Emoji
) : subPost.Icon && subPost.Icon.Type === 'external' ? (
<img src={subPost.Icon.Url} class="notion-icon" />
) : (
'📄'
)}
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text">{subPost.Title}</span>
</>
</a>
) : (
<a class="link">
<span class="icon">
🚫
<img src={arrow} class="icon-link" alt="" />
</span>
<span class="text not-found">Post not found</span>
</a>
)}
修正後のコードでは、post
を取得した後に、存在しない場合のみ subPost
を取得するようにしました。つまり、post
が存在する場合には subPost
は取得されません。
これにより、post
と subPost
の両方にデータが入る問題が解決し、適切に記事の取得が行われます。
ご不明な点があればお知らせください。お手数ですが、修正後のコードを再度確認いただけますと幸いです。
できました!!!ありがとう
どういたしまして!お役に立ててうれしいです。問題が解決し、ご満足いただけたようで良かったです。
もし他に質問やお困りごとがありましたら、いつでもお知らせください。お手伝いできることがあります。
Astroを使用して複数のブログDBを管理する方法についての記事で、getPostLinkとgetSubPostLinkを使用して、postとsubPostの両方にデータが入る問題を解決しました。
できたーーーーーー\(^o^)/
https://github.com/herohoro/MakaiZoo_astro-notion-site/pull/42