콘솔에 오류가 표시되지 않습니다. 하지만 참고용으로 동영상을 녹화했습니다.
이 문제는 Chrome, Firefox, Safari에서 모두 발생합니다. 모바일 Safari에서는 발생하지 않습니다.
영상 링크가 깨졌어요!
실례합니다. 제가 제대로 이해하지 못했네요. 맞아요, 달력에서 날짜를 클릭하면 이벤트 생성 모달이 열리지만, ‘종료하시겠습니까?’ 버튼이 함께 표시됩니다. 네, 맞아요. 작은 버그가 있네요 ![]()
참고로, 내 쪽에서는 제목을 클릭해서 주제에 접근하는 것을 잊는 사용자를 위해 ‘+ 정보’ 버튼을 추가했습니다. @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>
결과 미리보기
선택의 여지가 있습니다 ![]()
최근 업데이트 이후로 이벤트를 생성하는 과정이 정말 쉬워졌어요 ![]()
하지만, 사용자가 캘린더를 클릭할 때 이벤트 생성을 막아주는 설정이 있는지 궁금합니다. 가끔 이벤트가 아닌 옆 부분을 클릭하게 되면 이벤트 생성 모달이 열리거든요 ![]()
감사합니다
귀찮은 질문이라는 걸 알지만, 만료된 이벤트에 대해 또 다른 질문이 있습니다. 더 이상 표시할 필요가 없으므로 자동으로 삭제할 수 있을 것 같습니다. events 플러그인이 자동으로 그렇게 했었거든요.
현재는 수동으로 처리하고 있어서, 시간을 절약할 수 있는 방법이 있다면 알려주세요. ![]()
팀에 감사드립니다.
이벤트의 위치에서 구글 캘린더나 페이스북 이벤트처럼 위치 검색을 할 수 있는 방법이 있을까요? a) 사용자가 위치를 선택하는 데 도움을 주고, b) 위치를 클릭하면 지도 앱으로 연결되도록 하는 기능입니다.
(검색을 해봤는데 해결책을 찾지 못했는데, 아마 검색어가 적절하지 않았을 수도 있습니다)
Locations Plugin 🌍 에도 그런 기능이 있지만, 대안인 Angus' Events Plugin 📅 플러그인과만 통합됩니다.
개발자(@merefield)가 공식 플러그인과의 통합에 개방적일 수 있지만, 이를 구축하고 유지보수하는 데 상당한 노력이 필요할 것으로 예상됩니다. 따라서 이 작업이 이루어지려면 definitely 스폰서십이 필요합니다.
저는 그 Events 플러그인을 살펴보려고 했지만, 아래 부분에서 막혀 있습니다.
해당 사이트가 몇 달째 다운되어 있기 때문입니다.
Contribute > Feature 채널에 #calendar-and-events 태그를 달아서 공식적인 기능 요청을 올려보는 것도 좋을 것 같습니다. 실현 가능성이 높을 수 있으며, 많은 사용자에게 큰 가치를 제공할 잠재력이 있다고 생각합니다.
나중에…
@lou 님이 실제로 이 요청을 등록하셨습니다:
게시물이 기존 주제에 병합되었습니다: 이벤트 위치 지도 지원
일부 WordPress 플러그인을 사용하여 /discourse-post-event/events.ics에서 ICS 피드를 읽을 수 있도록 하여 공개 이벤트를 WordPress 웹사이트로 내보내려는 계획입니다. 지금까지는 잘 진행되고 있습니다.
이 웹사이트에는 이러한 이벤트의 하위 집합을 표시하려는 페이지들이 몇 개 있습니다. 각 페이지는 서로 다른 하위 집합을 표시하려고 합니다.
각 페이지와 연관된 태그로 이벤트를 태그하면 ICS 파일의 CATEGORIES 행에 표시되어 대상에서 필터링할 수 있기를 희망했지만, 그렇게 되어 있지 않은 것 같습니다.
URL에 ?tag=[tag]를 사용하고 각 페이지가 서로 다른 URL을 사용하도록 하는 방식도 사용할 의향이 있지만, 찾아본 자료에서 이것이 지원되는 기능인지는 확인하지 못했습니다.
제가 고려하지 않고 있는 부분이 있을까요?
아니요, 당신이 놓친 것은 없습니다(제가 아는 한).
다만, 캘린더 .ics 피드를 카테고리 및/또는 태그별로 필터링할 수 있도록 하는 것은 가치 있는 Contribute > Feature 요청이 될 것입니다!
결국 직접 태그 필터를 만들어야 할 것 같습니다. 그런데 “만료된” 이벤트는 /discourse-post-event/events.ics를 통해 다운로드되지 않는 것 같습니다. 또한 이벤트가 "만료"되는 시점을 제어하는 방법도 찾지 못했습니다. /…/events.ics를 사용하는 대신 데이터 탐색기 쿼리를 사용해야 할 수도 있습니다.
[다만 /discourse-post-event/event를 사용하여 이 문제를 해결하는 더 나은 방법을 찾은 것 같습니다]
안녕하세요, 오디오 및 라이브 스트림과 함께 이벤트를 통합하는 기능에 대한 피드백을 구하고 있습니다. 관련 내용은 아래 링크의 마지막 답변을 참고해 주세요 → https://meta.discourse.org/t/discourse-desktop-mac-app/406912/10?u=nicolsdennis
VDO.Ninja를 이벤트 라이브스트리밍에 구현해본 분이 있으신가요? Zoom 연동은 확인했는데, Zoom 대신 이를 우회적으로 적용할 수 있는 방법이 있을 것 같다는 생각이 듭니다 ![]()
게시물 3개가 새 주제로 분리되었습니다: Zoom 라이브스트림 통합에 대한 질문
Discourse Calendar / Events의 Upcoming Events 라우트는 초기 서버 렌더링 HTML 응답에서 모든 Open Graph 및 Twitter-card 메타데이터를 제외하는 것으로 보입니다.
이 문제는 일반 페이지가 소셜 메타데이터를 올바르게 출력하고 유효한 사이트 OpenGraph 이미지가 구성된 호스팅된 Discourse 사이트에서 재현됩니다.
영향을 받는 라우트 예시:
https://www.mbacommons.com/upcoming-events/month/2026/8/1
재현 단계
- 유효한 사이트 OpenGraph 이미지를 구성합니다.
- 홈페이지 또는 일반 토픽이 원본 HTML에서 일반적인 Open Graph 메타데이터를 출력하는지 확인합니다.
/upcoming-events/month/2026/8/1을 엽니다.- JavaScript 적용 후 DOM이 아닌 원본
view-source:/ 초기 서버 응답을 검사합니다.
실제 결과
Upcoming Events 라우트는 HTTP 200을 반환하지만, 원본 HTML에는 다음이 포함되어 있지 않습니다:
og:imageog:titleog:descriptionog:urltwitter:cardtwitter:image
LinkedInBot/1.0을 사용하여 테스트해 보았지만 결과는 동일했습니다.
같은 사이트에서 수행한 원본 HTML 프로덕션 감사 결과:
- 홈페이지: 소셜 메타데이터 태그 11개
- 일반 토픽: 14개
- Upcoming Events: 0개
홈페이지와 일반 토픽은 구성된 사이트 OpenGraph 이미지를 올바르게 사용하므로, 사이트 레벨 브랜딩 구성 자체는 정상적으로 작동하고 있습니다.
예상 결과
Upcoming Events 라우트는 크롤러가 볼 수 있는 서버 렌더링 소셜 메타데이터를 출력해야 하며, 최소한 다음을 포함해야 합니다:
og:titleog:descriptionog:urlog:image(구성된 사이트 OpenGraph 이미지로 폴백)- 해당되는 Twitter-card 메타데이터
LinkedIn과 유사한 소셜 크롤러는 클라이언트 측 테마 JavaScript에 의존할 수 없으므로, 이는 초기 HTML에 포함되어야 합니다.
LinkedIn Post Inspector는 현재 다음과 같이 보고합니다:
LinkedIn에서 콘텐츠의 이미지를 제어하려면 페이지에 og:image 태그를 추가하십시오.
글로벌 테마의 head_tag 주입은 적절하지 않은 것으로 보입니다. 일반 페이지에는 이미 올바른 메타데이터가 있으며, 이를 사용하면 중복/충돌하는 태그가 생성될 수 있기 때문입니다. 이는 Upcoming Events에 대한 라우트 인식 서버 측 처리 또는 Discourse의 일반 소셜 메타데이터 렌더링 경로 사용이 필요한 것으로 보입니다.
Peertube Live와 Discourse 달력 및 이벤트
지난해 여름(2025년)에는 Peertube와 함께 이 기능이 정상적으로 작동했습니다. #livestream 태그를 붙이면, /embed/xxx 비디오 URL을 사용하여 라이브 비디오를 표시하고 Peertube의 P2P로 인한 약 30초의 지연을 고려하여 주제와 함께 채팅 인터페이스를 제공했습니다.
하지만 오늘 다시 시도해 보니, 채팅이 예전처럼(적어도 제 기억에 따르면) 레이아웃에 임베드되지 않는 것 같습니다. 또한 이벤트 인터페이스에도 "라이브스트림 버튼"이 없습니다. 이것이 정상적인가요?
최근 업데이트된 지침을 보셨나요? 이 플러그인으로 통합되면서 UI가 조금 변경되었을 것 같습니다.

