投稿の内容を独自のスタイルでカスタマイズする

要件

:information_source: これらのヒントやテクニックを使用するには、セルフホスト型の Discourse インスタンスの管理者であるか、Discourse が提供するプランのうちBasicより上位のプランを利用している必要があります。

はじめに

Discourse では、投稿の内容をフォーマットしたりカスタマイズしたりするための複数の方法がサポートされています。そのリストはこちらで確認できます:

しかし、時にはより具体的な表現が必要になることもあります。例えば、ボタンのように見えるリンクを作りたい場合などです。

Green button

今回は、このようなカスタマイズ方法を学びます。

ロジック

背後にあるロジックを簡単に説明しますが、すぐに次のステップに進んで実践的な例を学ぶこともできます :slight_smile:

Discourse では、投稿の内容内で data- で始まる任意の HTML 属性を使用できます。
これらの属性を CSS でターゲットにして、コンテンツをカスタマイズします。

このチュートリアルでは、これらを**data- 属性**と呼びます :slight_smile:

これらの属性を持つ要素を作成する一つの方法は、BBcode に似たタグ [wrap] を使用することです。これに任意の値を追加します。ここでは “button” を選択します(他にも何でも、例えばあなたの犬の名前でも構いません :dog:):

[wrap=button]some text[/wrap]

これにより、以下のような属性を持つ HTML 要素が出力されます: data-wrap="button"

最初の例:ピンクの背景

実践的な例から始めましょう。ピンクの背景を持つテキストを作成します。

ブロック 要素として

投稿内の空の行に以下を入力します:

[wrap=pink]pink text[/wrap]

これにより、data-wrap="pink" という属性を持つ div 要素が作成されます。

次に、テーマに以下の CSS を追加します。
管理パネル → カスタマイズ → テーマ → あなたのテーマ → CSS/HTML の編集 → CSS の順に移動してください。

以下の CSS コードを貼り付けます:

[data-wrap="pink"] {
  background: pink;
}

その後、保存ボタンをクリックします。

投稿に戻り、結果を確認してください:

はい、すでに美しいですね :cherry_blossom:

背景が投稿の全幅を覆っていることに気づくでしょう。これは、wrap がその行で唯一の要素であるため、ブロック要素として出力されるからです。
ブロックインラインの HTML 要素の違いについて詳しくは、こちらをご覧ください: https://www.w3schools.com/html/html_blocks.asp。

ピンクの背景を複数の行にわたって表示したい場合(まだブロックとして)、[wrap] タグの両側に同じ行に他のコンテンツやテキストがないようにする必要があります:

[wrap=pink]
pink text
pink text
pink text
pink text
[/wrap]

これは以下のようになります:

インライン 要素として

次に、[wrap] の前後、またはその両方にテキストを追加してみましょう :smile:。例えば:

Here is some [wrap=pink]pink text[/wrap] and it's awesome ✨

結果は以下の通りです:

テキストや他の要素が [wrap] タグと同じ行にある場合、インライン要素として出力されます。

2 番目の例:ボタンのような見た目のリンク

[wrap] タグを操作すると、状況によってはブロック要素にもインライン要素にもなるため、望まない結果になることがあります。
そこで、同じ結果をもたらす 2 つの異なる方法を紹介します。どちらが自分に合うか選んでください :v:

[wrap] を使ったインラインのボタンリンク

Markdown でリンクを作成する構文は [some text](https://some-link.etc) です。
テキストをカスタマイズしてボタンのように見せるには、角括弧の中に wrap を挿入します。例:

This [[wrap=button]nice link[/wrap]](https://discourse.org/) is a blue button 🐳 !

このコードの出力について解説はしません。[wrap=button] を書いたということは、CSS で [data-wrap="button"] をターゲットにする必要があることはご存知でしょう。

では、素敵な CSS を追加して見栄えを良くしましょう!:sparkles:

[data-wrap="button"] {
  display: inline-block;
  padding: 0.5em 1em;
  background: DodgerBlue;
  color: White;
}

CSS ルールの詳細についてはここでは触れません。インターネットには多くの CSS リソースがありますので、より具体的なカスタマイズを行いたい場合は、まず CSS を学ぶ必要があります :slight_smile:

結果 :magic_wand: :

いい感じですね?

通常の HTML コンテンツを使ったインラインのボタンリンク

Discourse は HTML コードを受け入れるため、[wrap] タグを使わずに data- 属性を持つ HTML を使用することもできます。この例では、リンクの標準的な Markdown 構文を使用し、それを <span> タグで囲みます。
:information_source: リンクである <a> タグを直接使用することはできません。これは例外であり、data- 属性を受け付けないためです。

以下を入力します:

This <span data-button>[link](https://discourse.org/)</span> is a green button 🐸 !

これにより、data-button 属性を持つ <span> タグにリンクが出力されます。つまり、CSS は少し複雑になります。data-button とリンクの両方をターゲットにする必要があります:

[data-button] {
  display: inline-block;
  padding: 0.5em 1em;
  background: ForestGreen;
  a {
    color: White;
  }
}

そして、結果はこちらです!

さらに進んで

[wrap] を使ったカスタマイズされたリスト

[wrap] タグと data- 属性は多くのコンテキストで使用でき、より高度なコンテンツのカスタマイズも可能です。制限は主にあなたの CSS の知識(そして HTML の知識)です。

説明なしに、各要素に猫の絵文字を先頭に付けるリストのカスタマイズ例を一つ示します:

テキスト:

[wrap=cat]

- Felix
- Garfield
- Nat's cat
  [/wrap]

CSS:

[data-wrap="cat"] ul {
  list-style: none;
  li:before {
    content: "🐈";
    margin-right: 0.25em;
  }
}

結果:

テーマのカラー変数の使用

ユーザーが異なるテーマや色を選択できるようにしている場合、特に明色と暗色の配色の選択がある場合、カスタマイズがすべてのユーザーにとって見栄えが良くない可能性があります。

良い慣習は、red#FF0000rgb(255,0,0) のような「ハードコードされた」色の代わりに、Discourse のカラー変数を使用することです。

以下の例では、ボタンの背景色に現在のパレットのプライマリカラーを、テキスト色にセカンダリカラーを使用しています:

テキスト:

This [[wrap=button]nice link[/wrap]](https://discourse.org/) is a button 🌈 !

CSS:

[data-wrap="button"] {
  display: inline-block;
  padding: 0.5em 1em;
  background: var(--primary);
  color: var(--secondary);
}

Solarized Light 配色を使用しているユーザーには以下のように表示されます:

Solarized Dark 配色を使用している場合は以下のようになります:

まとめ

これで、[wrap] 要素と data- 属性を使用してカスタム要素を作成する基礎が身につきました。

より高度なカスタマイズを行うには、CSS を学ぶことが不可欠です。インターネットには多くのチュートリアルがあります。

以下の Discourse ガイドも参考になるでしょう: Making custom CSS changes on your site
また、ブラウザの開発者ツールを使用すると、Discourse のカラー変数の一覧とそれぞれの見た目を簡単に確認できます:


:raised_hand_with_fingers_splayed: このガイドに対する修正案を自由に提案してください!


このドキュメントはバージョン管理されています。変更を GitHub で提案してください。

「いいね!」 23

@Canapin 様、ありがとうございます。

これらの概念のいくつかを活用したテーマコンポーネントの良い例は、こちらです。

「いいね!」 4

素晴らしい!\n\nユーザーが data 属性を使ってどのようなクリエイティブなソリューションを生み出すのか、興味があります。\n\n—\n\nHTML の \u003cspan data-button\u003e を使用することに、BBCode の [wrap=\"button\"] を使用することに対する利点はありますか?

「いいね!」 2

あまり深く考えずに言うと、<span>を使用すると、1行にインライン要素のみを配置できます。

1行に他のコンテンツがない状態で[wrap]を使用すると、自動的にブロック要素が出力されます。また、その中のテキストは段落<p>タグで囲まれます。

それ以外は、おそらく好みの問題でしょう。また、[wrap]とHTML要素は複数の-data属性を持つことができることにも触れていませんが、ほとんどの目的にはあまり役立たないと思います。

「いいね!」 3

Bootstrapの「カード」を投稿/トピックに追加する方法

…これはクレイジーだ、複雑すぎる、あるいはやりすぎだと言う人もいるかもしれませんが、私はそれが大好きです :smiley:

image

  • BBCodeのネストをより見やすくするために、いくつかの色を追加しました。

停止! 私のコードを使用しないでください

代わりに、@Canapinが投稿した改善されたコードを使用してください ここをクリック

トピック/投稿に含めるBBCode

[wrap="card"]
[wrap="card-header"]**カードヘッダー**[/wrap]
[wrap="card-body"]
[wrap="card-title"]**カードタイトル**[/wrap]
[wrap="card-text"]カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト[/wrap]
[/wrap]
[/wrap]

テーマに追加するCSSコード。

// Bootstrap Card Box
[data-wrap="card"] {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    word-wrap: break-word;
    background-color: #fff;
    background-clip: border-box;
    border: 1px solid rgba(0,0,0,.125);
    border-radius: 0.25rem;
}

// Bootstrap Card Header
[data-wrap="card-header"] {
    padding: 0.5rem 1rem;
    margin-bottom: 0;
    border-bottom: 1px solid rgba(0,0,0,.125);
    background: #007bff;
    color: #fff;
    border-radius: 5px 5px 0px 0px;
    
}

// Bootstrap Card Body
[data-wrap="card-body"] {
    flex: 1 1 auto;
    padding: 1rem 1rem;
}

// Bootstrap Card Title
[data-wrap="card-title"] {
    margin-bottom: 0.5rem;
}

// Bootstrap Card Text
[data-wrap="card-text"] {
    margin-top: 0;
    margin-bottom: 1rem;
}
「いいね!」 4

もちろん、何を入れるかによりますが、例と同じような見た目を実現するには、コードを大幅に最適化できます。

[wrap="card-header"]**カードヘッダー**[/wrap]
[wrap="card-body"]
**カードタイトル**

カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト、カードテキスト
[/wrap]
[data-wrap="card-header"] {
    padding: 0.5em 1em;
    border: 1px solid rgba(0,0,0,.125);
    border-bottom: 0;
    background: #007bff;
    color: #fff;
    border-radius: 5px 5px 0 0;
}

[data-wrap="card-body"] {
    padding: 1em;    
    border: 1px solid rgba(0,0,0,.125);
    border-radius: 0 0 5px 5px;
}

「いいね!」 5

ああ!ずっと良くなりました!改善してくれて本当にありがとう!:heart:

素晴らしいですね! [wrap]...[/wrap] 要素内のマークダウンはいつ処理されるのでしょうか、それともラップされる前にレンダリングさせるためのコツはありますか?

例えば、要素内で一部のテキストを太字イタリックでフォーマットしようとしましたが、ブラウザで保存したときにページに表示されるのは、単に _text_**text** となり、そのようにはレンダリングされませんでした。 :frowning:

「いいね!」 1

[wrap] 内では、インライン要素(同じ行に他のコンテンツがある場合)の場合、フォーマット(HTML、Markdown、BBcodeのいずれであっても)は機能しないようです。

このためには <span> を作成する必要があります。

「いいね!」 2