참고로, 내 쪽에서는 제목을 클릭해서 주제에 접근하는 것을 잊는 사용자를 위해 ‘+ 정보’ 버튼을 추가했습니다. @nathank 님의 ‘캘린더에 추가’ 버튼 아이디어를 참고했습니다.
스크립트는 컴포넌트 테마의 일반 /head 부분에 넣으세요.
<script>
(() => {
const eventInfoSelector = ".event-header .event-info";
const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";
// Discourse 테마(라이트/다크)에 맞게 깔끔하게 주입된 CSS
const style = document.createElement("style");
style.innerHTML = `
.custom-topic-info-btn {
display: flex !important;
align-items: center;
justify-content: center;
width: 40%; /* 제목 아래 깔끔한 렌더링을 위해 전체 너비 사용 */
box-sizing: border-box;
margin: 12px 0 6px 0;
padding: 10px 16px;
/* Discourse 네이티브 변수 사용 */
background-color: var(--tertiary) !important; /* 강조 색상 (예: 파랑) */
color: var(--secondary) !important; /* 대비되는 텍스트 색상 */
border-radius: 8px;
font-weight: 700;
text-decoration: none !important;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
transition: background-color 0.2s ease, transform 0.1s ease;
}
/* 호버 효과 */
.custom-topic-info-btn:hover {
background-color: var(--tertiary-hover) !important;
color: var(--secondary) !important;
transform: translateY(-1px);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
}
/* 클릭 효과 */
.custom-topic-info-btn:active {
transform: translateY(0);
}
/* SVG 아이콘 스타일 */
.custom-topic-info-btn .btn-icon-svg {
margin-right: 8px;
width: 16px;
height: 16px;
fill: currentColor;
}
`;
document.head.appendChild(style);
const findTopicLink = (container) => {
if (!container) return null;
const links = [...container.querySelectorAll('a[href*="/t/"]')];
if (links.length) return links[0].href;
return null;
};
const createTopicInfoButton = () => {
const eventInfo = document.querySelector(eventInfoSelector);
if (!eventInfo || eventInfo.querySelector(".custom-topic-info-btn")) return;
const card = eventInfo.closest(eventCardSelector) || document;
const topicUrl = findTopicLink(card);
if (!topicUrl) return;
const button = document.createElement("a");
button.className = "btn custom-topic-info-btn";
button.title = "전체 주제 보기";
button.href = topicUrl;
// 조화로운 SVG 정보 아이콘 추가
button.innerHTML = `
<svg class="btn-icon-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V240h-24c-13.3 0-24-10.7-24-24s10.7-24 24-24h40c13.3 0 24 10.7 24 24v120h24c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144a32 32 0 1 1 0-64 32 32 0 1 1 0 64z"/>
</svg>
<span class="d-button-label">더 많은 정보</span>
`;
if (eventInfo.firstElementChild) {
eventInfo.insertBefore(button, eventInfo.firstElementChild.nextSibling);
} else {
eventInfo.appendChild(button);
}
};
const observer = new MutationObserver(() => createTopicInfoButton());
observer.observe(document.body, { childList: true, subtree: true });
createTopicInfoButton();
})();
</script>
아래는 미리보기입니다
아니면
이 코드를 사용하세요
<script>
(() => {
const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";
// 깔끔하고 현대적인 렌더링을 위한 주입된 CSS
const style = document.createElement("style");
style.innerHTML = `
.custom-topic-info-wrapper {
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid var(--primary-low); /* 은은한 구분선 */
width: 100%;
display: flex;
justify-content: center;
}
.custom-topic-info-btn {
display: flex !important;
align-items: center;
justify-content: center;
width: 100%;
box-sizing: border-box;
padding: 8px 16px;
/* 우아한 아웃라인 스타일 */
background-color: transparent !important;
color: var(--tertiary) !important;
border: 1px solid var(--tertiary) !important;
border-radius: 6px;
font-weight: 600;
text-decoration: none !important;
transition: all 0.2s ease;
cursor: pointer;
}
/* 호버 효과: 버튼이 채워짐 */
.custom-topic-info-btn:hover {
background-color: var(--tertiary) !important;
color: var(--secondary) !important;
border-color: var(--tertiary) !important;
}
/* 정보 로고 정렬 */
.custom-topic-info-btn .btn-icon-svg {
margin-right: 8px;
width: 16px;
height: 16px;
fill: currentColor;
}
`;
document.head.appendChild(style);
const findTopicLink = (container) => {
if (!container) return null;
const links = [...container.querySelectorAll('a[href*="/t/"]')];
if (links.length) return links[0].href;
return null;
};
const createTopicInfoButton = () => {
const cards = document.querySelectorAll(eventCardSelector);
cards.forEach(card => {
if (card.querySelector(".custom-topic-info-btn")) return;
const topicUrl = findTopicLink(card);
if (!topicUrl) return;
const wrapper = document.createElement("div");
wrapper.className = "custom-topic-info-wrapper";
const button = document.createElement("a");
button.className = "btn custom-topic-info-btn";
button.title = "전체 주제 보기";
button.href = topicUrl;
// "i" 정보 아이콘 + 실행 가능한 새 텍스트
button.innerHTML = `
<svg class="btn-icon-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V240h-24c-13.3 0-24-10.7-24-24s10.7-24 24-24h40c13.3 0 24 10.7 24 24v120h24c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144a32 32 0 1 1 0-64 32 32 0 1 1 0 64z"/>
</svg>
<span class="d-button-label">주제 보기</span>
`;
wrapper.appendChild(button);
// 응답 옵션(참석 등) 위에 위치시키기
const actionsContainer = card.querySelector(".status-and-options, .event-actions");
const infoContainer = card.querySelector(".event-info");
if (actionsContainer && actionsContainer.parentNode) {
actionsContainer.parentNode.insertBefore(wrapper, actionsContainer);
} else if (infoContainer) {
infoContainer.appendChild(wrapper);
} else {
card.appendChild(wrapper);
}
});
};
const observer = new MutationObserver(() => createTopicInfoButton());
observer.observe(document.body, { childList: true, subtree: true });
createTopicInfoButton();
})();
</script>
결과 미리보기
선택의 여지가 있습니다 ![]()

