• 活用ブログTOP
  • 【カスタムブロック】レイアウトを選べるチャット風ブロック
jun jun

【カスタムブロック】レイアウトを選べるチャット風ブロック

トフトフ

チャットみたいに、吹き出し風に会話を表示したいなぁー。
もちろんアイコンを設定できて、左右どっちに置くかも指定したいよねぇー。
難しいプログラムのコードは触らないでできたらいいなぁー。

トフ

任せて!そんなトフトフのために、チャット風画面を作るカスタムブロック作っちゃおう

トフトフ

わーい!
トークとか、インタビューとか、FAQのページが良い感じに表示できるね☆

こんにちは!エンジニアの jun です。
茶番にお付き合い頂きありがとうございます。

というわけでは、チャット風のカスタムブロックをご紹介。
自由に画像を設定可能で、画像の左右レイアウトを任意に指定することが出来きます。
インタビューやFAQなどのコンテンツと相性が良いと思います。

下記のリンクからファイルをダウンロードしインポートすれば、お使いのブログで利用可能です。

トフ

ダウンロードしてね!

カスタムブロック

それでは早速カスタムブロックの詳細を見ていきましょう。

ブロックの作成

まずはブロックの設定から。
今回は「画像」、「画像の配置」、「メッセージ」の3つを設けました。

入力欄 利用するブロック 補足
画像 画像 チャットの画像。正方形推奨。正方形以外は、画像の一部が切り取られる。
画像の配置 ドロップダウン 画像の左右を選択。
メッセージ テキストボックス チャットのメッセージ。

ポイントとしては、ドロップダウンをオプションとして利用している点でしょうか。選択した内容は実際には表示されず、CSSのクラスとして利用しています。

詳細のついては以下をご覧ください。手前味噌で恐縮です。

カスタムスクリプト

続けてカスタムスクリプト。
大まかに3つの工程に分かれます。

  1. ライブラリを読み込む。
  2. テンプレートになるHTMLを記述。テンプレートエンジンに mustache.js を利用。
  3. メインの処理を記述。入力された画像などをテンプレートに受け渡す。
// ライブラリを読み込み
<script src="https://cdn.jsdelivr.net/npm/mustache@4.2.0/mustache.min.js"></script>

// テンプレートになるHTMLを記述
<script type="x-tmpl-mustache" id="chat-item-template">
<div class="chat-item img-position:{{img-position}}">
  <div class="chat-item-head">
    <figure>
      <img src="{{img.src}}" alt="{{img.alt}}" width="100" height="100" loading="lazy">
      <figcaption>{{img.caption}}</figcaption>
    </figure>
  </div>

  <div class="chat-item-body">
    {{{message}}}
  </div>
</div>
</script>

// メインの処理を記述
<script>
document.addEventListener('DOMContentLoaded', async () => {
  if ( document.body.dataset.hasCompiledHtml ) return

  const $img = document.querySelector('.img img')
  const data = {
    img: {
      src: $img.src,
      alt: $img.alt,
      width: $img.width,
      height: $img.height,
      caption: document.querySelector('.img figcaption')?.textContent || '',
    },
    'img-position': '右' === document.querySelector('.img-position')?.textContent ? 'right' : 'left',
    message: document.querySelector('.message')?.innerHTML || '',
  }

  const template = document.querySelector('#chat-item-template').innerHTML
  const rendered = Mustache.render(template, data)

  MTBlockEditorSetCompiledHtml(rendered)
});
</script>

HTML構造とメインの処理を切り分ける目的で、 mustache.js というテンプレートエンジンライブラリを利用しています。
もしHTMLを改変したい場合は、この箇所を編集してください。

また、画像の「代替テキスト」と「キャプション」もそのまま出力しています。
「キャプション」は、チャットの人物名として利用しています。もちろん、空のままでも大丈夫です。

スタイル

最後にスタイルを記述します。

ただ、スタイルに必須の要素はないので、お好きな見栄えに自由に編集してみてください。今回は、あくまで一例として、このようなデザインで作りました。

<style>
.chat-item{
  --bg-body: #dcf7f5;
  --flex-direction: row;

  display: flex;
  gap: 2rem;
  flex-direction: var(--flex-direction, row);
  align-items:flex-start;
}
.chat-item.img-position\:right{
  --flex-direction: row-reverse;
  --bg-body: #f7f7f7;
}
.chat-item + .chat-item{
  margin-top: 1rem;
}
:not(.chat-item) + .chat-item{
  margin-top: 3rem;
}
.chat-item-head{
  flex: 0 0 100px;
}
.chat-item-head figure{
  margin: 0;
}
.chat-item-head figcaption{
  text-align: center
}
.chat-item-head figcaption:empty{
  display: none;
}
.chat-item-head img{
  border-radius: 100%;
  aspect-ratio: 1/1;
  object-fit: cover;
}
.chat-item-body{
  position: relative;
  flex: 1 1 auto;
  padding: 1rem;
  border-radius: 8px;
  background: var(--bg-body, #dcf7f5);
}
.chat-item-body::before{
  content: '';
  position: absolute;
  top: 16px;
  left: -15px;
  width: 0px;
  height: 0px;
  border-top: 15px solid var(--bg-body);
  border-right: 0px none;
  border-left: 15px solid transparent;
}
.chat-item.img-position\:right .chat-item-body::before{
  left: auto;
  right: -15px;
  transform: scaleX(-1);
}
.chat-item-body :first-child{
  margin-top: 0;
}
.chat-item-body :last-child{
  margin-bottom: 0;
}
</style>

なお、サンプルのJSONを読み込んだだけでは、チャットのスタイルが適用されるのは管理画面のみです。
そのため、実際の表示側にもスタイルを適用する必要があります。方法は様々ですが、一例として、上記の <style> タグを丸ごと <head> タグへ記載するとスタイルが利用出来ると思います。

完成!

トフトフ

うれしー。これが欲しかったのー!

トフトフ

さっそく試してみよっ!

トフ

ありがとう!ぜひ活用してね!

トフ

これからもいろんなカスタムブロックを紹介するから、お楽しみに〜!