Использование новой функции пользовательской домашней страницы

Попробую новую функцию кастомной домашней страницы: DEV: allow themes to render their own custom homepage by pmusaraj · Pull Request #26291 · discourse/discourse · GitHub :tada:

@pmusaraj Интересно, какой подход лучше всего подходит для добавления компонентов?

  1. Добавление модификатора custom-homepage включает маршрут discovery.custom и отображает стандартное информационное уведомление, которое рендерится в слоте custom-homepage:

  2. Я добавляю компонент в этот слот, и он отображается вместо уведомления:

  3. Однако, если я добавляю более одного компонента, возникает ошибка:

  4. При этом я могу добавлять несколько компонентов в другие слоты. Вот пример с видимыми плагинными слотами:

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

  • С одной стороны, слот может и не понадобиться. Я могу просто использовать другие доступные слоты и ограничить компоненты маршрутом discovery.custom.
  • С другой стороны, похоже, что нужно добавить хотя бы один компонент в слот, иначе отображается стандартное уведомление? Пустой шаблон там не работает.
  • В то же время, если бы я мог добавлять несколько компонентов в слот, логика маршрута вообще не понадобилась бы. Компоненты отображались бы только на домашней странице, поскольку слот будет недоступен на других маршрутах?

Это не удивительно?

Разместите здесь один шаблонный файл и используйте его для ссылки на ваши компоненты в папке Components (в которой вы можете иметь множество таких компонентов):

<MyFirstComponent />
<MySecondComponent />
<MyThirdComponent />

Или что угодно другое… просто придерживайтесь одного шаблона в этой папке?

Я думал, что это связано с тем, что он работает с другими розетками? Как на скриншоте выше..

Ой, извините, вы правы. Похоже, что в Outlets (обычно) разрешено публиковать более одного файла шаблона в одном компоненте темы (я знал, что система обрабатывает конфликты между компонентами темы и плагинами, чтобы все они могли отображаться). Любопытно.

Хотя возникает вопрос: зачем вам это нужно? У вас будет меньше контроля над макетом?

Один шаблон заставляет вас сразу компоновать весь макет с любым количеством подкомпонентов, которые вы хотите?

Поведение, однако, кажется несогласованным…

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

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

Но почему вы не можете ссылаться на все эти компоненты в одном шаблоне?

Ах, потому что они приходят из разных компонентов темы?

Кажется, мы говорили о разных вещах.

Когда я говорю «разместите все свои (Ember) компоненты в папке Components», я имею в виду именно это, но в рамках одного компонента темы.

Я думаю, суть здесь проста: «почему этот выход ведёт себя иначе?» Я понимаю, что вы пытаетесь объединить разные компоненты темы.

Да, именно так. Я просто использовал приведенные выше шаблоны обычного текста в качестве иллюстрации. Например, я использую Featured Lists. И я могу отобразить его на выходе с этими настройками:

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

:+1:t4:

Спасибо за тестирование, @manuel, и за ваши вопросы.

Я тоже не знал ответа на этот вопрос, но поискал и примерно понял причину. В прошлом году в рамках этого PR мы ввели различие между классическими выходами плагинов и обёрнутыми выходами плагинов: DEV: Allow PluginOutlets to 'wrap' a core implementation by davidtaylorhq · Pull Request #23110 · discourse/discourse · GitHub

Обёрнутые выходы плагинов позволяют подключать только один коннектор, остальные — несколько. Для наглядности: текущий код выхода плагина в ядре выглядит так:

<PluginOutlet @name="custom-homepage">
  {{#if this.currentUser.admin}}
    <p class="alert alert-info">
      {{i18n "custom_homepage.admin_message"}}
    </p>
  {{/if}}
</PluginOutlet>

и он допускает только один коннектор. Однако, если изменить код выхода в ядре на:

<PluginOutlet @name="custom-homepage" />

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

Обратите также внимание, что при использовании нескольких коннекторов возникает проблема порядка: насколько мне известно, у нас нет механизма для определения порядка их отображения.

В любом случае, я считаю, что лучший подход здесь — это то, что предложил @merefield: использовать один шаблон и ссылаться из него на компоненты Ember.

Стандартное уведомление отображается только администраторам, FYI.

Спасибо за разъяснения!

Попользовавшись этим чуть больше… это действительно свежо и приятно в использовании!

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

Ещё одно наблюдение: я добавил ссылку в боковую панель, используя URL /custom:

Она не подсвечивается, когда мы находимся на кастомном маршруте.

Если я правильно понимаю логику подсветки ссылок в боковой панели, она также должна подсвечиваться на корневом URL /.

После краткого ознакомления с компонентом Featured Lists я лучше понял вашу проблему. Один из вариантов — рефакторинг этого компонента и вывод всех списков в один компонент Ember. Затем вы сможете добавить этот компонент в выходной слот обёртки плагина.

Другой вариант — добавить второй выходной слот плагина в шаблон пользовательской главной страницы, например, <PluginOutlet @name="below-custom-homepage"/>.

Честно говоря, я, возможно, удерживаю этот выходной слот custom-homepage с сообщением для администраторов без особой причины. Это предупреждение не особенно полезно…

Да, это может быть непросто. В моём локальном тесте только что /custom не работал корректно. Лучше использовать /, который маршрутизируется правильно. Но даже тогда подсветка не появляется.

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

Да, я тоже могу представить, что предупреждение просто отображалось бы иначе. Основное преимущество wrapper outlet, кажется, в том, что я могу условно выводить основной код или рендерить кастомный. Но для этого информационного сообщения такой случай, вероятно, никогда не возникнет.

Должно быть, возникло недопонимание. Компонент уже оборачивает все списки в одну обёртку и рендерит её на любом заданном outlet:

image

Поэтому я могу добавить компонент без проблем в текущий wrapper outlet на кастомной целевой странице.
Что я не могу сделать, так это использовать этот outlet для рендеринга более чем одного автономного компонента на кастомной целевой странице. Компоненты, которые я бы установил как компоненты темы, например, эти три:

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

Если вы рассматриваете добавление ещё одного outlet или изменение настройки outlet, я могу дать дополнительную обратную связь на основе моего опыта использования. Хотя я не буду углубляться в детали этой кроличьей норы :smile:

Итак, я понял, что outlet рендерится внутри элемента main-outlet. Общая структура этих элементов такова:

  • обёртка main-outlet
    • sidebar-wrapper
    • main-outlet
      • custom-homepage outlet

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

Структура, показанная на скриншоте выше, выглядит так:

  • обёртка main-outlet
    • sidebar-wrapper
    • компонент: баннер поиска
    • компонент: избранные темы
    • компонент: избранные списки
    • main-outlet

Преимущество в том, что я могу располагать элементы по всей ширине обёртки main-outlet, а не только внутри элемента main-outlet. Чтобы проиллюстрировать это: если бы я рендерил один из компонентов на текущем custom-homepage outlet, он бы рендерился вложенным внутри элемента main-outlet вот так:

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

  • как прямой потомок обёртки main-outlet (аналогично outlet before-main-outlet)
  • внутри обёрточного div

Этот обёрточный div объединял бы все добавленные в него компоненты и позволял бы легко менять их порядок. Такая структура выглядела бы так:

  • обёртка main-outlet
    • sidebar-wrapper
    • custom-homepage-wrapper
      • компонент: баннер поиска
      • компонент: избранные темы
      • компонент: избранные списки
    • main-outlet

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

Предположительно, эта страница является «поверхностной» в том смысле, что она будет отображаться для пользователя, но не для «Googlebot», и поэтому не будет проиндексирована?

Да, верно, для представления краулера я решил выводить только верхнее меню. Из приложения Rails действительно невозможно узнать, что именно выведет тема в этом маршруте.

Я обдумываю предложения здесь, @manuel, и скоро выделю время, чтобы протестировать некоторые изменения. Пожалуйста, :bear: подождите меня.

Я добавил поддержку этой функции в Discourse Bars 🍻 🍸 (a sidebar framework) - #43 by merefield

Возникла следующая проблема: я хотел отобразить компонент Homepage Feature на пользовательской главной странице. Однако на этом маршруте темы не фильтруются. Компонент просто показывает любые недавние темы, у которых есть изображение.

Код компонента выглядит так:

    const topicList = await this.store.findFiltered("topicList", {
      filter: "latest",
      params: {
        tags: [`${settings.featured_tag}`],
        order: sortOrder,
      }

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

Редактирование: Я использую тот же метод в компоненте Featured Lists. При использовании этого компонента на пользовательской главной странице фильтр также не применяется. Но это касается только первого списка… если списков больше, то следующие списки фильтруются корректно.

Интересно, я не уверен, почему это так. Возможно, в хранилище topicList есть какая-то логика, связанная с маршрутами обнаружения? Пользовательская главная страница не является маршрутом обнаружения.

Мне интересно, работает ли тот же компонент с параметрами нормально, скажем, в маршруте администратора или в маршруте профиля пользователя? Есть ли у вас возможность проверить?

@tynaut столкнулся с похожей проблемой, поэтому, скорее всего, здесь есть что-то, что нужно исправить.

Я пробовал использовать компонент «Избранные списки» — у него уже есть настройка для отображения компонента повсюду. Это не включает административные маршруты, но я проверил все остальные (статические страницы, профили пользователей и т. д.), и он, кажется, работает везде, кроме пользовательской главной страницы.

Другая странность, о которой я упоминал, заключается в том, что фильтрация не применяется только к первому списку. Например, здесь я фильтрую два списка: один по тегу «featured», другой по категории «General», и вот как списки отображаются на всех остальных маршрутах:

Только на маршруте пользовательской главной страницы они отображаются так:

То есть первый список больше не фильтруется по тегу, а второй фильтруется по категории. А когда я меняю порядок списков, первый список не фильтруется по категории, а второй фильтруется по тегу:

Мне показалось немного сложным корректно воспроизвести это с компонентом Featured Homepage, так как он смешивает слишком много других условий.

Однако я могу легко воспроизвести это с упрощённым компонентом. Я выложил его в репозиторий-пример здесь: GitHub - pmusaraj/discourse-sample-custom-homepage · GitHub

Компонент sample-list оттуда должен подтягивать только темы с тегом featured, но этого не происходит (для меня подтягиваются первые 3 темы). Если я удалю модификатор custom_homepage из файла about.json этой темы, то подтянутся правильные темы.

Я найду кого-то, кто лучше знаком с сервисом store, чтобы он взглянул на это. Спасибо!

Привет!

Не могли бы вы объяснить, как добавить компонент (поисковый баннер или уже установленный на форуме пользовательский компонент) в файл home.hbs, чтобы он отображался на новой пользовательской главной странице?

Спасибо.