Примечание: Перед публикацией этого компонента темы я хотел бы получить обратную связь — соответствует ли он критериям или есть ли в нём серьёзные проблемы.
Раскрытие информации: Этот компонент темы был спланирован, реализован и протестирован с помощью инструментов ИИ для программирования.
Discourse Tag Reveal — это лёгкий компонент темы, который поддерживает аккуратность списков тем, отображая только первые N тегов для каждой темы и заменяя остальные доступной кнопкой-переключателем «+X ещё тегов». Пользователи могут развернуть список, чтобы увидеть все теги, и свернуть его обратно в сокращённый вид. Компонент работает «из коробки» со стандартным интерфейсом тегов Discourse и не требует изменений на стороне сервера.
Возможности
Настраиваемый лимит тегов (по умолчанию: 5) через настройки темы
Переключатель оформлен как тег, доступен с клавиатуры (Enter/Space) с атрибутами ARIA
Локализованные строки с использованием themePrefix и discourse-i18n
Безопасное поведение в SPA: сброс и повторное применение логики при изменении страницы
Поддержка бесконечной прокрутки через MutationObserver
Минимальный CSS; сохраняет основные стили тегов
Никаких переопределений шаблонов или зависимостей от плагинов
Видео-демонстрация:
Установка и настройка
Протестировано с версией Discourse: 3.6.0beta1
Настройки конфигурируются на вкладке «Settings» компонента:
max_tags_visible (целое число, по умолчанию 5): количество отображаемых тегов перед сворачиванием
toggle_tag_style: визуальный стиль переключателя для соответствия внешнему виду тегов (в настоящее время реализован только стиль «box»)
Область применения: влияет на списки тем (Последние, Новые, Непрочитанные и списки тем категорий)
Совместимость с другими компонентами тем
Проведены лишь минимальные тесты, пожалуйста, протестируйте самостоятельно перед развёртыванием в продакшен
Выглядит действительно интересно. Я попробую это в своей среде разработки позже, так как, похоже, это не работает в Theme Creator (если я, конечно, ничего не делаю не так?) .
Добавлена короткая видеодемонстрация в первом посте, смотрите здесь:
Я даже ещё не проверял, как отправить/добавить свой компонент для TC туда…
Но в любом случае, я предпочитаю сначала собрать здесь обратную связь, а когда всё будет готово к публикации в #theme-component, посмотрю, как добавить его туда.
Хорошая мысль. Я забыл изменить метку по умолчанию на +%{count} ещё, чтобы она была короткой и лаконичной. Так мы её используем, чтобы всё оставалось компактным и чистым.
Эта функция может быть интересна в некоторых ситуациях!
На первый взгляд, стоит отметить несколько моментов:
Настройки темы и настройки сайта — это не одно и то же. Чтобы получить доступ к max_tags_per_topic, сначала нужно получить сервис, например: const siteSettings = api.container.lookup("service:site-settings");
Дополнительные проверки для получения лимита, вероятно, не нужны; вы можете получить значение напрямую. Скорее всего, можно сделать так: Math.min(settings.max_tags_visible, siteSettings.max_tags_per_topic)
Вы не восстанавливаете видимость разделителей.
Возможно, стоит отменить регистрацию обработчиков событий.
Процесс при первоначальной загрузке, скорее всего, не нужен при использовании MutationObserver. Обычно, прежде чем применять решение глобально, стоит проверить, можно ли сузить область вокруг элемента с помощью API (например, через плагин outlet).
Вы используете это в классе. В противном случае это не сработает.
Тогда вам нужно написать 3.6.0.beta1, иначе в данный момент никто не сможет его установить.
Я немного проверил. Действительно, простого способа достичь этого нет; однако я нашел интересный и упрощенный метод с использованием API.
Он использует модель темы для изменения того, какие видимые теги будут выведены до генерации шаблона. Это означает отсутствие манипуляций с DOM и независимость от настроек. В зависимости от состояния (revealTags) он вернет либо исходный список, либо его часть.
Для создания кнопки переключения используется API для добавления тега с HTML-кодом кнопки (к сожалению, здесь нет точки расширения плагина). Событие клика обрабатывается отдельно. При клике обновляется состояние переключения (revealTags), и мы запускаем повторный рендеринг списка тегов.
Главное преимущество этого подхода в том, что вам не нужно возиться с HTML и выяснять, что показывать/скрывать с помощью CSS, исходя из различных стилей.
Привет, ребята! Я выпустил ещё одно обновление и добавил дополнительные экспериментальные функции (теги «featured», которые всегда отображаются первыми и не учитываются при подсчёте максимального количества, а также подсветка строки темы в списке тем). В связи с этим общая логика работы с тегами немного меняется, чтобы обеспечить более расширенный функционал для подсветки определённых тем на основе настроенных вкладок.
@Arkshine, спасибо за твой упрощённый метод, я очень это ценю!!!
Это также повлияло на просмотр отдельной темы, поэтому мы добавили настройку для ручного включения такого поведения. Кроме того, при использовании нового метода состояние развёрнутой темы сохраняется при переходе на другие маршруты/страницы, но я пока не реализовал эту часть.
Понятно. Я считаю, что это имеет смысл, если информация отображается в виде тега, но здесь это кнопка для отображения дополнительных тегов; контекст для меня другой. Решать вам; я не думаю, что это так уж важно.
Продолжая обратную связь:
Список тегов может отображаться в других местах, например: на странице категорий, в активности пользователя и т. д. Я бы, вероятно, убрал настройку collapse_in_topic_view и либо создал новую с конкретными маршрутами, либо просто включил её везде.
В моем тестовом коде я использовал что-то вроде этого для игнорирования других маршрутов:
Вам не нужно устанавливать текущий маршрут из onPageChange, вы можете получить к нему доступ через роутер.
Будьте осторожны с регистром букв в тегах. У вас есть настройки сайта, которые не принуждают к нижнему регистру, поэтому, я думаю, лучше не изменять тег.
Что касается сброса состояния, вы, вероятно, можете использовать onPageChange.
JS
api.onPageChange((url) => {
const route = api.container.lookup("service:router").recognize(url);
if (!isAllowedRoute(route?.name)) {
return;
}
for (const [id, model] of topicModels) {
if (model && model.revealTags) {
model.revealTags = false;
model.notifyPropertyChange("tags");
}
}
});
Если возможно, было бы здорово добавить тесты.
Вот полный код теста (я внес другие незначительные изменения)