Personnalisez le contenu des publications avec vos propres styles

Requirements

:information_source: To be able to use these tips and tricks, you need to be an administrator of either a self-hosted Discourse instance or a Discourse-hosted plan higher than Basic.

Introduction

Discourse supports several methods to format and customize a post’s contents. You can find the list here:

But sometimes, you’ll want something more specific, for example, a link that looks like a button.

Green button

This is the kind of modification we’ll learn here.

The logic

I’ll briefly explain the logic behind but you can go to the next step and jump into a practical example :slight_smile:

Discourse allows any HTML attribute starting with data- in a post’s content.
Those are the attributes we’ll target with CSS to customize our content.

I’ll call them data- attributes in this tutorial :slight_smile:

One way to create elements with these attributes is a BBcode-like tag: [wrap], to which we’ll add a value of our choice. Here we choose “button” (that could be anything else, even the name of your dog :dog:):

[wrap=button]some text[/wrap]

This will output an HTML element having the following attribute: data-wrap="button".

First example: a pink background

Let’s start with a practical example. We’ll create text with a pink background.

As a block element

In your post, on an empty line, write:

[wrap=pink]pink text[/wrap]

It will create a div element having the attribute data-wrap="pink".

Then, add the following CSS to your theme.
Go to Admin panel → Customize → Themes → your theme → Edit CSS/HTML → CSS.

Put the following CSS code inside:

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

Then click the Save button.

Go back to your post, and see the result:

Yes, it is already beautiful :cherry_blossom:

You’ll notice that the background covers the whole post width. Because our wrap is the only element on its line, it outputs a block element.
You can learn more about the difference between blocks and inline HTML elements here: HTML Block and Inline Elements.

If you want your pink background on multiple lines (still as a block), you’ll need both your [wrap] tags having no other content or text on the same line:

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

This will look like this:

As an inline element

Now, let’s add some text before the [wrap], or after, or both :smile:. For example:

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

Here’s the result:

If text or other elements are on the same line as one of your [wrap] tags, it will output an inline element.

Second example: a link with a button’s appearance.

Fiddling with the [wrap] tag can sometimes lead to unwanted results for various reasons, one being that it can be a block or an inline element depending on the context.
So, we’ll describe two different methods that achieve the same result, but you’ll be able to pick the one that suits you the most :v:

An inline button link with [wrap]

The syntax to create a link using markdown is: [some text](https://some-link.etc).
To customize the text and make it appear like a button, we’ll insert the wrap inside the square brackets. Here’s an example:

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

We won’t comment on what this code outputs. You know that because you wrote [wrap=button], you’ll have to target [data-wrap="button"] in your CSS.

So, let’s go, let’s add some fancy CSS to make it pretty! :sparkles:

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

We won’t detail the CSS rules here. There are many CSS resources on the Internet, so if you want to do more specific modifications, you’ll have to learn about it first. :slight_smile:

The result :magic_wand: :

That looks good, right?

An inline button link with regular HTML content

Since Discourse accepts HTML code, we can decide not to use the [wrap] tags and use HTML with a data- attribute. In this example, we’ll use the regular Markdown syntax for the link and surround it with <span> tags.
:information_source: We can’t directly use a link <a> tag because it’s an exception and won’t allow any data- attribute.

Write:

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

It will output a link inside a <span> tag having a data-button attribute, which means the CSS will be a bit more complicated. We will have to target both data-button and the link:

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

And here’s the result!

To go further

A customized list using [wrap]

[wrap] tags and data- attributes can be used in many contexts and you can customize more advanced content. The limit is mostly your CSS knowledge (and HTML to a lesser extent).

I’ll give a single example without explanation by customizing a list in which each element will be prepended with a cat emoji:

Text:

[wrap=cat]

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

CSS:

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

Result:

Using your own theme’s colors variables

If you allow users to use different themes or colors, your modifications may not look good for each one, especially if they have choices between light and dark color schemes.

A good practice is using Discourse’s color variables instead of “hardcoded” colors such as red, #FF0000 or rgb(255,0,0).

Here’s an example in which the button’s background color will use the primary color of the current palette, and the text will use the secondary color:

Text:

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);
}

Here’s how it will look for a user using the Solarized Light color scheme:

And if they use the Solarized Dark color scheme:

Conclusion

You now have the basics to create custom elements using the [wrap] element and the data- attributes.

To make more advanced customizations, learning CSS is primordial. You’ll find many tutorials on the Internet.

The following Discourse’s guide can also be of some help: Making custom CSS changes on your site.
Using the developer’s tools of your Internet Browser will also easily show you the list of your Discourse’s color variables and what each looks like:


:raised_hand_with_fingers_splayed: Feel free to suggest any modification for this guide!


This document is version controlled - suggest changes on github.

21 « J'aime »

Merci @Canapin

Un bon exemple de composant de thème utilisant certains de ces concepts est celui-ci :

4 « J'aime »

Excellent travail !

Je suis curieux de voir quelles autres solutions créatives les utilisateurs proposeront en utilisant l’attribut data.


Y a-t-il un avantage à utiliser <span> data-button</span> HTML par rapport à [wrap="button"] BBCode ?

2 « J'aime »

Sans y avoir trop réfléchi, je dirais que l’utilisation d’un <span> permet de placer un élément en ligne comme seul contenu sur une seule ligne.

L’utilisation d’un [wrap] sur une seule ligne sans autre contenu à côté produira automatiquement un élément de bloc. Le texte à l’intérieur sera également encapsulé avec des balises de paragraphe <p>.

Sinon, c’est probablement une question de goût. Je n’ai pas non plus mentionné qu’un [wrap] et un élément HTML peuvent avoir plusieurs attributs -data car je ne pense pas que ce soit très utile dans la plupart des cas.

3 « J'aime »

Comment ajouter des « cartes » Bootstrap dans vos publications/sujets

…certains pourraient dire que c’est de la folie, trop compliqué ou excessif, mais j’adore ça :smiley:

image

  • Ajout de quelques couleurs pour mieux voir l’imbrication du BBCode.

ARRÊT ! N’utilisez pas mon code

Utilisez plutôt le code amélioré publié par @Canapin CLIQUEZ ICI

BBCode à inclure dans le sujet/la publication

[wrap="card"]
[wrap="card-header"]**En-tête de carte**[/wrap]
[wrap="card-body"]
[wrap="card-title"]**Titre de la carte**[/wrap]
[wrap="card-text"]Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte[/wrap]
[/wrap]
[/wrap]

Code CSS à ajouter au thème.

// Boîte de carte Bootstrap
[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;
}

// En-tête de carte Bootstrap
[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;
    
}

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

// Titre de carte Bootstrap
[data-wrap="card-title"] {
    margin-bottom: 0.5rem;
}

// Texte de carte Bootstrap
[data-wrap="card-text"] {
    margin-top: 0;
    margin-bottom: 1rem;
}
4 « J'aime »

Bien sûr, cela dépend de ce que vous avez l’intention d’y mettre, mais pour obtenir le même visuel exact que votre exemple, vous pouvez beaucoup optimiser votre code :

[wrap="card-header"]**En-tête de carte**[/wrap]
[wrap="card-body"]
**Titre de la carte**

Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte, Texte de la carte
[/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 « J'aime »

Ahhh ! C’est tellement mieux ! Merci beaucoup d’avoir apporté les améliorations ! <3

Génial ! Quand le markdown dans l’élément [wrap]...[/wrap] est-il traité, ou y a-t-il une astuce pour le faire rendre avant qu’il ne soit inclus dans le wrap ?

Par exemple, j’ai essayé de formater du texte dans l’élément en gras ou en italique, et il ne s’affiche pas comme ça - je vois juste _texte_ ou **texte** sur la page dans mon navigateur, une fois que je l’ai sauvegardé :frowning:

1 « J'aime »

Il semble en effet que le formatage (qu’il s’agisse de HTML, Markdown ou BBcode) ne fonctionnera pas dans [wrap] s’il s’agit d’un élément inline (s’il y a d’autres contenus sur la même ligne) :

Vous devrez créer un <span> pour cela.

2 « J'aime »