# Discourse 活动

**URL:** https://meta.discourse.org/t/discourse-events/97376
**Category:** Plugin
**Tags:** official, events, included-in-core
**Created:** [2018年九月17日 15:50 UTC](https://meta.discourse.org/t/discourse-events/97376 "2018-09-17T15:50:24Z")
**Posts on this page:** 20
**Page:** 8

<div class="post-metadata">

### Author: ![JuliusRa](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/juliusra/32/554488_2.png) [@JuliusRa](https://meta.discourse.org/u/JuliusRa)
#### Post date: [2026年六月1日 18:35 UTC](https://meta.discourse.org/t/discourse-events/97376/592 "2026-06-01T18:35:59Z")

</div>

控制台未显示任何错误。但我录制了一段视频供参考。  
此问题出现在 Chrome、Firefox 和 Safari 上。在移动 Safari 上则不会发生。

---

<div class="post-metadata">

### Author: ![gilles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gilles/32/549022_2.png) [@gilles](https://meta.discourse.org/u/gilles)
#### Post date: [2026年六月1日 19:08 UTC](https://meta.discourse.org/t/discourse-events/97376/593 "2026-06-01T19:08:52Z")

</div>

你的视频链接失效了！

---

<div class="post-metadata">

### Author: ![gilles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gilles/32/549022_2.png) [@gilles](https://meta.discourse.org/u/gilles)
#### Post date: [2026年六月1日 19:50 UTC](https://meta.discourse.org/t/discourse-events/97376/594 "2026-06-01T19:50:08Z")

</div>

抱歉，我之前没太理解。确实，你说得对：当我们在日历中点击某个日期时，会弹出创建事件的模态框，但其中包含“是否放弃”的按钮。是的，确实有个小问题：😅

---

<div class="post-metadata">

### Author: ![gilles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gilles/32/549022_2.png) [@gilles](https://meta.discourse.org/u/gilles)
#### Post date: [2026年六月1日 19:58 UTC](https://meta.discourse.org/t/discourse-events/97376/595 "2026-06-01T19:58:52Z")

</div>

供参考，我为用户添加了一个“更多信息”按钮，以防他们忘记点击标题以访问主题。我借鉴了 @nathank 在“添加到日历”按钮上的想法。

将脚本放入主题组件的通用部分 `/head` 中：

```plaintext
<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>

```

以下是预览效果：

 ![image](https://global.discourse-cdn.com/meta/original/4X/d/d/2/dd28cc577174015648a8f92231352adab3ef981f.png)

或者，也可以使用以下代码：

```plaintext
<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;
        
        /* 优雅的 Outline 样式 */
        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>

```

结果预览：

 ![image](https://global.discourse-cdn.com/meta/original/4X/c/0/2/c02ca11a0cc2f8b8d018a52dd3d863a300028f63.png)

您可以自行选择：rofl

---

<div class="post-metadata">

### Author: ![gilles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gilles/32/549022_2.png) [@gilles](https://meta.discourse.org/u/gilles)
#### Post date: [2026年六月3日 18:19 UTC](https://meta.discourse.org/t/discourse-events/97376/596 "2026-06-03T18:19:08Z")

</div>

自从上次更新以来，创建事件的便捷性确实得到了显著提升 👍

不过，我想了解一下，是否有一个设置可以防止用户在点击日历时直接创建事件？有时候用户本想点击某个事件，却误点到了旁边，结果弹出了创建事件的对话框 😅

谢谢

---

<div class="post-metadata">

### Author: ![gilles](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gilles/32/549022_2.png) [@gilles](https://meta.discourse.org/u/gilles)
#### Post date: [2026年六月5日 16:01 UTC](https://meta.discourse.org/t/discourse-events/97376/597 "2026-06-05T16:01:26Z")

</div>

我知道我有点烦人，但我还有一个关于过期事件的问题或改进建议。这些事件可以自动删除，因为它们似乎已不再需要存在。我记得“事件”插件以前是自动处理这一点的。

目前我是手动操作的，所以如果有办法节省时间就太好了：sweat\_smile：

感谢团队！

---

<div class="post-metadata">

### Author: ![Lou](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lou/32/544605_2.png) [@Lou](https://meta.discourse.org/u/Lou)
#### Post date: [2026年六月7日 19:08 UTC](https://meta.discourse.org/t/discourse-events/97376/598 "2026-06-07T19:08:25Z")

</div>

事件中的地点是否支持像 Google 日历或 Facebook 事件那样的查找功能？这样既能帮助用户选择地点，又能让地点可点击并跳转到地图应用。

（我尝试搜索但未找到解决方案，可能是我的搜索关键词不够准确。）

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [2026年六月8日 03:34 UTC](https://meta.discourse.org/t/discourse-events/97376/599 "2026-06-08T03:34:34Z")

</div>

[Locations Plugin 🌍](https://meta.discourse.org/t/locations-plugin/69742) 确实具备此类功能，但它仅与替代方案 [Events Plugin 📅](https://meta.discourse.org/t/events-plugin/69776) 集成。

开发者（@merefield）可能愿意将其与官方插件集成，但我估计这将需要大量的工作来建立和维护——因此，若要实现这一目标，您肯定需要资助相关工作。

---

<div class="post-metadata">

### Author: ![Lou](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lou/32/544605_2.png) [@Lou](https://meta.discourse.org/u/Lou)
#### Post date: [2026年六月8日 07:34 UTC](https://meta.discourse.org/t/discourse-events/97376/600 "2026-06-08T07:34:33Z")

</div>

> [@nathank](#):
>
> [Locations Plugin 🌍](https://meta.discourse.org/t/locations-plugin/69742) 确实具备此类功能，但仅能与替代方案 [Events Plugin 📅](https://meta.discourse.org/t/events-plugin/69776) 集成。

我一直在尝试查看那个 Events 插件，但在以下步骤卡住了：

> [@angus](#):
>
> 1. [获取订阅并授权您的论坛](https://discourse.angus.blog/t/getting-a-subscription-and-authorizing-your-forum/55)。

因为该网站已经宕机好几个月了。

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [2026年六月8日 08:41 UTC](https://meta.discourse.org/t/discourse-events/97376/601 "2026-06-08T08:41:50Z")

</div>

也许值得在 #Contribute > Feature（标记为 #calendar-and-events）中提交一份正式的功能请求以供考虑。我可以想象这是一件可行的事情——而且它有很高的潜力为许多人带来高价值。

* * *

_稍后……_  
@lou 确实已经在这里这样做了：

> [@支持活动地点地图](https://meta.discourse.org/t/event-location-map-support/404734):
>
> 我希望在事件中添加一个地点查找功能，类似于 Google 日历或 Facebook 事件中的做法：a) 帮助用户选择地点；b) 使地点可点击并跳转到地图应用。 这将有助于我们从 Facebook 群组迁移到 Discourse 论坛。

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [2026年六月9日 05:08 UTC](https://meta.discourse.org/t/discourse-events/97376/602 "2026-06-09T05:08:16Z")

</div>

一篇帖子已合并到现有主题中：[事件位置地图支持](https://meta.discourse.org/t/event-location-map-support/404734/2)

---

<div class="post-metadata">

### Author: ![Lou](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lou/32/544605_2.png) [@Lou](https://meta.discourse.org/u/Lou)
#### Post date: [2026年六月28日 19:19 UTC](https://meta.discourse.org/t/discourse-events/97376/604 "2026-06-28T19:19:45Z")

</div>

我计划使用某个 WordPress 插件将公开活动导出到 WordPress 网站，该插件能够读取来自 /discourse-post-event/events.ics 的 iCal 订阅源。到目前为止一切顺利。

该网站上有一些页面希望显示这些活动中的子集，每个页面需要展示不同的子集。

我曾希望能为活动打上与每个页面对应的标签，这样这些标签会出现在 iCal 文件的 CATEGORIES 行中，从而允许按目标页面进行筛选，但似乎并未实现这一功能。

我也愿意在 URL 中使用 ?tag=[tag] 参数，并让不同页面使用不同的 URL，不过根据我查阅的资料，这似乎并不是一项现有功能。

是否有我忽略的地方？

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [2026年七月2日 01:51 UTC](https://meta.discourse.org/t/discourse-events/97376/605 "2026-07-02T01:51:01Z")

</div>

不，你没有遗漏任何内容（据我所知）。

能够按类别和/或标签筛选日历 .ics 源确实是一个值得提出的 #Contribute > Feature 请求！

---

<div class="post-metadata">

### Author: ![Lou](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lou/32/544605_2.png) [@Lou](https://meta.discourse.org/u/Lou)
#### Post date: [2026年七月5日 19:10 UTC](https://meta.discourse.org/t/discourse-events/97376/606 "2026-07-05T19:10:46Z")

</div>

我最终不得不自己构建标签过滤器，但我了解到“已过期”的事件不会通过 /discourse-post-event/events.ics 下载。我也没找到任何方法可以控制事件何时变为“已过期”。我可能不得不退而求其次，使用数据浏览器查询，而不是使用 /…/events.ics。

[不过，我觉得我找到了一个更好的方法，使用 /discourse-post-event/event 来实现]

---

<div class="post-metadata">

### Author: ![nicolsdennis](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nicolsdennis/32/545883_2.png) [@nicolsdennis](https://meta.discourse.org/u/nicolsdennis)
#### Post date: [2026年七月20日 14:01 UTC](https://meta.discourse.org/t/discourse-events/97376/608 "2026-07-20T14:01:18Z")

</div>

你好，我想就活动与音频及直播集成的某个方面征求反馈意见。请查看此处的最后回复 → [https://meta.discourse.org/t/discourse-desktop-mac-app/406912/10?u=nicolsdennis](https://meta.discourse.org/t/discourse-desktop-mac-app/406912/10?u=nicolsdennis)

---

<div class="post-metadata">

### Author: ![DrekkSama](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/drekksama/32/481386_2.png) [@DrekkSama](https://meta.discourse.org/u/DrekkSama)
#### Post date: [2026年七月23日 12:01 UTC](https://meta.discourse.org/t/discourse-events/97376/609 "2026-07-23T12:01:18Z")

</div>

有没有人成功将 [VDO.Ninja](https://vdo.ninja/) 集成到活动直播中？我看到了 Zoom 的集成方案，我在想是否有可能通过临时拼凑的方式将其替代 Zoom 🤔

---

<div class="post-metadata">

### Author: ![lindsey](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lindsey/32/318210_2.png) [@lindsey](https://meta.discourse.org/u/lindsey)
#### Post date: [2026年八月11日 16:15 UTC](https://meta.discourse.org/t/discourse-events/97376/610 "2026-08-11T16:15:54Z")

</div>

3 条帖子已拆分至新主题：[关于 Zoom 直播集成的问题](https://meta.discourse.org/t/questions-about-the-zoom-livestream-integration/409816)

---

<div class="post-metadata">

### Author: ![jesse\_mba\_commons](https://avatars.discourse-cdn.com/v4/letter/j/cab0a1/32.png) [@jesse\_mba\_commons](https://meta.discourse.org/u/jesse_mba_commons)
#### Post date: [2026年八月14日 11:33 UTC](https://meta.discourse.org/t/discourse-events/97376/611 "2026-08-14T11:33:19Z")

</div>

Discourse 日历/事件插件的“即将发生的事件”（Upcoming Events）路由似乎从初始服务器端渲染的 HTML 响应中省略了所有 Open Graph 和 Twitter 卡片元数据。

在托管的 Discourse 站点上可以复现此问题，其中普通页面能正确输出社交元数据，且已配置有效的站点 OpenGraph 图片。

受影响的路由示例：

`https://www.mbacommons.com/upcoming-events/month/2026/8/1`

**复现步骤**

1. 配置有效的站点 OpenGraph 图片。
2. 确认首页或普通主题在原始 HTML 中输出了正常的 Open Graph 元数据。
3. 打开 `/upcoming-events/month/2026/8/1`。
4. 检查原始 `view-source:` / 初始服务器响应，而非 JavaScript 执行后的 DOM。

**实际结果**

“即将发生的事件”路由返回 HTTP 200，但原始 HTML 中不包含：

- `og:image`
- `og:title`
- `og:description`
- `og:url`
- `twitter:card`
- `twitter:image`

我还使用 `LinkedInBot/1.0` 进行了测试，结果相同。

对该站点进行的原始 HTML 生产环境审计统计如下：

- 首页：11 个社交元数据标签
- 普通主题：14 个
- 即将发生的事件：0 个

首页和普通主题正确使用了已配置的站点 OpenGraph 图片，因此站点级别的 branding 配置本身是正常工作的。

**预期结果**

“即将发生的事件”路由应输出爬虫可见的、服务器端渲染的社交元数据，至少包括：

- `og:title`
- `og:description`
- `og:url`
- `og:image`，若未设置则回退到已配置的站点 OpenGraph 图片
- 对应的 Twitter 卡片元数据

这些元数据必须包含在初始 HTML 中，因为 LinkedIn 和类似的社交爬虫无法依赖客户端主题 JavaScript。

LinkedIn 帖子检查器当前报告：

`Add an og:image tag to the page to have control over the content's image on LinkedIn.`

全局主题 `head_tag` 注入似乎并不合适，因为普通页面已经具有正确的元数据，且这可能导致标签重复或冲突。这似乎需要对“即将发生的事件”路由进行路由感知的服务器端处理，或使用 Discourse 的标准社交元数据渲染路径。

---

<div class="post-metadata">

### Author: ![hellekin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/hellekin/32/51636_2.png) [@hellekin](https://meta.discourse.org/u/hellekin)
#### Post date: [2026年八月16日 13:06 UTC](https://meta.discourse.org/t/discourse-events/97376/612 "2026-08-16T13:06:22Z")

</div>

### 使用 Discourse 日历和活动进行 Peertube 直播

去年夏天（2025年），这在使用 [Peertube](https://joinpeertube.org) 时运行良好，当时在标记 `#livestream` 时，会提供与主题关联的聊天界面（使用 `/embed/xxx` 视频 URL 来显示直播视频，并考虑到 Peertube 中 P2P 传输导致的约 30 秒延迟）。

但我今天再次尝试时，聊天界面似乎没有像以前那样嵌入到布局中（至少在我的记忆中是这样的）。此外，活动界面上也没有“直播按钮”。这是正常的吗？

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [2026年八月18日 05:52 UTC](https://meta.discourse.org/t/discourse-events/97376/613 "2026-08-18T05:52:51Z")

</div>

你看过[最近更新的说明](https://meta.discourse.org/t/discourse-calendar-and-events/97376#p-473517-creating-a-livestream-event-10)吗？我觉得在把这些功能整合到这个插件后，界面可能有一些变化。

[上一頁](https://meta.discourse.org/t/discourse-events/97376.md?page=7)

[下一頁](https://meta.discourse.org/t/discourse-events/97376.md?page=9)
