¿Cómo personalizar el texto en una publicación incrustada?

Tengo un sitio donde publico varios tutoriales y blogs, y utilizo Discourse tanto como foro como para comentarios utilizando la función de incrustación.

Esto funciona muy bien la mayor parte del tiempo, excepto que cuando creo una nueva página en el sitio principal, todo el contenido se incluye en la publicación de Discourse. ¡Algunos de mis usuarios ni siquiera conocen el sitio principal, porque siempre leen la publicación completa en el foro! Lo cual es un problema porque funciones como los editores de código incrustados no funcionan en Discourse, por lo que la experiencia parece defectuosa.

En un mundo perfecto, la publicación de Discourse sería solo un enlace corto y muy obvio a la publicación original en la página principal. Quizás algo como esto:

Ver la publicación original aquí:

https://example.com

¡Las respuestas a este hilo se mostrarán como comentarios en la publicación original!

He intentado deshabilitar la configuración embed truncate como se describe en este hilo, pero eso parece ocultar el botón “mostrar publicación completa” pero aún muestra todo el contenido en la publicación.

También he intentado editar el mensaje embed.imported_from, pero eso solo cambia el texto pequeño en la parte inferior que la gente parece estar perdiendo de todos modos.

También he intentado editar la publicación manualmente después de que Discourse la crea, pero el markdown no se renderiza en HTML y se muestra como texto sin formato. Esto suena similar a este problema: Customizing the "Embedding" Behavior by Disabling Show Full Post?

¿Hay alguna configuración que me esté perdiendo, o algún otro truco que pueda usar para personalizar el texto en una publicación de Discourse generada automáticamente? ¿Quizás algo que pueda incluir en el HTML del sitio principal para engañar a Discourse para que muestre lo correcto? O no me importa editarlo manualmente, si hay una manera de solucionar el problema de renderizado de markdown.

¡Gracias por cualquier ayuda que puedan ofrecer!

1 me gusta

Disculpe la interrupción, ¡pero estaría muy agradecido si alguien tuviera alguna idea para que la pruebe!

Hola Kevin, ¿puedo confirmar si estás usando el plugin WP Discourse o un embed de javascript?

1 me gusta

¡Gracias por la respuesta! Estoy usando la incrustación de JavaScript. Por ejemplo, tengo esta página:

Que contiene este código de incrustación:

<script type="text/javascript">
DiscourseEmbed = { discourseUrl: location.protocol 
	+ '//forum.happycoding.io/',
	discourseEmbedUrl: location.protocol + '//happycoding.io/tutorials/javascript/react-css' };
	
(function() {
	var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
	d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
	(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
})();
</script>

Eso crea esta publicación en mi Discourse:

https://forum.happycoding.io/t/css-in-react/1092

Y si haces clic en eso, verás que la publicación contiene el texto completo de la página original.

Gracias por la aclaración.

¿Por qué tienes habilitada la configuración del sitio embed truncate en Discourse? Estoy un poco confundido, ya que mencionas que la has deshabilitado, pero también dices que tu problema es

La configuración de embed truncate está ahí en parte por esta misma razón. Significa que el usuario solo verá un extracto parcial de la publicación en Discourse.

¿Podrías explicar un poco más qué comportamiento específico del usuario estás tratando de evitar y qué comportamiento específico del usuario estás tratando de fomentar?

1 me gusta

He ido y venido con la configuración de embed truncate. Mirándolo de nuevo ahora, supongo que habilitarla es marginalmente mejor, pero todavía espero una forma de evitar mostrar el texto completo del artículo original en Discourse en absoluto. En otras palabras, no quiero ocultar el texto completo tras hacer clic en un botón, sino que nunca quiero mostrar el texto completo, solo un enlace al artículo original.

El comportamiento que intento evitar es que los usuarios lleguen a mi Discourse y lean el artículo completo en Discourse, en lugar de en la página original. Esto es un problema porque el texto completo en Discourse a menudo contiene errores (con JS interactivo, código incrustado, etc.), y luego recibo informes de errores donde la solución es dejar de leer en Discourse e ir al sitio “real” en su lugar.

En otras palabras, el comportamiento del usuario que intento fomentar es leer el artículo completo en la página original, en lugar de en la publicación de Discourse.

Esto puede parecer menor (y en el gran esquema de las cosas lo es), pero mi temor es que los usuarios lleguen a mi Discourse, piensen que el comportamiento de la página tiene errores y se vayan antes de darse cuenta de que hay una página en mi sitio “real” que deberían estar leyendo en lugar de Discourse.

Algunas opciones posibles que he considerado:

  • ¿Hay alguna configuración que le diga a Discourse que incluya solo un enlace y no incluya nada del artículo original?
  • ¿Hay alguna clase CSS u otro atributo que pueda agregar a mi HTML original para indicar qué parte del artículo debe incluirse (o excluirse) en la publicación de Discourse?
  • ¿Quizás podría agregar CSS personalizado a Discourse para ocultar el botón Show Full Post...?

Gracias por la explicación, Kevin. No hay configuraciones dirigidas específicamente a este problema, pero hay dos maneras de abordarlo.

Personalizar qué HTML se extrae de tu sitio

La forma en que funcionan las incrustaciones es que extraen el contenido de un sitio usando el gem Readability. El gem y su salida utilizan las siguientes opciones para filtrar qué HTML se extrae.

opts[:whitelist] = SiteSetting.allowed_embed_selectors if SiteSetting.allowed_embed_selectors.present?
opts[:blacklist] = SiteSetting.blocked_embed_selectors if SiteSetting.blocked_embed_selectors.present?
allowed_embed_classnames = SiteSetting.allowed_embed_classnames if SiteSetting.allowed_embed_classnames.present?

Por lo tanto, podrías configurar los ajustes del sitio allowed_embed_selectors, blocked_embed_selectors o allowed_embed_classnames para restringir qué contenido se extrae de tu HTML y se muestra en la publicación de Discourse, por ejemplo, podrías restringirlo a clases inexistentes para que no se extraiga ningún contenido.
El contenido extraído del sitio luego tiene este HTML agregado:

"\n<hr>\n<small>#{I18n.t('embed.imported_from', link: \"<a href='#{url}'>#{url}</a>\")}</small>\n"

Así que solo necesitarías personalizar el texto embed.imported_from en el panel de administración para indicarle al usuario que lea el contenido en el blog. Ten en cuenta que puedes interpolar el enlace al contenido en ese texto, por ejemplo, la versión en inglés del texto de la localización es

Este es un tema de discusión complementario para la entrada original en %{link}

Ocultar el botón Mostrar publicación completa

Como sugeriste, ocultar el botón Mostrar publicación completa con CSS también debería funcionar.

2 Me gusta

Me cuesta entender por qué no hay una opción para personalizar el texto incrustado completo. No quiero extraer ningún contenido real de la URL incrustada, sino simplemente tener un enlace a ella con una breve descripción (por ejemplo, solo el resumen meta).

Ahora hago esto con una llamada API automatizada, pero quiero cambiar a la función de incrustación nativa.

Intenté crear un elemento oculto en el sitio extraído específicamente para Discourse para extraer solo ese único elemento, pero la desventaja es que el onebox no se mostrará para el enlace.

Personalizar embed.imported_from también tiene sus limitaciones, ya que siempre se inserta en una etiqueta <small> que no permite ninguna personalización real.

Parece que no quieres una incrustación, que es, por su naturaleza, la “incrustación” de contenido de otro lugar.

¿Por qué quieres cambiar?

Es cierto, solo quiero una creación automática de hilos cada vez que se publica un nuevo artículo de blog.

Sin embargo, también quiero usar la función nativa de incrustación de JS para mostrar comentarios debajo de la publicación del blog en el sitio web externo, lo que también viene con el comportamiento de incrustación en el foro.

Mi automatización actual tiene un pequeño retraso (no en tiempo real), e implementar una creación automática de hilos en nuestro CMS cada vez que se publica un nuevo artículo es un poco más difícil, ya que no es solo un CMS de blog y ni siquiera hay un evento de “publicación” distinto.

En cualquier caso, habrá colisiones entre la incrustación de JS que intenta crear el hilo y mi automatización, siendo la primera probablemente más rápida la mayor parte del tiempo. Es por eso que quiero “cambiar” a solo usar la función de incrustación de JS, con la desventaja de que los hilos deben editarse manualmente cada vez.

¡Estaré encantado de escuchar sugerencias! :smile:

Gracias por la explicación.

Ok, si te entiendo correctamente:

  1. Quieres la funcionalidad de creación de temas y vinculación de comentarios de los incrustados de JS; y
  2. Quieres solo un enlace con una breve descripción en la primera publicación del tema enlazado en Discourse.

¿Es correcto? Para el punto 2, ¿has probado la configuración del sitio embed truncate? Si lo has hecho, ¿qué es lo que no te gustó? Entiendo que ya lo has mencionado un poco en tu primera respuesta, sin embargo, ¿podrías explicar específicamente con qué estás teniendo problemas? Quizás dar un ejemplo de lo que te impide lograr tu resultado deseado (y cuál es exactamente ese resultado deseado).

1 me gusta

Sí, lo haces.

El problema se reduce a la previsualización de enlaces (link onebox), que no se muestra porque el contenido incrustado siempre se envuelve en etiquetas HTML. :smiley:

Sé que esto suena a un detalle menor (y lo es), pero la molestia en la calidad de vida de tener que editar esto manualmente para cada artículo es significativa y algo que quería solucionar desde hace mucho tiempo.

Así es como quiero que se vea (usando un ejemplo de publicación de blog de Discourse):

Actualmente, tendría que manipular elementos ocultos en el sitio web para poder extraer específicamente la URL y el resumen, e incluso entonces, el problema es que la previsualización de enlace no se muestra. Lo único que puedo personalizar más o menos por completo es la parte “Leer la publicación completa del blog…” en la parte inferior.

Supongo que lo que pido es la capacidad de agregar algo al fragmento de JS como esto:

DiscourseEmbed = {
    discourseUrl: 'https://forum.example.com/',
    discourseEmbedUrl: 'https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks',
    discourseRaw: 'https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks\n\nEstamos encantados de compartir la migración de la comunidad de Spiceworks a Discourse. El equipo de Spiceworks ha trabajado en estrecha colaboración con nuestro equipo de migración\n\n<small>Lee la publicación completa del blog en <a href="https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks/">discourse.org</a>. Esta publicación se ha creado automáticamente y las respuestas se mostrarán en el sitio web.</small>'
};

discourseEmbedRaw siendo equivalente al valor raw en una solicitud de API normal a /posts.json.

Pero entiendo que este podría ser un requisito de caso extremo y no es relevante para la mayoría de los usuarios. Supongo que intentaré solucionar esto creando los temas a través de la API antes de que el fragmento de JS intente hacerlo.

No te lo recomendaría.

Esto causaría varios problemas. Dejemos eso a un lado por ahora.

Aprecio que idealmente quieras tener control total sobre todo, sin embargo, ten paciencia mientras intento traducir tus necesidades en lo que podrían ser mejoras factibles al sistema actual. Ten en cuenta que estas son solo sugerencias y no tengo control sobre lo que el equipo de Discourse acepta.

Una publicación incrustada en Discourse se compone esencialmente de dos cosas:

  1. HTML “importado de” (es decir, el enlace)
  2. Contenido HTML de la página enlazada, ya sea completo o truncado.

1. Control sobre el HTML “importado de”

Actualmente, este HTML está codificado como

 "
<hr>
<small>#{I18n.t("embed.imported_from", link: "<a href='#{url}'>#{url}</a>")}</small>
"

Te gustaría personalizarlo para que sea, por ejemplo, solo la URL para que se convierta en un onebox. Creo que una mejora factible allí sería una configuración del sitio que simplemente cambie esto a “solo URL”, para que no tengas que permitir que los administradores ingresen HTML en algún lugar.

2. Control sobre el contenido HTML truncado

Ya puedes hacer esto. Simplemente configura el ajuste del sitio allowed embed classnames a un nombre de clase de un elemento que hayas utilizado para envolver el extracto que deseas en tu sitio, por ejemplo:

En Discourse

Configura estos ajustes del sitio:

  • embed truncate a false
  • allowed embed classnames a “discourse-excerpt”

En la página de tu blog


<div class="discourse-excerpt">
Nos complace compartir la migración de la comunidad Spiceworks a Discourse. El equipo de Spiceworks ha trabajado en estrecha colaboración con nuestro equipo de migración
</div>

3. Control sobre el orden del HTML “importado de” y el Contenido HTML

Si te entiendo correctamente, quieres que la parte “importado de” (por ejemplo, solo la URL) aparezca antes del contenido HTML (o contenido truncado). Nuevamente, la forma más sencilla de hacerlo sería una configuración booleana del sitio, algo como embed imported from above content.

Entonces, en resumen, si te entiendo correctamente, podrías lograr esto con la adición de dos nuevas configuraciones booleanas y algunos pequeños ajustes en la clase TopicEmbed. Notarás que todos estos cambios son en discourse/discourse mismo, ya que el procesamiento tiene que ocurrir allí.

Como mencioné anteriormente, estas son solo sugerencias sobre cómo lograría lo que quieres hacer. Para que estos, o algo similar, se lleven a cabo, necesitaría la aprobación del equipo de Discourse.

1 me gusta

¡Gracias por escribir esto! :+1:

Sí, eso es exactamente con lo que jugué, el problema es que el contenido estará envuelto en varias etiquetas HTML, por lo que el onebox no se activará. Intenté separar la URL con etiquetas <br> (para activar el onebox), pero cosas como esa parecen ser recortadas automáticamente.

Hmm, está bien, ¿por qué? :slight_smile:

Establecería el valor de embed_url, por supuesto.

Conseguir que tu URL de incrustación se convierta en un onebox es un problema aparte. Usa allowed embed classnames solo para establecer el extracto de texto como en mi ejemplo.

Porque estarás reinventando la rueda para intentar eludir lo que es realmente un problema de análisis de TopicEmbed. También abrirá un nuevo conjunto de problemas, como qué pasa si tu código no se ejecuta en el orden que esperas, por ejemplo, si hay una condición de carrera u otra excepción intermedia. Este tipo de problemas ocurren con relativa frecuencia con una mezcla de código en un sitio externo con el plugin WP Discourse. En resumen, no vale la pena.

Parece que te manejas bien con un código base :slight_smile: . Básicamente, necesitas hacer dos cambios sencillos en esta clase.

  1. Inserta una condición controlada por una configuración del sitio aquí
  1. Inserta otra condición controlada por una configuración del sitio aquí

Ni siquiera necesitarías construir la aplicación discourse. Simplemente escribe dos pruebas rspec primero, luego haz los cambios y, una vez que los consigas, haz un PR :slight_smile:

1 me gusta

Por si sirve de algo, esto es lo que terminé haciendo:

  1. En mi blog, tengo un <div> con un id de forum-excerpt, que está oculto con display:none pero contiene el HTML que me gustaría mostrar en la publicación de Discourse. (Lo hago usando algo de lógica Jekyll / Liquid, pero eso realmente no debería importar).

  2. En mi Discourse, establecí el selector CSS para los elementos que se permiten en las incrustaciones en #forum-excerpt. Aunque el div está oculto en mi página real, el contenido aparece en el foro.

  3. También desmarco Truncar las publicaciones incrustadas.

  4. En la sección CSS incrustado, le doy a .button una fuente más grande. Este es un pequeño cambio, pero hace que el botón para agregar un comentario sea más grande.

  5. También he personalizado el texto de embed.continue, embed.start_discussion y embed.imported_from, lo que cambia lo que aparece en la sección de comentarios de mi sitio web.

Esto significa que tengo control total sobre el HTML que aparece en la publicación del foro. El HTML que le doy es básicamente el equivalente a un OneBox: es una miniatura grande y un enlace a la publicación principal.

Esto funciona casi perfectamente para mí, ¡gracias atrasadas por la ayuda!

2 Me gusta

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.