Добавьте собственный контент, который отображается только на вашей главной странице

Очень часто в роли разработчика тем вы столкнетесь с необходимостью создавать контент, который отображается только на главной странице вашего сообщества.

Вы можете добавить HTML в раздел «После заголовка» вашей темы, и он будет отображаться на каждой странице. Можно пойти на хитрости с CSS, чтобы скрыть этот контент везде, кроме главной страницы… но вместо этого давайте используем тему Discourse для создания компонента с контентом, видимым только на вашей главной странице.

Если вы не знакомы с темами Discourse, ознакомьтесь с этими материалами: Beginner's guide to using Discourse Themes и Structure of themes and theme components

В вашей теме Discourse необходимо настроить следующую структуру каталогов:

:file_folder: javascripts/discourse/components/
:file_folder: javascripts/discourse/connectors/

Далее мы создадим компонент Ember. Подробнее о компонентах Ember можно узнать в их документации: Ember.js Guides - Guides and Tutorials - Ember Guides

Но пока это будет простой компонент, написанный в виде одного файла .gjs, содержащего как логику, так и шаблон.

:page_facing_up: javascripts/discourse/components/custom-homepage-content.gjs

import Component from "@glimmer/component";
import { service } from "@ember/service";
import { defaultHomepage } from "discourse/lib/utilities";

export default class CustomHomepageContent extends Component {
  @service router;

  get isHomepage() {
    const { currentRouteName } = this.router;
    return currentRouteName === `discovery.${defaultHomepage()}`;
  }

  <template>
    {{#if this.isHomepage}}
      <h1>Это мой HTML-контент главной страницы</h1>
    {{/if}}
  </template>
}

Это создает геттер isHomepage, который проверяет сервис роутера на наличие currentRouteName. Если имя маршрута совпадает с именем вашей главной страницы (как задано в настройках сайта), он вернет true. Шаблон внутри <template>...</template> проверяет этот геттер и отображает ваш контент только тогда, когда значение true. Между блоками {{#if}} вы можете добавить любой HTML, какой захотите.

Теперь, когда компонент создан, нам нужно добавить его в Discourse. На этом этапе вам нужно решить, какой выход плагина (plugin outlet) использовать. Это области в Discourse, куда мы добавили небольшой код для разработчиков, чтобы они могли подключаться к системе. Вы можете поискать эти выходы на GitHub или просмотреть их на странице (deprecated) Plugin outlet locations theme component.

Для пользовательских главных страниц часто выбирают above-main-container, поэтому давайте используем его.

Нам нужно создать файл коннектора в правильном каталоге:

:page_facing_up: javascripts/discourse/connectors/above-main-container/custom-homepage-connector.gjs

import CustomHomepageContent from "../../components/custom-homepage-content";

<template><CustomHomepageContent /></template>

:point_up: И всё! Достаточно одной строки с вызовом вашего компонента :tada:


Этот документ находится под версионным контролем — предлагайте изменения на GitHub.

47 лайков

Привет @awesomerobot,

Спасибо за объяснение. Я попробовал шаги, которые вы предложили, но реализованный мной after_header по-прежнему отображается на страницах детального просмотра постов. Можете ли вы порекомендовать, как исправить это, чтобы он показывался только на моей главной странице?

1 лайк

Привет, @Cornelius, можно посмотреть твой код?

2 лайка

Было бы здорово переписать это с учётом современного использования файловой системы, а не размещать всё в тегах заголовков.

Большинство этих старых руководств по темам устарели, так как сейчас всё делается иначе.

7 лайков

Да, это было довольно устаревшим! Я обновил это, чтобы отразить структуру удалённых тем и наши современные компоненты Ember.

6 лайков

Это здорово!

И этот getter — это то же самое, что и http://ember-cli-page-object.js.org/docs/v1.11.x/api/getter.html? Я знаю ровно столько, чтобы быть опасным. Если это одно и то же, то я отредактирую первый пост и добавлю ссылку на него.

3 лайка

@awesomerobot Привет, Kris! Я установил Discourse локально на своей системе. Какой правильный путь для добавления этих файлов в мою локальную версию Discourse? Я хочу добавить новый компонент темы в свою локальную версию Discourse.

1 лайк

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

Установка темы или компонента темы

Установите консольное приложение Discourse Theme CLI для помощи в создании тем

4 лайка

Если я создам свою домашнюю страницу на основе представления категории, то, соответственно, я всё ещё буду получать свой пользовательский контент, даже если перейду по адресу /categories, который не является корневым URL. Я хочу ограничить это только корневым URL /, и, как мне кажется, предыдущий код делал именно это, но я задаюсь вопросом, должно ли это делать defaultHomepage().

3 лайка

discovery.${defaultHomepage()} будет соответствовать маршруту, установленному в качестве стартового с помощью настройки top-menu. Он будет совпадать как с корневой URL-адресом /, так и с конкретным маршрутом, например /categories.

По моему опыту, при создании кастомной главной страницы на основе defaultHomepage() возникают две сложности:

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

Чтобы создать кастомную главную страницу только для корневого URL, можно проверить условие router.currentURL === '/'. По умолчанию это условие совпадает только с корневым URL /, а не с стартовым маршрутом, заданным настройкой верхнего меню. Однако в ссылках боковой панели теперь есть логика, которая дополнительно пытается сопоставить данный URL с маршрутом. Поэтому по умолчанию это не будет работать для ссылок в боковой панели. Я только что создал тему по этому вопросу: Могу ли я иметь ссылки в боковой панели, которые не разрешают URL в маршрут?

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

4 лайка

Да, это своего рода давний обходной путь, при котором / и соответствующий /route могут отображать разный контент. У нас есть задача по:

  1. Разрешению независимой настройки главной страницы от параметра top_menu.
  2. Добавлению нового автономного шаблона главной страницы, который можно настраивать, не захватывая существующий маршрут.

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

6 лайков