プロフィール

arismmn timeline blog

← ブログ一覧に戻る

管理画面にMarkdownインポート機能を追加した

機能実装UI/UXAstro

概要

ブログ記事とWiki用語の新規作成画面に、YAMLフロントマター付きMarkdownをそのまま貼り付けて各フィールドに一括反映できるインポート機能を追加した。

これまでは、GeminiなどのAIが生成したMarkdownをもとに記事を登録するとき、タイトル・スラグ・カテゴリ・本文を個別に手入力する必要があった。今回の機能で、AIが出力したMarkdownをそのままコピペするだけで登録できるようになった。

image


実装した機能

タブ切り替えUI

フォーム上部に「通常入力」と「Markdownインポート」の2つのタブを追加した。

  • 通常入力: 従来どおりの個別フィールド入力
  • Markdownインポート: テキストエリアにMarkdownを貼り付け、「フィールドに反映して通常入力へ」ボタンを押すと各フィールドが自動で埋まる

反映後は自動的に通常入力タブに切り替わり、内容を確認してから登録できる。

対応するYAMLキー

ブログ記事

キー 反映先 補足
title タイトル 必須
slug スラグ(URL) 必須
description 概要 任意
categories カテゴリ カンマ区切り文字列
post_date 公開日時 YYYY-MM-DDTHH:mm 形式
draft 下書き true でチェックON

Wiki用語(ブログ記事の項目に加えて)

キー 反映先 補足
related 関連用語スラグ カンマ区切り
level 難易度 beginner / intermediate / advanced
no_autolink 自動リンク無効 true でチェックON

入力フォーマット例

---
title: SSR(サーバーサイドレンダリング)
slug: ssr
description: サーバーでHTMLを生成する手法
categories: フロントエンド, Astro
draft: true
---

## 概要

SSRとは、リクエストのたびにサーバー側でHTMLを生成してクライアントに返す方式のことをいう...

実装の設計

フロントマターパーサー

外部ライブラリは使わず、正規表現ベースのシンプルなパーサーを実装した。

function parseFrontmatter(text) {
  const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
  if (!match) return { fields: {}, body: text };
  // ...各行をkey: value形式で解析する
}

処理の流れは次のとおり。

  1. --- で囲まれたブロックを正規表現で抽出する
  2. 各行を キー: 値 の形式で解析する
  3. 値を囲むクォート(" または ')を除去する
  4. フロントマター以降のテキストを本文として返す

YAMLのネスト構造やリスト型は対象外とし、単純な key: value のみを解析対象にした。これにより実装をシンプルに保ちつつ、AIが出力する一般的なフロントマット形式をほぼカバーできる。

サーバーサイドへの変更ゼロ

この機能はすべてクライアントサイドのJavaScriptで完結している。既存のフォーム送信ロジックには一切手を加えていないため、バリデーションやデータ保存の処理はそのまま再利用できる。

タブ切り替えも display: none / display: block の切り替えのみで、フォームのname属性やDOMの構造は変更していない。


課題と今後の検討点

  • 著者(Author)フィールドはドロップダウン選択式のため、YAMLからの自動反映は対象外にした。登録後に手動で選択する
  • YAMLのリスト形式(- item)には未対応。カンマ区切り文字列のみサポート
  • フロントマターに認識されないキーが含まれていても無視するだけで、エラーにはならない
Claude Code
Powered by
Claude Code
(使用モデル Sonnet 4.6)
← ブログ一覧に戻る