Emojiメンションテーマコンポーネント

Mentionの横にカスタムSVGをアイコンとして使用したいと思っていました。これはGuildedでスタッフのMentionに実装されているのを見たことがあり、私も実装したかったのですが、できなかったことです。Discourseを気に入っているもう一つの理由は、開発者が追加してくれるのを待つのではなく、自分で機能させることができることです。

そこで、以下のソリューションを自分で作成しました。決して完璧ではありませんが、アップロードするSVGにはsvgで始まるSCSS変数が必要なようですが、今のところ私には十分機能しています。

もし誰かがこのコードを基にして、より洗練されたものに改良してくれるなら、感謝します!

改善の可能性

  1. すべてのSVGアイコン(Discourseのアイコンと、svgで始まらないアップロードされたアイコン)で動作するようにする。
  2. コードを整理する。
  3. スタイリングを改善する。CSSはとりあえず動作するようにハックしたもので、すべての状況で機能するとは限りません。

それでも、私がEmotional Self-Defenseのために用意したカスタムアイコンをスタッフMentionアイコンとして使用したMentionの例を以下に示します。

image

追加したコードは以下の通りです。

header.html

  // SVGアイコンをオプションとして追加する。アセットに含まれ、アップロードされている限り有効。
  // すべてのアセットのオブジェクトを作成し、どのリンクがデータ絵文字属性とアセット変数名が一致するかを検索して、そのURLを追加する。

  // オブジェクトをキーの配列に変換
  const keys = Object.keys(settings.theme_uploads);

  // すべてのキーを出力
  console.log(keys);

  // オブジェクトを反復処理
  keys.forEach((key, index) => {
      console.log(`${key}: ${settings.theme_uploads[key]}`);
      api.decorateCooked($elem => {
        var url = settings.theme_uploads[key];
        console.log("key: " + key);
        console.log("index: " + index);
        console.log("url: " + url);
        console.log(JSON.stringify(settings.theme_uploads));
        $elem
          .find("a[data-emoji^='" + key + "']")
          .css("--svg-icon", "url('" + url + "')");
        }
      );    
  });

common.scss

@if $show-after-mention == "true" {
  [data-emoji^="svg"]:after {
    content: 'hey ';
    color: transparent;
    height:5px;
    width:15px;
    background: var(--svg-icon) no-repeat center;
    background-size: contain;
    display: inline;
  }
} @else {
  [data-emoji^="svg"]:before {
    content: 'hey ';
    color: transparent;
    height:5px;
    width:15px;
    background: var(--svg-icon) no-repeat center;
    background-size: contain;
    display: inline;
  }
}

これには以下の作業も必要です。

  1. /assetsフォルダを作成する
  2. /assetsフォルダにSVGファイルを配置する(例: /assets/esd-heart.svg)
  3. about.jsonファイルを更新して、以下のようなアセットをリンクする。
"assets": {
  	"svg_esd_heart": "assets/esd-heart.svg"
}
「いいね!」 1