No aparecen errores en la consola. Sin embargo, he grabado un video de referencia.
Esto ocurre en Chrome, Firefox y Safari. En Safari móvil no sucede.
¡Tu enlace al video está roto!
Perdona, no lo había entendido bien. En efecto, tienes razón: al hacer clic en una fecha del calendario, se abre el modal de creación de evento, pero con el botón «¿Quieres abandonar?». Sí, en efecto, hay un pequeño error ![]()
Para su información, de mi parte he añadido un botón de +info para mis usuarios que no piensan hacer clic en el título para acceder al tema. He retomado la idea de @nathank sobre su botón «Añadir al calendario».
Coloque el script en un componente de tema, en la sección general /head
<script>
(() => {
const eventInfoSelector = ".event-header .event-info";
const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";
// CSS inyectado limpio y adaptado a los temas de Discourse (Claro/Oscuro)
const style = document.createElement("style");
style.innerHTML = `
.custom-topic-info-btn {
display: flex !important;
align-items: center;
justify-content: center;
width: 40%; /* Ocupa todo el ancho para un aspecto limpio bajo el título */
box-sizing: border-box;
margin: 12px 0 6px 0;
padding: 10px 16px;
/* Uso de variables nativas de Discourse */
background-color: var(--tertiary) !important; /* Color de acento (ej. azul) */
color: var(--secondary) !important; /* Color de texto con contraste */
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;
}
/* Efecto al pasar el cursor */
.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);
}
/* Efecto al hacer clic */
.custom-topic-info-btn:active {
transform: translateY(0);
}
/* Estilo del icono 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 = "Ver el tema completo";
button.href = topicUrl;
// Añadir un icono de información SVG armonizado
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">Más info</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>
Aquí tiene una vista previa
o bien
este código
<script>
(() => {
const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";
// CSS inyectado para un aspecto limpio y moderno
const style = document.createElement("style");
style.innerHTML = `
.custom-topic-info-wrapper {
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid var(--primary-low); /* Línea de separación sutil */
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;
/* Estilo Outline elegante */
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;
}
/* Efecto al pasar el cursor: el botón se rellena */
.custom-topic-info-btn:hover {
background-color: var(--tertiary) !important;
color: var(--secondary) !important;
border-color: var(--tertiary) !important;
}
/* Alineación del icono de información */
.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 = "Consultar el tema completo";
button.href = topicUrl;
// Icono "i" de información + Nuevo texto accionable
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">Consultar el tema</span>
`;
wrapper.appendChild(button);
/* Posicionamiento encima de las opciones de respuesta (Participará, 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>
Vista previa del resultado
Tiene la opción de elegir ![]()
¡Realmente han mejorado la facilidad para crear un evento desde las últimas actualizaciones ![]()
Pero quería saber si existe una configuración que impida crear un evento cuando un usuario hace clic en el calendario. A veces, en lugar de hacer clic en el evento, hace clic al lado, lo que abre un modal para crear un evento ![]()
Gracias
Sé que soy pesado, pero tengo otra pregunta o sugerencia sobre los eventos expirados. Podrían eliminarse automáticamente, ya que ya no tienen interés en estar presentes; me parece que el plugin de eventos lo hacía automáticamente.
Actualmente, lo hago manualmente, así que si hay alguna forma de ahorrar tiempo ![]()
Gracias al equipo.
¿Existe alguna forma de que la ubicación en el evento realice una búsqueda, como se hace en Google Calendar o en los eventos de Facebook, a) para ayudar al usuario a seleccionar la ubicación y b) para que la ubicación sea clicable y abra una aplicación de mapas?
(No pude encontrar ninguna solución buscando, pero quizás mis consultas de búsqueda no fueron adecuadas)
El Locations Plugin 🌍 sí tiene ese tipo de funcionalidad, pero solo se integra con la alternativa Events Plugin 📅.
El desarrollador (@merefield) podría estar dispuesto a integrarlo con el plugin oficial, pero imagino que sería bastante trabajo establecerlo y mantenerlo, por lo que definitivamente necesitarías patrocinar el trabajo para que esto ocurra.
He estado intentando revisar ese plugin de eventos, pero me he quedado atascado en
ya que el sitio lleva meses fuera de línea.
Podría valer la pena presentar una solicitud formal de función en Contribute > Feature (etiquetada como calendar-and-events) para su consideración. Puedo imaginar que sería algo viable y que tiene el potencial de ser de gran valor para muchos.
más tarde…
@lou efectivamente lo ha hecho aquí:
Se ha fusionado una publicación en un tema existente: Soporte para mapa de ubicación de eventos
Planeo exportar los eventos públicos a un sitio web de WordPress utilizando algún plugin de WordPress que sepa cómo leer el feed ics de /discourse-post-event/events.ics. Hasta ahora, todo bien.
Hay algunas páginas en este sitio web que querrían mostrar un subconjunto de estos eventos; cada página quiere mostrar un subconjunto diferente.
Esperaba poder etiquetar los eventos con una etiqueta asociada a cada página, para que esto apareciera en la línea CATEGORIES del archivo ics y permitiera filtrar por destino, pero parece que eso no está ocurriendo.
Estaría dispuesto a usar ?tag=[tag] en la URL y hacer que las diferentes páginas usen URLs distintas, aunque no he encontrado que esto sea una característica al leer lo que pude encontrar.
¿Hay algo que no esté considerando?
No, no te estás perdiendo nada (que yo sepa).
¡La capacidad de filtrar la fuente .ics del calendario por categoría y/o etiqueta sería una solicitud de Contribute > Feature digna de mención!
Al final, me he visto obligado a crear mi propio filtro de etiquetas, pero creo que he descubierto que los eventos “caducados” no se descargan a través de /discourse-post-event/events.ics. Tampoco veo ninguna forma de controlar cuándo un evento se considera “caducado”. Tal vez tenga que recurrir a realizar una consulta en Data Explorer en lugar de usar /…/events.ics
[aunque creo que he encontrado una mejor manera de hacerlo usando /discourse-post-event/event ]
Hola, busco comentarios sobre un aspecto relacionado con la integración de eventos con audio y transmisión en vivo. Ve la última respuesta aquí → https://meta.discourse.org/t/discourse-desktop-mac-app/406912/10?u=nicolsdennis
¿Alguien ha tenido éxito al implementar VDO.Ninja en la transmisión en vivo de eventos? Veo la integración con Zoom y pienso que podría haber una manera de improvisar una solución para usarlo en lugar de Zoom ![]()
3 mensajes se dividieron en un nuevo tema: Preguntas sobre la integración de Zoom Livestream
Las rutas de Próximos eventos del calendario/eventos de Discourse parecen omitir todos los metadatos de Open Graph y Twitter Card de la respuesta HTML inicial renderizada por el servidor.
Esto es reproducible en un sitio Discourse alojado donde las páginas normales emiten correctamente metadatos sociales y se ha configurado una imagen OpenGraph válida del sitio.
Ejemplo de ruta afectada:
https://www.mbacommons.com/upcoming-events/month/2026/8/1
Pasos para reproducir
- Configura una imagen OpenGraph válida del sitio.
- Confirma que la página de inicio o un tema normal emite metadatos Open Graph normales en el HTML sin procesar.
- Abre
/upcoming-events/month/2026/8/1. - Inspecciona la fuente del código (
view-source:) / la respuesta inicial del servidor, no el DOM posterior a la ejecución de JavaScript.
Resultado actual
La ruta de Próximos eventos devuelve HTTP 200, pero el HTML sin procesar contiene:
- ninguna
og:image - ninguna
og:title - ninguna
og:description - ninguna
og:url - ninguna
twitter:card - ninguna
twitter:image
También probé usando LinkedInBot/1.0; el resultado es idéntico.
Una auditoría de producción de HTML sin procesar en el mismo sitio contó:
- página de inicio: 11 etiquetas de metadatos sociales
- tema normal: 14
- Próximos eventos: 0
La página de inicio y los temas normales utilizan correctamente la imagen OpenGraph configurada del sitio, por lo que la configuración de marca a nivel de sitio funciona correctamente.
Resultado esperado
Las rutas de Próximos eventos deberían emitir metadatos sociales visibles para los rastreadores y renderizados por el servidor, que incluyan al menos:
og:titleog:descriptionog:urlog:image, con la imagen OpenGraph configurada del sitio como valor predeterminado- metadatos correspondientes de Twitter Card
Esto debe estar presente en el HTML inicial porque LinkedIn y rastreadores sociales similares no pueden depender del JavaScript del tema del lado del cliente.
El Inspector de publicaciones de LinkedIn informa actualmente:
«Añade una etiqueta og:image a la página para controlar la imagen del contenido en LinkedIn.»
Una inyección global de head_tag en el tema no parece apropiada porque las páginas normales ya tienen metadatos correctos y podría crear etiquetas duplicadas o en conflicto. Esto parece requerir un manejo del lado del servidor consciente de la ruta para Próximos eventos o el uso de la ruta de renderizado de metadatos sociales normal de Discourse.
Peertube Live con el Calendario y Eventos de Discourse
Esto funcionaba perfectamente con Peertube el verano pasado (2025), proporcionando la interfaz de chat con el tema (usando la URL de vídeo /embed/xxx para mostrar la transmisión en directo y teniendo en cuenta el retraso de ~30s debido al P2P en Peertube) al etiquetar con #livestream.
Pero lo he vuelto a probar hoy y el chat no parece estar integrado en el diseño como solía hacerlo (al menos según mi recuerdo). Además, no hay ningún «botón de transmisión en directo» en la interfaz de eventos. ¿Es esto normal?
¿Has visto las instrucciones actualizadas recientemente? Creo que la interfaz de usuario podría haber cambiado un poco cuando todo se integró en este plugin.

