Discourse Kalender und Veranstaltungen

Zu Ihrer Information: Ich habe für meine Benutzer, die nicht daran denken, auf den Titel zu klicken, um Zugriff auf das Thema zu erhalten, einen „Mehr Infos“-Button hinzugefügt. Ich habe die Idee von @nathank für seinen „Zum Kalender hinzufügen“-Button übernommen.

Fügen Sie das Skript in einem Theme-Komponenten im allgemeinen /head-Bereich ein

<script>
(() => {
    const eventInfoSelector = ".event-header .event-info";
    const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";
    // Sauberer, an Discourse-Themen (Hell/Dunkel) angepasster CSS-Einbau
    const style = document.createElement("style");
    style.innerHTML = `
    .custom-topic-info-btn {
        display: flex !important;
        align-items: center;
        justify-content: center;
        width: 40%; /* Nimmt die gesamte Breite ein für ein sauberes Erscheinungsbild unter dem Titel */
        box-sizing: border-box;
        margin: 12px 0 6px 0;
        padding: 10px 16px;
        
        /* Nutzung nativer Discourse-Variablen */
        background-color: var(--tertiary) !important; /* Akzentfarbe (z. B. Blau) */
        color: var(--secondary) !important;          /* Kontrastreiche Textfarbe */
        
        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;
    }
    /* Hover-Effekt */
    .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);
    }
    /* Klick-Effekt */
    .custom-topic-info-btn:active {
        transform: translateY(0);
    }
    /* Stil des SVG-Symbols */
    .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 = "Vollständiges Thema ansehen";
        button.href = topicUrl;
        
        // Hinzufügen eines harmonisierten SVG-Infosymbols
        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">Mehr Infos</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>

Hier ist die Vorschau

oder alternativ

dieser Code hier

<script>
(() => {
    const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";

    // CSS-Einbau für ein sauberes und modernes Erscheinungsbild
    const style = document.createElement("style");
    style.innerHTML = `
    .custom-topic-info-wrapper {
        margin-top: 16px;
        padding-top: 16px;
        border-top: 1px solid var(--primary-low); /* Subtile Trennlinie */
        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;
        
        /* Eleganter Outline-Stil */
        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;
    }

    /* Hover-Effekt: Der Button füllt sich */
    .custom-topic-info-btn:hover {
        background-color: var(--tertiary) !important;
        color: var(--secondary) !important;
        border-color: var(--tertiary) !important;
    }

    /* Ausrichtung des Informationssymbols */
    .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 = "Vollständiges Thema konsultieren";
            button.href = topicUrl;
            
            // Info-Symbol „i“ + neuer, handlungsorientierter Text
            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">Thema konsultieren</span>
            `;

            wrapper.appendChild(button);

            /* Positionierung über den Antwortoptionen (Teilnehmen, etc.) */
            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>

Vorschau des Ergebnisses

Sie haben die Wahl :rofl:

3 „Gefällt mir“