ogImage

Next.js on WordPressを卒業してastro-notion-blogに移行しました。

個人ブログを続けています。

Image in a image block

どうもこんばんは、しゃけごんです。

当ブログ「flap around」は開始からもうすでにn年が経ちましてご愛顧いただきありがとうございます。

内容自体もちょこちょこ変わったりして、今現在は私の愛するオシナモノを並べては「これいいでしょ!?」と息巻くそんなブログになっております。

そもそもブログってもう流行らんじゃんね、動画しないとあかんよね。とは思ってはいて、それ相応の準備や機材などは揃えてはいますがイマイチ一歩踏み出せずにする、そんな状態ではあります。

文言も多いのでほんま動画でやればいいのになぁと思いつつも、Web屋ってこともあってWeb技術に触れながら言いたいことを言うみたいなことが第一にありますので、とりあえず時代遅れではありますが、続けていけたらと思っておるところでございます。

さて、今回また新たな転換期を迎えまして、Next.jsとWordPressを使ったCMSで運用していましたが、この度astro-notion-blogというまた別の記事運営システムに乗り換えた、というそのようなことをこの2024年お盆休みは取り組んでおりました。

なぜ、乗り換えに至ったのか、これを語っていきたいと思います。

ちょっと複雑になってしまった更新周り

Next.jsを導入する前までは、WordPressのみで記事を書いたり更新していたのでシンプルだったのですが、とりあえずNext.jsスルゾー!ってなってできそうなことを調べたらSSGでページを書き出してそれをAWSのCloudFrontにアップしてキャッシュで鬼速や!みたいな事で約半年がかりで作り上げました。

最終的にGitHub ActionsでNext.jsのビルドをしようとしたのですが、あまりにも速度が出なくて1時間たっても終わらないような構成となってしまったので、自宅のMacbook Proにビルド処理は任せることにしました。

そして記事を書くのはNotionで記事を書いたものを、Markdownで書き出し、Pythonを通して画像圧縮をかけてWordPressのAPIを使って画像の登録を行って、WordPressのプラグインを通してS3へと保存しにいくというバケツリレーで行っていたり、記事を整形してこれまたWordPressのAPIを使って記事を登録して、そこからWordPressの投稿画面で改めて整形したり、リンクを張り替えたりとかなり面倒な仕様となっていました。

はじめは「自分の作ったものだし」と思って粛々と記事を書いていたのですが、記事を書く時間と記事を公開するまでの用意の時間が後者の方が遅くなっていったので「何でこんなことしてるんだろうなぁ」とアホらしく感じることとなりました。自分の設計のせいではありますけれど🥺

記事書くのだりーってなってました正直。

雑記サイトの立ち上げ

そしてflap aroundはどちらかというと製品に対して色々深掘りするような記事が多く、「もっと手軽に言いたいことを間違えててもいいからポッと出せるようなブログがあればなぁ」という気持ちになっていた時に、見つけたのがastro-notion-blogでした。

このastro-notion-blogはNotionとcloudFlareを使ってブログを作ろうみたいなもので、AstroというNext.jsに似た新たなフレームワークが台頭してきたもので「これも触ってみたいな」という所で今年の1月くらいから試してみて3月くらいに雑記サイトあつもりを運用しはじめました。

この雑記サイト、さっきから言ってるようにNotionで記事を書くだけ書いて、あとはcloudFlareのデプロイコマンドをPOSTで叩くだけで記事が公開できてしまうという、構築してしまえば本当に楽さこの上ない素晴らしいもので、こちらで雑記を書くことも増えていました。

その頃から、メインブログもこちらに移せないかなぁと思うようになって、このお盆についに実行となったわけです。

データの移行について

Next.jsとWordPressを使っていたデータをどのようにNotionへ移行したかと言うと、ある意味力業でした😅

まず、PyhtonでWP REST APIを叩いて記事を全取得しJSONファイルへ保存しました。

それらの記事に対してリンクURLなどの絶対パスをしてあるものを置換し、WP REST APIで取れるデータはレンダリング後のデータが取れてしまうので、すでにレンダリングされたHTML構造を持ったものでこの構成であればこう変更するだの、正規表現だけでは難しかったので、cheerioなども用いてHTMLの構造についてのアプローチも考えたり、なかなか綺麗なデータにするのに時間を要したこととなりました。

インポート時のnotion-block形式で

先ほど整形したデータはJSONでnotion-blocksの形式に変換しつつ、そのデータを用いてインポートしていくこととなります。

インポート例のPythonコード例は以下の通りです

# Notionデータベースに記事を追加する関数
def create_notion_page(post):
    # スラッグがエンコードされている場合はデコード
    decoded_slug = unquote(post["slug"])

    # 画像の存在をチェック
    featured_image_url = post["featured_image"]
    if not check_image_exists(featured_image_url):
        featured_image_url = ""

    # Notionページのプロパティを構築
    properties = {
        "Page": {"title": [{"text": {"content": post["title"]}}]},
        "Tags": {
            "multi_select": (
                [{"name": tag} for tag in post["categories"]]
                if post["categories"]
                else []
            )
        },
        "Date": {"date": {"start": post["post_date"].split("T")[0]}},
        "Excerpt": {"rich_text": [{"text": {"content": post["excerpt"]}}]},
        "Rank": {"number": post["rank"]},
        "Slug": {"rich_text": [{"text": {"content": decoded_slug}}]},
        "Is_wp_post": {"checkbox": bool(post.get("is_wp_post", 1))},
        "Published": {"checkbox": bool(post.get("published", 0))},
    }

    # 画像がある場合のみ FeaturedImage プロパティを追加
    if featured_image_url:
        properties["FeaturedImage"] = {
            "files": [
                {
                    "name": "Image",
                    "type": "external",
                    "external": {"url": featured_image_url},
                }
            ]
        }

    # Notionページを作成
    response = notion.pages.create(
        parent={"database_id": database_id},
        properties=properties,
    )
    return response


# 子ブロックを分割して追加する関数
def append_children_to_page(page_id, children_blocks):
    for i in range(0, len(children_blocks), 100):
        valid_children = []
        for block in children_blocks[i : i + 100]:
            if block["type"] == "image":
                image_url = block["image"]["external"]["url"]
                if not check_image_exists(image_url):
                    print(f"Replacing invalid image URL: {image_url}")
                    block["image"]["external"][
                        "url"
                    ] = "https://media.musicubicle.com/images/no-image.png"
            valid_children.append(block)

        if valid_children:
            try:
                notion.blocks.children.append(block_id=page_id, children=valid_children)
            except Exception as e:
                print(f"Failed to append blocks: {e}")

Pythonのライブラリにnotion_clientを使用しました。

notion_clientはNotionの記事にデータを追加したり消したり色々できるライブラリですが、またNotionのあのリッチテキストな記事の構造で追加していくので癖になれることが肝心です。

例えば、画像が存在しないと同じ流れで画像のurlの値を空で渡すとcreate時にエラーとなってしまってこの記事は全て登録されないようになってしまうので、画像がない時にはFeturedImageのキーすら入れない事をしなくてはいけなかったり。Postの中に子ブロックとして記事を入れていく際は画像がないとこれも弾かれてこの記事自体の登録がなくなるため、ダミーのno-image画像を入れておかなければならないなど、細かい制約がありました。

ただ一旦通ってしまったらどんどん登録されて、約14年分の地にも涙にもならない記事経ちが半分くらいは読めるかなーという感じで引き継ぐことができました。

記事がNotionに移行してしまえば、もうあとはその仕様に合わせてAstroで合わせていくだけというところになります。

Astroは1つのファイルを用いて点線と改行を用いて上側はJS(サーバサイド)、中盤はレンダリングHTML要素をHTMLでかけて、下側にこの関数内で使用するCSSが書けたりと、Next.jsを知っていればちょっとの違いでAstroは書けるのかなと思いました。

astro-notion-blogの記事検索機能などが面白くて非常にためになって勉強になりました。

アフィリエイトや画像変換ツールも自前で作った

ブロガーで商品紹介をするいろんなツールがありますが、ブラウザでこの商品を共有ボタンを押したらiOSだったりPythonista3、Macなら直接のPythonライブラリを読み出して画像変換を行ってそれをS3にアップして、astro-notion-blogのCodeブロックで特殊な文字の入れ方をするとアフィリエイトのタグがそのまま表示させられるように改造したりしました。

Notionの少しイケてない仕様としては、画像を貼った時に画像の圧縮率やフォーマットが決められない事。これができればダイレクトに画像を入れることができるのですが、今は結構ファイルサイズが大きいままなのでできれば選べたらWebサイトの読み込み速度も考えなくて済むのだけれどもなと考え値ます。

この流れで、画像もiOSのショートカットから画像のサイズやフォーマットを変換させる自分用のAPIサーバを建てたりしてWebPファイルを生成してそのままNotionアプリの指定ブログに書き出すなんてことができるようにも構築しました。

Image in a image block
Mac用にStreamlitで作成したWebP対応の画像変換ツール

iOSがWebPに対応していないため、すべて出先やiPadのネット環境があれば完結させるように持っていきたかったので最高の状態となりましたね!!

ワークフローが下がったからと言って記事が増えるか

さて、ワークフローがだいぶ変わったので、記事が書きやすくなったのは明白ですが、記事がこれからコンスタントに提供できるかは謎です。

雑記サイトでやっていたドラクエウォークの記事なんてのもこちらでも書きやすくなったのでやれたらいいなと思います。

色々とありますが、astro-notion-blogに乗り変えて書きやすいブログライフに憧れていました!やっと出会えた!!さよならWordPressまた会う日まで。

P.S.

キーボードを英字配列で何買おうか悩んでいましたが、CIDOO V75を買いました!

Image in a image block
EPOMAKER CIDOO V75 VIA プログラマブル ゲーミングキーボード メカニカルキーボード 81キー ガスケット 3モード Bluetooth/2.4Ghz/USB-Cワイヤレス 南向きLED ロータリーノブ E-Sport ポロンフォーム付き Mac Win用 (Matte Linear Switch,V75)

EPOMAKER CIDOO V75 VIA プログラマブル ゲーミングキーボード メカニカルキーボード 81キー ガスケット 3モード Bluetooth/2.4Ghz/USB-Cワイヤレス 南向きLED ロータリーノブ E-Sport ポロンフォーム付き Mac Win用 (Matte Linear Switch,V75)

キースイッチを静かなタクタイルに変更したら自分好みのすごい静かで打ち心地がたまらなくなりました。

Kailh Midnight Silent V2 Switch/Tactile メカニカルキーボード用 5ピン 55gf 潤滑済み 静音タクタイルスイッチ (35個)

Kailh Midnight Silent V2 Switch/Tactile メカニカルキーボード用 5ピン 55gf 潤滑済み 静音タクタイルスイッチ (35個)

 

あとは英字配列だけ慣れていきたい!「」や’”などが難しいですね。ある程度は打てるようになってきましたので、記事作成のお供に英字キーボードで楽しみたいと思います🥳

【𝟐𝟎𝟐𝟑新登場】EPOMAKER TH80-X ガスケット ゲーミングキーボード メカニカルキーボード 75%レイアウト 2.4ghz/Bluetooth/USB-C有線 3モード ホットスワップ RGB付き 4000mAhバッテリー LCDスクリーン シリコンパッド NKRO オフィス/Win/Mac用(Flamingo Switch,Green Grey-X)

【𝟐𝟎𝟐𝟑新登場】EPOMAKER TH80-X ガスケット ゲーミングキーボード メカニカルキーボード 75%レイアウト 2.4ghz/Bluetooth/USB-C有線 3モード ホットスワップ RGB付き 4000mAhバッテリー LCDスクリーン シリコンパッド NKRO オフィス/Win/Mac用(Flamingo Switch,Green Grey-X)

これも触ってみたい〜🤗