alkah3st
(Daniel Quinn)
1
이 문제에 대한 몇 가지 게시물을 봤지만, 명확한 답변은 찾지 못했습니다.
Unreal Engine Discourse(Discourse의 “Discover” 페이지에 소개된)는 완전히 커스텀 테마를 사용 중인가요, 아니면 이 효과를 달성할 수 있는 컴포넌트가 있나요?
또한, 하위 카테고리를 클릭하면 상위 레벨 링크로 표시되고, 그 아래에 모든 토픽이 나열되는 것을 확인할 수 있습니다. 여기서 일어나는 일은 부모 카테고리의 "Subcategory List Style"을 "Rows"로 설정하는 것인가요?
alkah3st
(Daniel Quinn)
3
컴포넌트로 해결할 수 있는 문제가 아닐 것 같습니다.
다만, AI의 도움으로 이 기능을 구현하는 JS와 CSS를 생성해 보았습니다. 관심 있으신 분이 계신다면 기꺼이 공유하겠습니다.
nathank
(Nathan Kershaw)
4
이미 보셨을 것 같습니다:
그리고 이것도:
당연히 코드를 공유해 주세요. 물론, 이런 것들의 문제는 지속적인 유지보수입니다.
alkah3st
(Daniel Quinn)
5
네, 그들이 하는 일의 상당 부분이 커스텀 작업인 것 같습니다.
제 스크립트는 다음과 같습니다:
import { apiInitializer } from "discourse/lib/api";
import { ajax } from "discourse/lib/ajax";
export default apiInitializer("0.11.1", (api) => {
ajax("/site.json").then((data) => {
const categories = data.categories;
// Build map of parent_id => [child_category_ids]
const childMap = {};
categories.forEach((cat) => {
if (cat.parent_category_id) {
if (!childMap[cat.parent_category_id]) {
childMap[cat.parent_category_id] = [];
}
childMap[cat.parent_category_id].push(cat.id);
}
});
const collapseState = {}; // Tracks collapse state per parent
function applyCollapseState(parentId, childIds, collapsed) {
childIds.forEach((childId) => {
const childEl = document.querySelector(
`.sidebar-section-link-wrapper[data-category-id="${childId}"]`
);
if (childEl) {
childEl.classList.toggle("is-collapsed", collapsed);
childEl.classList.add("is-subcategory");
}
});
}
function ensureToggleExists(parentId, childIds) {
const parentEl = document.querySelector(
`.sidebar-section-link-wrapper[data-category-id="${parentId}"]`
);
if (!parentEl || parentEl.classList.contains("has-toggle")) return;
const toggle = document.createElement("span");
toggle.innerText = collapseState[parentId] ? "▸" : "▾";
toggle.className = "toggle-subcategories";
toggle.style.cursor = "pointer";
toggle.style.marginLeft = "0.5em";
toggle.onclick = () => {
const isNowCollapsed = !collapseState[parentId];
applyCollapseState(parentId, childIds, isNowCollapsed);
toggle.innerText = isNowCollapsed ? "▸" : "▾";
collapseState[parentId] = isNowCollapsed;
};
parentEl.classList.add("has-toggle");
const link = parentEl.querySelector(".sidebar-section-link");
if (link) link.appendChild(toggle);
}
api.onPageChange(() => {
Object.entries(childMap).forEach(([parentId, childIds]) => {
// Set default collapse state
if (collapseState[parentId] === undefined) {
collapseState[parentId] = true;
}
applyCollapseState(parentId, childIds, collapseState[parentId]);
ensureToggleExists(parentId, childIds);
});
const container = document.querySelector('[data-section-name="categories"]');
if (!container) return;
const observer = new MutationObserver(() => {
Object.entries(childMap).forEach(([parentId, childIds]) => {
applyCollapseState(parentId, childIds, collapseState[parentId]);
ensureToggleExists(parentId, childIds); // <-- Restore toggles
});
});
observer.observe(container, {
childList: true,
subtree: true,
});
});
});
});
그냥 이 코드를 테마의 JS 패널에 넣었습니다. 관련 CSS는 다음과 같습니다:
.sidebar-section-link-wrapper.is-collapsed {
display: none !important;
}
.sidebar-section-link-wrapper.is-subcategory {
padding-left: 1.5em;
}
.toggle-subcategories {
float: right;
display: flex;
width: 30px;
align-items: center;
font-size: .9em;
line-height: 1;
height: 30px;
}
제 용도에는 충분히 잘 작동하지만, 하위 카테고리가 많다면 이 방법을 권장하지 않습니다.