Настройте содержимое постов с помощью собственных стилей

Требования

:information_source: Чтобы использовать эти советы и приемы, вы должны быть администратором либо самостоятельно размещенного экземпляра Discourse, либо тарифного плана Discourse выше уровня Basic.

Введение

Discourse поддерживает несколько методов форматирования и настройки содержимого поста. Список можно найти здесь:

Однако иногда вам понадобится что-то более специфичное, например, ссылка, выглядящая как кнопка.

Зеленая кнопка

Именно такие изменения мы и изучим здесь.

Логика

Я кратко объясню лежащую в основе логику, но вы можете сразу перейти к следующему шагу и посмотреть практический пример :slight_smile:

Discourse разрешает использование любых HTML-атрибутов, начинающихся с data-, в содержимом поста.
Именно эти атрибуты мы будем нацеливать с помощью CSS для настройки нашего контента.

В этом руководстве я буду называть их атрибутами data- :slight_smile:

Один из способов создания элементов с такими атрибутами — использование тега, похожего на BB-код: [wrap], к которому мы добавим значение по нашему выбору. Здесь мы выбираем «button» (это может быть что угодно, даже имя вашей собаки :dog:):

[wrap=button]какой-то текст[/wrap]

Это создаст HTML-элемент со следующим атрибутом: data-wrap="button".

Первый пример: розовый фон

Давайте начнем с практического примера. Мы создадим текст с розовым фоном.

Как блочный элемент

В вашем посте на пустой строке напишите:

[wrap=pink]розовый текст[/wrap]

Это создаст элемент div с атрибутом data-wrap="pink".

Затем добавьте следующий CSS в вашу тему.
Перейдите в Панель администратора → Настроить → Темы → Ваша тема → Редактировать CSS/HTML → CSS.

Вставьте следующий код CSS внутрь:

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

Затем нажмите кнопку «Сохранить».

Вернитесь к своему посту и посмотрите результат:

Да, это уже красиво :cherry_blossom:

Вы заметите, что фон занимает всю ширину поста. Поскольку наш wrap является единственным элементом на своей строке, он выводит блочный элемент.
Вы можете узнать больше о разнице между блоками и строчными HTML-элементами здесь: HTML Block and Inline Elements.

Если вы хотите, чтобы розовый фон занимал несколько строк (все еще как блок), вам нужно, чтобы оба ваших тега [wrap] не содержали другого контента или текста на одной строке:

[wrap=pink]
розовый текст
розовый текст
розовый текст
розовый текст
[/wrap]

Это будет выглядеть так:

Как строчный элемент

Теперь давайте добавим немного текста перед [wrap], после или и то, и другое :smile:. Например:

Вот какой-то [wrap=pink]розовый текст[/wrap], и это круто ✨

Вот результат:

Если текст или другие элементы находятся на одной строке с одним из ваших тегов [wrap], он выведет строчный элемент.

Второй пример: ссылка с внешностью кнопки.

Работа с тегом [wrap] иногда может приводить к нежелательным результатам по разным причинам, одна из которых — он может быть блочным или строчным элементом в зависимости от контекста.
Поэтому мы опишем два разных метода, которые дают один и тот же результат, но вы сможете выбрать тот, который вам больше подходит :v:

Строчная ссылка-кнопка с помощью [wrap]

Синтаксис для создания ссылки с помощью Markdown: [какой-то текст](https://какая-то-ссылка.и-т-д).
Чтобы настроить текст и сделать его похожим на кнопку, мы вставим wrap внутрь квадратных скобок. Вот пример:

Это [[wrap=button]хорошая ссылка[/wrap]](https://discourse.org/) — синяя кнопка 🐳 !

Мы не будем комментировать, что выводит этот код. Вы знаете, что, поскольку вы написали [wrap=button], вам нужно будет нацелиться на [data-wrap="button"] в вашем CSS.

Итак, давайте добавим немного стильного CSS, чтобы это выглядело красиво! :sparkles:

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

Мы не будем подробно разбирать правила CSS здесь. В интернете много ресурсов по CSS, поэтому, если вы хотите внести более специфичные изменения, вам сначала придется изучить эту тему. :slight_smile:

Результат :magic_wand: :

Выглядит хорошо, верно?

Строчная ссылка-кнопка с обычным HTML-содержимым

Поскольку Discourse принимает HTML-код, мы можем решить не использовать теги [wrap] и использовать HTML с атрибутом data-. В этом примере мы используем обычный синтаксис Markdown для ссылки и окружим его тегами <span>.
:information_source: Мы не можем напрямую использовать тег ссылки <a>, так как это исключение, и он не позволит использовать атрибуты data-.

Напишите:

Это <span data-button>[ссылка](https://discourse.org/)</span> — зеленая кнопка 🐸 !

Это создаст ссылку внутри тега <span> с атрибутом data-button, что означает, что CSS будет немного сложнее. Нам придется нацеливаться и на data-button, и на ссылку:

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

И вот результат!

Для дальнейшего развития

Настроенный список с использованием [wrap]

Теги [wrap] и атрибуты data- можно использовать во многих контекстах, и вы можете настраивать более сложный контент. Ограничение в основном зависит от ваших знаний CSS (и в меньшей степени HTML).

Я приведу один пример без объяснения, настроив список, в котором каждый элемент будет начинаться с эмодзи кошки:

Текст:

[wrap=cat]

- Феликс
- Гарфилд
- Кошка Ната
  [/wrap]

CSS:

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

Результат:

Использование переменных цветов вашей собственной темы

Если вы разрешаете пользователям использовать разные темы или цвета, ваши изменения могут выглядеть плохо для каждого из них, особенно если у них есть выбор между светлой и темной цветовыми схемами.

Хорошей практикой является использование переменных цветов Discourse вместо «закодированных» цветов, таких как red, #FF0000 или rgb(255,0,0).

Вот пример, в котором цвет фона кнопки будет использовать основной цвет текущей палитры, а текст — вторичный цвет:

Текст:

Это [[wrap=button]хорошая ссылка[/wrap]](https://discourse.org/) — кнопка 🌈 !

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 лайка

Отличная работа!

Мне интересно узнать, какие ещё креативные решения придумают пользователи, используя атрибут data.


Есть ли какие-либо преимущества у использования HTML <span data-button> перед BBCode [wrap="button"]?

2 лайка

Не вдаваясь в детали, скажу, что использование тега <span> позволяет размещать строчно-строковый элемент в качестве единственного содержимого на одной строке.

Использование тега [wrap] на одной строке без какого-либо другого содержимого рядом автоматически создаст блочный элемент. Текст внутри также будет обернут в параграфные теги <p>.

Помимо этого, это, вероятно, вопрос вкуса. Я также не упомянул, что и тег [wrap], и HTML-элемент могут иметь несколько атрибутов -data, но, на мой взгляд, это не очень полезно для большинства целей.

3 лайка

Как добавить «Карточки» Bootstrap в ваши темы/сообщения

…кто-то может сказать, что это безумие, слишком сложно или излишне, но мне это нравится :smiley:

  • Добавлены цвета для лучшего визуального отображения вложенности BBCode.

СТОП! Не используйте мой код

Вместо этого используйте улучшенный код, опубликованный @Canapin НАЖМИТЕ СЮДА

BBCode для вставки в тему/сообщение

[wrap="card"]
[wrap="card-header"]**Заголовок карточки**[/wrap]
[wrap="card-body"]
[wrap="card-title"]**Заголовок карточки**[/wrap]
[wrap="card-text"]Текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки, текст карточки[/wrap]
[/wrap]
[/wrap]

CSS-код для добавления в тему.

// Блок карточки 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;
}

// Заголовок карточки 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;
    
}

// Тело карточки Bootstrap
[data-wrap="card-body"] {
    flex: 1 1 auto;
    padding: 1rem 1rem;
}

// Заголовок карточки Bootstrap
[data-wrap="card-title"] {
    margin-bottom: 0.5rem;
}

// Текст карточки Bootstrap
[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 лайков

Ах! Теперь гораздо лучше! Большое спасибо за внесение улучшений! <3

Отлично! Когда обрабатывается markdown внутри элемента [wrap]...[/wrap], или есть какой-то трюк, чтобы он рендерился до включения в wrap?

Например, я пробовал форматировать текст внутри элемента как жирный или курсив, но он не отображается таким образом — я вижу просто _текст_ или **текст** на странице в браузере после сохранения :frowning:

1 лайк

Действительно, похоже, что форматирование (будь то HTML, Markdown или BBCode) не будет работать внутри [wrap], если это строчный элемент (если на той же строке есть другой контент):

Вам нужно создать <span> для этого.

2 лайка