これは何か?

CMSの管理画面というのは基本的に無機質なものです。必須項目への入力を忘れれば「入力してください」と素っ気なく怒られ、頑張って記事を書いたとしても誰も褒めてくれません。SNSのメッセージ入力画面などはあれほど背中を押してくれるのに。

これはMovable Type 9に搭載された新しいリッチテキストエディタ(MTRichTextEditor)に、トフが編集を応援してくれる機能を追加して編集中の気持ちを少しでも上げようと試みるMovable Typeプラグインです。

GitHub - usualoma/mt-plugin-TophCheer
Contribute to usualoma/mt-plugin-TophCheer development by creating an account on GitHub.
github.com

追加される機能

  • ステータスバーの領域でトフが跳ねて応援してくれます
  • 行を追加するたびに文字数をカウントして応援してくれます
  • 内容を踏まえてOpenAIのAPIを使ってメッセージを考えて応援してくれます

追加されない機能

  • トフは応援するだけで、記事を書いてはくれません

設定

以下の項目を設定できます。

  • Secret Key
  • モデル
  • システムプロンプト

実装の概要

MTRichTextEditor がインストールされている環境だと、ステータスバーに表示するアイテムのための MTRichTextEditor.Component.StatusbarItemElement をグローバルで参照できます。これは HTMLElementを継承しいているので、これをさらに継承したクラスを定義してカスタム要素として定義することで、ステータスバーに表示するアイテムを追加できます。

AIエージェントに任せたプラグインの作り方

MTRichTextEditor 開発者向けガイドサンプルプラグイン があるので、それをエージェントに伝えてからコーディングを依頼すれば、それだけで割と動くものが出てきます。

この記事について

この記事はMovable Type Advent Calendar 2025の3日目の記事です!

トフについて

トフはシックス・アパートの公式キャラクターです。CC BY-NC-SA 4.0 の下でライセンスされており、オリジナルは シックス・アパートのウェブサイトで入手可能です。

これは何か?

カスタムブロックは非常に拡張性が高いのですが、「入力フォーム兼テンプレートとなるHTMLはブロックエディタで用意する」「挿入するカスタムスクリプトはHTML形式で、style要素やscript要素を混ぜたものになる」というところで、ローカル環境で開発がやややりにくいところがあったので、その問題を解決するべく開発ツールを作ってみました。

以前のものとの違い

カスタムブロックの開発ツールの用意は以前も試みたことがあり、そのときにはVSCodeの拡張機能として「MT Custom Block Editor」というものを作っていました。(記事はここです)これはVSCodeとの連携の試みとしては面白かったのですが、VSCodeに強く結びついてしまうため他のcliツールとの連携が逆に難しくなる面がありました。

そのような折、去年から今年にかけていくつか出したnpmをベースにしたツールが意外と興味をもってもらえたのもあり、こちらのアプローチに変えてみようと思い、以前のVSCode版とは違うものとして作りました。

こんな感じで動きます。

npm create @usualoma/mt-custom-block

このコマンドで雛形を作成できて、動画のサンプルのカスタムブロックも最初から入っています。

.jsonのファイル自体は、ゼロからつくるよりも一回MTで簡単な設定をしてから書き出すほうが楽だと思います。そこをベースにして、このツールでは主に以下のデータを更新できます。

  • アイコン
  • JavaScript または TypeScript
    • .tsというファイル名で保存すると勝手にトランスパイルします
    • script[type=module]で挿入されるので、DOMContentLoadedを明示的に書く必要はありません
  • 入力フォーム兼テンプレートとなるHTML

上の2つはエディタから、一番下はブラウザから更新します。(ブラウザの保存ボタンでちゃんとファイルも更新されます)

デモ動画をみてもらうとなんとなく分かりますが、エディタでTypeScriptを変更して保存するとブラウザの方も自動でリロードされ、TypeScript(カスタムスクリプト)の実行結果をすぐに確認できます。カスタムブロックの作成で一番手間がかかるのがここだと思うので、ここですぐに反映されるのは嬉しいのではないでしょうか。

データとしては本来、カスタムスクリプトにはlink要素やstyle要素を書くこともできるのですが、そのあたりはJavaScriptで動的に対応できるので、このツールでは割り切ってJavaScriptのみで動かすようにしています。

注意事項

ビルドのプロセスを経ることで、意図せずにJavaScriptを大きくなってしまいがちである点には注意が必要です。大きくなるとCMSのシステム側への負荷も大きくなるのでご注意ください。script[type=module]で読み込まれるので、ブラウザ上でのimportも普通に使えるのでnpmのモジュールの読み込みはcdnからの直接の読み込みなどを利用するのがおすすめです。

この記事について

この記事はMovable Type Advent Calendar 2024の25日目の記事です!

今年はMTDDC Meetup TOKYO 2024にも参加ささせていただいて直接いろいろな人と話ができ、そしてこのアドベントカレンダーでいつも通りの年末感も味わうことができました。どちらも主催者であった西山さんをはじめ、関係者のみなさん、ありがとうございました。おつかれさました。

それではみなさん良いお年を!

これは何か?

Movable Typeの管理画面のfaviconを自分の好きな画像に差し替えるプラグインです。画像はウェブブラウザに保存されます。

mt-plugin-ShortcutIcon

対応ウェブブラウザ

  • Google Chrome : 任意の画像を設定できます
  • Firefox : SVGやPNGは設定できますが、JPEGは設定できません
  • Safari : 設定されません

開発の動機

@usualoma/mt-plugin-builderを使って何ができるかをもう少し考えたくて、「ウェブブラウザだけでできること」というテーマで作りました。

仕組み

ユーザーが指定した画像をIndexedDBに保存して、ページ表示の切り替わりごとに読み出してURL.createObjectURLを使ってURLを生成して、link[rel="shortcut icon"] を作成してheadに挿入するという動作をしています。

誰のためのものか?

faviconを設定するだけなら画像のリソースもプラグインに含んでしまえばよく、そうすればユーザー毎に設定せずともインストールしたMT全体で差し替えることができます。

しかしここで、「制作会社のユーザー」と「クライアントのユーザー」で考えると、クライアントのユーザーは複数のサイトのMTを使うわけではないのでMTのデフォルトでよく(むしろそれが自然)、制作会社のユーザーは複数のサイトのMTを使うのでfaviconで「どのサイトのMTか?」を区別できるとよかったりすると思います。そのようなわけで意外と「ユーザーが自分の好きなfaviconを設定できる」という機能にも需要があるのではないかと思っています。

この記事について

この記事はMovable Type Advent Calendar 2024の12日目の記事です!

HonoのJSXでPolyglotなSVGからQuineでイルミネーション

  • 投稿日:
  • by
  • カテゴリ:

こんにちは。OSS珍百景として紹介されたPRの作者の天野です。

今年は以下のあたりを中心にHonoにコミットしました

  • v3.12.0
    • CSRF Protection Middleware
    • css Helper
  • v4.0.0
    • Client Components
  • v4.5.0
    • Combine Middleware
    • React 19 Compatibility

この記事ではこれらの機能の実現に使った内部の機能に触れつつ、PolyglotなSVGを使ってHonoのJSXの表現力を試してみたいと思います。

できたもの

hono-polyglot-svgができました。以下のSVG画像ファイルはそのまま出力するとオリジナルのHonoのアイコン画像が表示されますが、HonoのJSXを経由すると、色を変えつつ自分自身を出力するQuineなSVG画像として出力されます。

  • http://localhost:3000/static/hono.svg : そのまま出力
  • http://localhost:3000/static/hono.svg?eval=1 : JSXで処理して出力

です。以下のような結果になります。

解説

コールバックから書き換える

HonoのJSXの文字列化では、要素の属性値や内容としてPromise<string | String>を返すことができ、useを使うことなしにasyncな関数コンポーネントから簡単に文字列の結果を出力することができます。さらにここでStringに対してisEscapedcallbacksを指定することで、出力される際の挙動をコントロールすることができます。

この特殊なStringを作成するためには、通常は"hono/utils/html"からエクスポートされているraw()を使いますが、使わずに作成することもできます(内部の構造は今後変更される可能性もあるので、推奨はされませんが)。

callbacksに指定した関数が呼び出されるタイミングは、単純な文字列化以外にもrenderToReadableStream()を使ってレスポンスを返す前後のタイミングなど、いくつかあるのですが、ここでは深入りせず単純な文字列化を前提とします。以下のようにしてcallbacksに指定した関数で渡されたbufferの値を変更すると、出力結果を書き換えることができます。

これが今回の、処理するたびにSVG画像の色が変わる挙動の仕組みです。Honoに実装された機能の中では「css Helper」でのstyle要素の埋め込みや、「React 19 Compatibility」でのtitle要素のhoistingで使われています。

(無駄に)Combine Middlewareを使う

「同じパスのURL」でありながら「処理方法(クエリストリングで指定)によって結果が変わる」ということを表現したかったので、Combine Middlewareのsome()を無駄に使って宣言的に書いてみました。以下のように書くと「evalが指定されたときにのみevalSvgMiddlewareを適用する」という挙動になります。

今回の例だと無理矢理感がありますが、hono.devのドキュメントでは認証と組み合わせた実用的な例も紹介されています。

解説は以上になります。

今年の振り返り

さて今年といえばHonoにとってはHono Conference 2024 - Our first stepの開催が一番のイベントだったと思います。(参加レポート書いてなかったですが。)コミッターの方やコメントをしてくれる方の顔を見られて、どんな話し方をするのかを知ることができたのは嬉しかったです。議論が円滑に進むかどうかはまた別の話だとしても、「GitHubのコメントが当人の声で再生できるようになる」というのは、やはりよいものだと思いました。

この記事について

これは Hono Advent Calendar 2024 のシリーズ 1の6日目の記事です。シリーズ 2もあるようなので、引き続きよろしくお願いします!

prettierで整形できて、minifyして書き出せる、MTML

  • 投稿日:
  • by
  • カテゴリ:

こんにちは、天野と申します。Movable Typeの開発に参加しています。

今日はMTML(Movable Type Markup Language)の話です。

MTMLを気持ちよく編集したい

公開される記事の典型的なMTMLは以下のようなものになります。

HTMLの属性の中にMTタグが入っていますが、「カスタム要素の入ったHTML」と思ってみれば特別見にくいものでもないと思います。VSCodeにMTMLの拡張を入れれば、属性の中にも色がついて見やすくなります。

ただMTMLはやはり独自のマークアップ言語で一般的なツールではパースできないので「自動整形ができない」「対応するタグで閉じられているか編集時に検証できない」という問題があります。上のGistの内容だと「</titl>」となっていてHTMLが壊れていますし、「encde_html」となっている箇所もあります。また「<mt:EntryTitle>」というのは「encode_html」を付け忘れていると思われます。

とういところで、「JSXで書ければ整形も検証も一般的なツールでできるのになぁ」というのを思ったのです。

MTMLとJSXの関係については以前もmt-data-api-react としてPoC的なことをやったことがあります。これは「既存のMTMLをそのままで、DataAPIから取得したデータでフロントエンドでレンダリングする」というテーマでした。今回はそれとは異なり「JSXを書いて、それをMTが処理できるMTMLに変換する」というものです。

JSXに馴染みのない方はここまで読んでnot for meだなと感じるかもしれませんが、この話はそうでもないのでもう少し読み進めてください。以下は前出のMTMLを書き換えたものですが、ほぼほぼXMLとして違和感はないだろうと思います。(ないということで話を進めます。)またこれはJSXとしてもValidであり、これを処理することができます。

Reactを書いている方は「JSXとしてもValid」というところで「Validかもしれないけど(TSXでは)型のエラーが出るよね」という話になってくると思いますが、JSXをReactでないJSXの処理系で型を付ければこれもいけます。

説明が長くなってきたので結果を見てみると、今回作ったmt-jsx-templateというコマンドで処理すると以下のような結果になります。

JSXで整形やバリデーションができる上に、つまるところJSXからMTMLへのトランスパイルになるので、その過程でMTMLをminifyして書き出すことができるのです。

実装部分は、honoというOSSのプロジェクトでJSXの処理系を実装したことがあったので、そこから一部をコピーしつつひとまず形にしました。

ちなみにTypeScriptで型も付けられるので、「encoee_html」もちゃんとエラーにできます。またトランスパイルのついでに「<$mt:EntryTitle$>」に自動で(デフォルトで)encode_htmlをつけることもできます。これは、結構いいんじゃないでしょうか。

JSXになればできること

JSXになると、自分でパースの努力をしなくてよくなるので「使われているCSSのクラス名を収集する」ということもやりやすくなります。(今までのテンプレートでも正規表現で収集すれば実用上十分な精度でできたと思いますが。)「JSXで書いてトランスパイルする」という処理が作業フローに組み込まれるのであれば、そのついでに「CSSのフレームワークから必要なCSSを抽出して最小限のCSSを作成する」というのもやろうかという話になってくると思います。

以下が、MasterCSSを使ったサイトのJSXテンプレートからクラス名を抽出して、使われているCSSのみを出力するイメージです。

このMTMLのclassを解析して、MasterCSSを使って以下のCSSを出力することができます。

フロントエンドに関しては、2023年においてはウェブサイトを運用する際には何らかのビルド作業が入っていることが多いと思いますが、MTMLや(MTMLの内容を踏まえた上での)CSSもビルドするようになってもいいのかもしれません。MTのプラグイン(主にPerl)でビルドできればよいようにも思いますが、プラグインだとサーバー上で動作させることになり制限があることも多いので、作業環境の方が自由に環境を作れるというのもあり、これはこれでよいアプローチだと思います。

「ここまでやるならJamstackで生成した方が素直じゃないか?」という指摘があっても否めない気もします。とはいえまあ、上と同じ理由で運用環境は自由にならないこともあるのでMTを使ううえではMTMLの開発効率が上がるのはよいことだと思います。

プレビューもしたい

「JSXでパースできる」ということは、mt:Entriesやmt:EntryTtileのモックを作ってあげれば、JSXを直接文字列化してテンプレートの出力結果も確認できそうです。これになってくると上で出たmt-data-api-reactとも近い話になってくるのですが。これをやるには時間が足りなかったのでやっていませんが、後はモックを頑張って作りさえすれば、プレビューできるというところまで来ていると思います。

今回作成したもの

mt-jsx-templateです。

$ npx mt-jsx-template ファイル名

だけですぐに動かせます。また標準入力からも読み込めますので、動くことだけ確認したい場合には以下のコマンドを実行すれば変換された結果を見ることができます。

$ curl https://gist.githubusercontent.com/usualoma/e3d68e800bd264e9cdb0f2b7b1b19a64/raw/7c0b05a92e95f01f4e317d8c7ab46cb118296b66/entry.mtml.tsx | npx mt-jsx-template

TSXを書いて実際に型の付くことを確認したい場合には以下のようにプロジェクトにインストールして、tsconfig.jsonを設定してもらえば好きなエディタで動作させることができます。

$ npm install --save-dev mt-jsx-template

属性値の型も定義されているので、補完が効いたり、マニュアルを参照できたりします。

これは、結構いいんじゃないでしょうか!

この記事について

この記事は Movable Type Advent Calendar 2023 の25日目の記事です。皆様お疲れさまでした。それでは良いお年を!