# Встраивание списка тем Discourse на другой сайт

**URL:** https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911
**Category:** Announcements
**Tags:** embedding
**Created:** [15.Август.2019 17:53:02 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911 "2019-08-15T17:53:02Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [15.Август.2019 17:53:02 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/1 "2019-08-15T17:53:02Z")

</div>

Если вы скачаете последние сборки Discourse, вы получите [возможность встраивать списки тем](https://github.com/discourse/discourse/commit/23367e79ea735598766ec6f507f6132e0bad3dba) на других сайтах с помощью простого JavaScript и HTML.

Типичный сценарий использования — блог или другой контент-ориентированный сайт, где вы хотите разместить виджет на боковой панели экрана со списком тем. Вы можете фильтровать по категории, тегу или [любым другим публичным](https://github.com/discourse/discourse/blob/master/lib/topic_query.rb#L51-L73) доступным параметрам фильтрации.

### Как встроить список тем

Сначала необходимо включить настройку сайта `embed topics list`.

Затем в вашем HTML добавьте тег `<script>`, содержащий JavaScript, необходимый для встраивания тем Discourse. Вы можете добавить его туда, где обычно размещаете скрипты. Например:

`<script src="http://URL/javascripts/embed-topics.js"></script>`

Замените `URL` на адрес форума, включая подпапку, если она существует.

После этого в теге `<body>` вашего HTML-документа добавьте тег `d-topics-list`, чтобы указать список тем, который вы хотите встроить. Здесь также нужно заменить `URL` на базовый URL вашего сайта:

`<d-topics-list discourse-url="URL" category="1234" per-page="5"></d-topics-list>`

Любые предоставленные вами атрибуты (кроме обязательного `discourse-url`) будут преобразованы в параметры запроса для поиска тем. Таким образом, если вы хотите искать темы по тегу, вы можете сделать следующее:

`<d-topics-list discourse-url="URL" tags="cool"></d-topics-list>`

Если параметр запроса содержит подчеркивания, замените их дефисами. В приведенном выше примере вы, вероятно, заметили, что `per_page` стало `per-page`.

В контекстах [SameSite](https://web.dev/same-site-same-origin/#same-site-cross-site) (т. е. когда встраиваемый сайт и ваш форум имеют общий родительский домен) Discourse определит, авторизованы ли вы на форуме, и отобразит результаты соответствующим образом. Не удивляйтесь, если вы увидите защищённые категории и тому подобное при входе в систему — анонимные пользователи не смогут этого сделать!

### Список параметров

`template`: `complete` или `basic` (по умолчанию). Пока `basic` представляет собой просто список заголовков тем, `complete` включает заголовок, имя пользователя, аватар пользователя, дату создания и миниатюру темы.

`per-page`: Число. Определяет количество возвращаемых тем.

`category`: Число. Ограничивает темы одной категорией. Передайте `id` целевой категории.

`allow-create`: Булево значение. Если включено, во встроенном виджете появится кнопка «Новая тема».

`tags`: Строка. Ограничивает темы теми, которые связаны с этим тегом.

`top_period`: Одно из значений `all, yearly, quarterly, monthly, weekly, daily`. Если включено, будут возвращены «Лучшие» темы за указанный период.

### Примеры

Я создал пример сайта здесь:

[https://embed.eviltrout.com](https://embed.eviltrout.com)

Вы можете просмотреть исходный код в браузере, чтобы увидеть код, но весь исходный код также доступен на GitHub:

> **[GitHub - eviltrout/embed-topics: Examples for Embedding Discourse Topics](https://github.com/eviltrout/embed-topics)**
>
> Examples for Embedding Discourse Topics

Это совершенно новая функция, поэтому любые отзывы и предложения будут очень полезны.

### Стилизация списка

Вы можете использовать существующую функцию тем для добавления пользовательских стилей для встроенного списка.

Например, по умолчанию наш встроенный список с использованием шаблона `complete` выглядит так:

 ![image](https://global.discourse-cdn.com/meta/original/3X/f/2/f23447c3d22656bdfd71b212985fa114467bb7c3.jpeg)

Если вы хотите, чтобы он выглядел, например, как сетка, вы можете добавить пользовательский SCSS в Раздел \> Общий \> Встроенный CSS:

```scss
.topics-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  
  .topic-list-item { 
    .main-link {
      border: 1px dotted gray;
      padding: 0;
    }
  
    .topic-column-wrapper {
      flex-direction: column-reverse;
      
      .topic-column.details-column {
        width: 100%;
      }
        
      .topic-column.featured-image-column .topic-featured-image img {
        max-width: initial;
        max-height: initial;
        width: 100%;
      }
    }
  }
}

```

Это сделает его похожим на следующее:

 ![image](https://global.discourse-cdn.com/meta/original/3X/b/a/bac5a09bb08436e53769a982dea2be175df98150.jpeg)

---

<div class="post-metadata">

### Author: ![vsoch](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vsoch/32/124967_2.png) [@vsoch](https://meta.discourse.org/u/vsoch)
#### Post date: [04.Август.2020 18:58:24 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/39 "2020-08-04T18:58:24Z")

</div>

Привет, ребята! Мы хотим, чтобы ссылки открывались в новой вкладке (то есть target=“\_blank” вместо target=“\_parent”). Есть ли простой способ сделать это с учетом iframe?

---

<div class="post-metadata">

### Author: ![j127](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j127/32/79093_2.png) [@j127](https://meta.discourse.org/u/j127)
#### Post date: [05.Август.2020 05:29:57 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/40 "2020-08-05T05:29:57Z")

</div>

Не знаю, ищете ли вы именно это, но что-то вроде этого должно сработать для открытия ссылок в новых вкладках. Для внешнего домена необходимо включить CORS. Я попробовал сделать это таким образом, потому что хотел отфильтровать закрепленную тему.

```javascript
// Для `fetch` может потребоваться полифилл
const targetEl = document.getElementById("forumTopics");

function renderTemplate(topicsArr) {
    const items = topicsArr.map(
        (topic) => `<li><a href="${topic[1]}" target="_blank">${topic[0]}</a></li>`
    );

    targetEl.innerHTML = `<ul>${items.join("\n")}</ul>`;
}

// Добавляем `.json` к любому списку тем
fetch("https://forum.example.com/latest.json")
    .then((res) => res.json())
    .then((json) => {
        const topics = json.topic_list.topics
            .slice(1, 6)
            .map((t) => [
                t.title,
                `https://forum.example.com/t/${t.slug}/${t.id}`,
            ]);

        renderTemplate(topics);
    });

```

---

<div class="post-metadata">

### Author: ![vsoch](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vsoch/32/124967_2.png) [@vsoch](https://meta.discourse.org/u/vsoch)
#### Post date: [05.Август.2020 17:37:04 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/41 "2020-08-05T17:37:04Z")

</div>

Спасибо! Мне нравится эта идея, но, исходя из этого поста [What are the risks of enabling Cross-origin resource sharing (DISCOURSE\_ENABLE\_CORS)](https://meta.discourse.org/t/what-are-the-risks-of-enabling-cross-origin-resource-sharing-discourse-enable-cors/41248), я думаю, что включение CORS — не лучшая идея.

---

<div class="post-metadata">

### Author: ![hellekin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/hellekin/32/51636_2.png) [@hellekin](https://meta.discourse.org/u/hellekin)
#### Post date: [05.Август.2020 17:53:13 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/42 "2020-08-05T17:53:13Z")

</div>

Включать CORS следует только для доверенных сайтов. Включение CORS для всех источников сводит его назначение на нет.

---

<div class="post-metadata">

### Author: ![j127](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j127/32/79093_2.png) [@j127](https://meta.discourse.org/u/j127)
#### Post date: [05.Август.2020 21:10:46 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/43 "2020-08-05T21:10:46Z")

</div>

Я включил CORS только для других сайтов, которыми владею. Цель заключалась в том, чтобы загружать список тем форума на наших других сайтах с помощью фронтенд-кода. Этот метод, вероятно, не подойдёт для того, чтобы случайные сайты могли встраивать посты.

**Редактирование:** если вы копируете/вставляете этот код, будьте осторожны с `.slice(1, 6)`, так как это удаляет одну из тем. (Кажется, это была закреплённая тема, которую я хотел убрать.)

---

<div class="post-metadata">

### Author: ![vsoch](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vsoch/32/124967_2.png) [@vsoch](https://meta.discourse.org/u/vsoch)
#### Post date: [05.Август.2020 21:40:31 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/44 "2020-08-05T21:40:31Z")

</div>

Круто, это можно попробовать. У меня сейчас нет сайта, кроме localhost (в период тестирования), поэтому я колебался добавлять его. Но если я найду кого-то, у кого есть подходящее место, мы сможем попробовать. Спасибо за помощь!

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [20.Август.2020 14:09:38 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/45 "2020-08-20T14:09:38Z")

</div>

Привет, @j127

Мы сейчас столкнулись с той же проблемой и хотим открывать ссылки в новой вкладке.  
Всего один быстрый вопрос.

Где именно вы размещаете код, который вы предоставили?

@eviltrout, есть ли у вас идеи, почему в моём случае стили CSS не отображаются?

> **[Pro Emit LED-Pflanzenlampen - Erfahrungen | CannabisAnbauen.net](https://www.cannabisanbauen.net/pro-emit-erfahrungen/)**
>
> Pro Emit gilt als Spitzenhersteller für Pflanzenlampen. Doch kann der Hersteller aus Deutschland sein Versprechen halten? Wir haben nachgehakt, nachgerechnet und verglichen. Wir zeigen hier…

---

<div class="post-metadata">

### Author: ![j127](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j127/32/79093_2.png) [@j127](https://meta.discourse.org/u/j127)
#### Post date: [20.Август.2020 20:01:40 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/46 "2020-08-20T20:01:40Z")

</div>

Этот код — просто краткий пример общей идеи. Я не думаю, что `fetch` [работает во всех браузерах](https://caniuse.com/#feat=fetch). Если хочешь, я могу переписать его на ES5.

Твой сайт — это WordPress или какая-то версия headless WordPress?

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [20.Август.2020 20:12:18 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/47 "2020-08-20T20:12:18Z")

</div>

Похоже, это работает во всех _современных_ браузерах, и Discourse больше не поддерживает IE11.

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [20.Август.2020 22:16:09 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/48 "2020-08-20T22:16:09Z")

</div>

Мой сайт — обычный WordPress, а не headless.

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [21.Август.2020 00:06:21 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/49 "2020-08-21T00:06:21Z")

</div>

Можно ли использовать это для встраивания списка тем Discourse в другой экземпляр Discourse? Или есть более умный способ это сделать?

Мой сценарий использования — создание «моста» между двумя экземплярами в качестве временной меры до их объединения в будущем. Было бы здорово, если бы это можно было автоматизировать и сделать динамическим.

---

<div class="post-metadata">

### Author: ![j127](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j127/32/79093_2.png) [@j127](https://meta.discourse.org/u/j127)
#### Post date: [21.Август.2020 01:21:41 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/50 "2020-08-21T01:21:41Z")

</div>

Если вам не важен IE, то этот фрагмент должен работать. (В настройках Discourse необходимо включить CORS для внешнего домена.)

Для проверки откройте любую страницу этого форума и вставьте приведенный ниже фрагмент в консоль браузера. Я изменил целевой элемент на `document.body`, поэтому он заменит всю страницу списком тем форума. Для реального сайта просто измените целевой элемент на `document.getElementById("#someId")`, а затем добавьте на страницу div с этим ID. Скрипт заполнит его списком тем.

```javascript
// `fetch` может потребовать полифилл, если вам не важен IE
// const targetEl = document.getElementById("forumTopics");

// это заменяет body страницы, просто в качестве примера
const targetEl = document.body;

// вставьте сюда URL вашего форума, чтобы протестировать на собственном форуме
const baseForumURL = `https://meta.discourse.org`;

// количество тем, которые вы хотите отобразить
const numTopics = 6;

function renderTemplate(topicsArr) {
    const items = topicsArr.map(
        (topic) => `<li><a href="${topic[1]}" target="_blank">${topic[0]}</a></li>`
    );

    targetEl.innerHTML = `<ul>${items.join("\n")}</ul>`;
}

// добавьте `.json` к любому списку тем
fetch(`${baseForumURL}/latest.json`)
    .then((res) => res.json())
    .then((json) => {
        const topics = json.topic_list.topics
            .slice(0, numTopics)
            .map((t) => [
                t.title,
                `${baseForumURL}/t/${t.slug}/${t.id}`,
            ]);

        renderTemplate(topics);
    });

```

**Пример:** если целевой div где-то на вашем сайте WP выглядит так

```html
<div id="forumTopics">
    <!-- здесь появятся сообщения форума -->
</div>

```

то JavaScript может обратиться к этому ID следующим образом:

```javascript
// найдите эту строку в исходном примере, который я опубликовал
const targetEl = document.getElementById("forumTopics");

```

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [21.Август.2020 08:04:43 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/51 "2020-08-21T08:04:43Z")

</div>

> [@j127](#):
>
> Если вам не важен IE, то этот фрагмент должен работать. (В настройках Discourse необходимо включить CORS для внешнего домена.)

Вы имеете в виду код из первого поста или фрагмент из поста 50? И нет, мне не важен IE. Нет нужды подстраиваться под этот динозавр :).  
В моём случае CSS не загружается для моего фрагмента ни в одном браузере.

> [@j127](#):
>
> Скрипт заполнит его списком тем.

Значит, это JavaScript, и при реализации в WordPress мне нужно обернуть его в тег `<script>`, верно?

---

<div class="post-metadata">

### Author: ![j127](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j127/32/79093_2.png) [@j127](https://meta.discourse.org/u/j127)
#### Post date: [21.Август.2020 08:52:33 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/52 "2020-08-21T08:52:33Z")

</div>

Прошло уже довольно много времени с тех пор, как я пользовался WordPress. Вы добавляете это в HTML темы? Если да, то оберните мой код в тег `script` и разместите `<div>` там, где вы хотите, чтобы появлялись посты.

Думаю, вы можете просто вставить код ниже в HTML шаблона WordPress в то место, где хотите видеть посты. Обязательно обновите строку с URL форума. Если это не сработает, дайте мне знать. (Код не тестировался.)

> **Нажмите здесь, чтобы получить код**
>
> ```html
> <div id="forumTopics"></div>
> <script>
> // вставьте URL вашего форума здесь для проверки на вашем собственном форуме
> const baseForumURL = `https://forum.example.com`;
> 
> // сколько тем вы хотите показать
> const numTopics = 6;
> 
> const targetEl = document.getElementById("forumTopics");
> // Если посты по какой-то причине не загрузятся, вы можете показать ссылку на форум
> targetEl.innerHTML = `<a class="link-to-discourse" href="${baseForumURL}/">Посмотреть последние посты на форуме</a>`;
> 
> function renderTemplate(topicsArr) {
> const items = topicsArr.map(
> (topic) => `<li><a href="${topic[1]}" target="_blank">${topic[0]}</li>`
> );
> 
> targetEl.innerHTML = `<ul>${items.join("\n")}</ul>`;
> }
> 
> // добавьте `.json` к списку тем
> fetch(`${baseForumURL}/latest.json`)
> .then((res) => res.json())
> .then((json) => {
> const topics = json.topic_list.topics
> .slice(0, numTopics)
> .map((t) => [
> t.title,
> `${baseForumURL}/t/${t.slug}/${t.id}`,
> ]);
> 
> renderTemplate(topics);
> });
> </script>
> 
> ```

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [21.Август.2020 09:10:25 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/53 "2020-08-21T09:10:25Z")

</div>

Спасибо, ценю полный фрагмент кода.

После первоначального теста отображается только ссылка. Но, думаю, CORS отключён, поэтому попрошу хостинг-провайдера его включить.

А пока, как сделать так, чтобы скрипт показывал только посты с определённым тегом и из определённой категории?

---

<div class="post-metadata">

### Author: ![j127](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j127/32/79093_2.png) [@j127](https://meta.discourse.org/u/j127)
#### Post date: [21.Август.2020 19:06:17 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/54 "2020-08-21T19:06:17Z")

</div>

Не уверен, но, кажется, формат такой:  
`https://forum.example.com/tags/c/<catgory_name>/<tag_name>`

**Пример:** категория «support», тег «css»:  
[https://meta.discourse.org/tags/c/support/css](https://meta.discourse.org/tags/c/support/css)

Чтобы получить JSON, добавьте `.json` в конец:  
[https://meta.discourse.org/tags/c/support/css.json](https://meta.discourse.org/tags/c/support/css.json)

Таким образом, в функции `fetch` вместо `/latest.json` используйте что-то вроде `/tags/c/support/css.json`.

(Не проверено.)

---

<div class="post-metadata">

### Author: ![JacobDK](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jacobdk/32/133657_2.png) [@JacobDK](https://meta.discourse.org/u/JacobDK)
#### Post date: [02.Сентябрь.2020 21:34:36 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/55 "2020-09-02T21:34:36Z")

</div>

А что, если я хочу встроить 5 тем прямо в экземпляр Discourse?

Я создаю тему, делаю её вики-страницой и публикую как страницу. Как встроить пять последних тем из конкретной категории или по тегу, либо использовать шаблон, поддерживаемый этой функцией?

Спасибо.

---

<div class="post-metadata">

### Author: ![littleviolette](https://avatars.discourse-cdn.com/v4/letter/l/d26b3c/32.png) [@littleviolette](https://meta.discourse.org/u/littleviolette)
#### Post date: [08.Октябрь.2020 20:45:07 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/57 "2020-10-08T20:45:07Z")

</div>

Какой параметр запроса используется для топ-тем? Я пробовал `order="top"`, но он не возвращает топ-темы так же, как форум, в зависимости от конкретного периода. Как можно воспроизвести результат фильтрации форума? Где можно найти значения атрибутов, которые принимают варианты фильтрации в Discourse? Спасибо!

---

<div class="post-metadata">

### Author: ![littleviolette](https://avatars.discourse-cdn.com/v4/letter/l/d26b3c/32.png) [@littleviolette](https://meta.discourse.org/u/littleviolette)
#### Post date: [08.Октябрь.2020 23:23:56 UTC](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911/58 "2020-10-08T23:23:56Z")

</div>

Можно ли изменить стиль шрифта встроенного содержимого? Я пробовал CSS-селекторы вроде `d-topics-list iframe html .topics-list .topic-list-item`, но безрезультатно. Заранее благодарю за подсказку!

[Следующая страница](https://meta.discourse.org/t/embedding-a-list-of-discourse-topics-in-another-site/125911.md?page=2)
