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

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

Вы можете добавить некоторый HTML в раздел «After Header» вашей темы, и тогда он будет появляться на каждой странице. Вы можете потратить много времени на 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. Вы можете добавить любой HTML между блоками {{#if}}.

Теперь, когда наш компонент создан, нам нужно добавить его в Discourse в нужное место. Для этого шага вам нужно решить, какой плагинный отсек (plugin outlet) использовать. Это области в Discourse, где мы добавили немного кода, чтобы разработчики могли подключаться к ним. Вы можете поискать их в 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 лайков