Como personalizar o texto em uma postagem incorporada?

Tenho um site onde publico vários tutoriais e blogs, e uso o Discourse tanto como fórum quanto como comentários usando o recurso de incorporação.

Isso funciona muito bem na maioria das vezes, exceto que, quando crio uma nova página no site principal, todo o conteúdo é incluído na postagem do Discourse. Alguns dos meus usuários nem sequer sabem do site principal, porque eles sempre leem a postagem completa no fórum! O que é um problema, pois recursos como editores de código incorporados não funcionam no Discourse, então a experiência parece defeituosa.

Em um mundo perfeito, a postagem do Discourse seria apenas um link curto e muito óbvio de volta para a postagem original na página principal. Talvez algo como isto:

Veja a postagem original aqui:

https://example.com

Respostas a este tópico aparecerão como comentários na postagem original!

Tentei desativar a configuração embed truncate como descrito neste tópico, mas isso parece ocultar o botão “mostrar postagem completa”, mas ainda mostra todo o conteúdo na postagem.

Também tentei editar a mensagem embed.imported_from, mas isso apenas altera o pequeno texto na parte inferior que as pessoas parecem já estar perdendo.

Também tentei apenas editar a postagem manualmente depois que o Discourse a cria, mas o markdown não é renderizado em HTML e aparece como texto simples. Isso parece semelhante a este problema: Customizing the "Embedding" Behavior by Disabling Show Full Post?

Existe alguma configuração que estou perdendo, ou algum outro truque que posso usar para personalizar o texto em uma postagem do Discourse gerada automaticamente? Talvez algo que eu possa incluir no HTML do site principal para enganar o Discourse a mostrar a coisa certa? Ou não me oponho a editá-lo manualmente, se houver uma maneira de corrigir o problema de renderização do markdown.

Obrigado por qualquer ajuda que vocês possam oferecer!

1 curtida

Desculpe pelo ressurgimento, mas ficaria muito grato se alguém tivesse alguma ideia para eu tentar!

Olá Kevin, posso confirmar se você está usando o plugin WP Discourse ou um embed de JavaScript?

1 curtida

Obrigado pela resposta! Estou usando o embed do JavaScript. Por exemplo, tenho esta página:

Que contém este código de incorporação:

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

Isso cria esta postagem no meu Discourse:

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

E se você clicar nisso, verá que a postagem contém o texto completo da página original.

Obrigado pelo esclarecimento.

Por que você habilitou a configuração do site embed truncate no Discourse? Estou um pouco confuso, pois você menciona que a desativou, mas também diz que o seu problema é

A configuração de truncamento de incorporação existe em parte por esse exato motivo. Isso significa que o usuário verá apenas um trecho parcial da postagem no próprio Discourse.

Você poderia explicar um pouco mais qual comportamento específico do usuário você está tentando evitar e qual comportamento específico do usuário você está tentando incentivar.

1 curtida

Eu já mudei de ideia sobre a configuração embed truncate. Olhando novamente agora, acho que habilitá-la é marginalmente melhor, mas ainda espero uma maneira de evitar mostrar o texto completo do artigo original no Discourse. Em outras palavras, não quero esconder o texto completo atrás de um clique de botão - nunca quero mostrar o texto completo, apenas um link para o artigo original.

O comportamento que estou tentando evitar é que os usuários venham ao meu Discourse e leiam o artigo completo no Discourse, em vez da página original. Isso é um problema porque o texto completo no Discourse muitas vezes contém bugs (com JS interativo, código incorporado, etc.), e então recebo relatórios de bugs onde a solução é parar de ler no Discourse e ir para o site “real” em vez disso.

Em outras palavras, o comportamento do usuário que estou tentando incentivar é ler o artigo completo na página original, em vez da postagem do Discourse.

Isso pode parecer pequeno (e no grande esquema das coisas é), mas meu medo é que os usuários venham ao meu Discourse, pensando que o comportamento da página está com defeito, e saiam antes de perceberem que há uma página no meu site “real” que eles deveriam estar lendo em vez do Discourse.

Algumas opções possíveis que considerei:

  • Existe alguma configuração que diga ao Discourse para incluir apenas um link e não incluir nenhuma parte da postagem original?
  • Existe uma classe CSS ou outro atributo que eu possa adicionar ao meu HTML original para indicar qual parte do artigo deve ser incluída (ou excluída) na postagem do Discourse?
  • Talvez eu possa adicionar CSS personalizado ao Discourse para ocultar o botão Mostrar Postagem Completa...?

Obrigado pela explicação, Kevin. Não há configurações especificamente direcionadas a este problema, mas há duas maneiras de abordar isso.

Personalizar qual HTML é extraído do seu site

A forma como os embeds funcionam é que eles raspam o conteúdo de um site usando o gem Readability. O gem e sua saída usam as seguintes opções para filtrar qual HTML é raspado

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?

Portanto, você pode definir as configurações do site allowed_embed_selectors, blocked_embed_selectors ou allowed_embed_classnames para restringir qual conteúdo é extraído do seu HTML e exibido na postagem do Discourse, por exemplo, você poderia restringi-lo a classes inexistentes para que nenhum conteúdo fosse extraído.
O conteúdo raspado do site então tem este HTML anexado a ele:

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

Portanto, você só precisaria personalizar o texto embed.imported_from no painel de administração para dizer ao usuário para ler o conteúdo no blog. Note que você pode interpolar o link para o conteúdo nesse texto, por exemplo, a versão em inglês do texto local é

This is a companion discussion topic for the original entry at %{link}

Ocultar o botão Mostrar Postagem Completa

Como você sugeriu, ocultar o botão Mostrar Postagem Completa com CSS também deve funcionar.

2 curtidas

Tenho dificuldade em entender por que não há uma opção para personalizar todo o texto incorporado. Não quero extrair nenhum conteúdo real do URL incorporado, em vez disso, apenas ter um link para ele com uma breve descrição (por exemplo, apenas o resumo meta).

Atualmente, faço isso com uma chamada de API automatizada, mas quero mudar para o recurso de incorporação nativo.

Tentei criar um elemento oculto no site extraído especificamente para o Discourse extrair apenas esse único elemento, mas a desvantagem é que o onebox não será exibido para o link.

Personalizar o embed.imported_from também tem suas limitações, pois ele é sempre forçado em uma tag <small>, não permitindo nenhuma personalização real.

Parece que você não quer um embed, que é, por sua natureza, o “incorporamento” de conteúdo de outro lugar.

Por que você quer mudar?

Verdade, eu só quero uma criação automática de tópico sempre que um novo artigo de blog for publicado.

No entanto, também quero usar o recurso nativo de embed JS para mostrar comentários abaixo do post do blog no site externo, o que também vem com o comportamento de embed no fórum.

Minha automação atual tem um pequeno atraso (não em tempo real), e implementar uma criação automática de tópico em nosso CMS sempre que um novo artigo for publicado é um pouco mais difícil, pois não é apenas um CMS de blog e nem há um evento distinto de “publicação”.

Em qualquer caso, haverá colisões entre o embed JS tentando criar o tópico e minha automação, sendo o primeiro provavelmente mais rápido na maioria das vezes. É por isso que quero “mudar” para usar apenas o recurso de embed JS, com a desvantagem de os tópicos terem que ser editados manualmente a cada vez.

Ficarei feliz em ouvir sugestões! :smile:

Obrigado pela explicação.

Ok, se entendi corretamente:

  1. você quer a funcionalidade de criação de tópicos e vinculação de comentários dos embeds JS; e
  2. você quer apenas um link com uma breve descrição no primeiro post do tópico vinculado no Discourse.

Está correto? Para o item 2, você já tentou a configuração do site embed truncate? Se sim, o que não gostou nela? Entendo que você já abordou isso um pouco em sua primeira resposta, mas poderia explicar especificamente com o que está tendo dificuldades? Talvez dar um exemplo do que o impede de alcançar o resultado desejado (e qual é exatamente esse resultado desejado).

1 curtida

Sim, está.

O problema reside no onebox do link, que não é mostrado porque o conteúdo incorporado é sempre envolvido em tags HTML. :smiley:

Sei que isto parece um detalhe pequeno (e é), mas a desvantagem na qualidade de vida de ter de editar isto manualmente para cada artigo é significativa e algo que queria corrigir há muito tempo.

Como eu gostaria que ficasse (usando um exemplo de um post de blog do Discourse):

Atualmente, teria de mexer em elementos ocultos no website para conseguir extrair especificamente o URL e o resumo, e mesmo assim, o problema é o onebox não ser exibido. A única coisa que posso personalizar mais ou menos completamente é a parte “Leia o post completo…” na parte inferior.

Suponho que o que estou a pedir é a capacidade de adicionar algo ao snippet JS como isto:

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 entusiasmados por partilhar a mudança da comunidade Spiceworks para o Discourse! A equipa Spiceworks trabalhou em estreita colaboração com a nossa equipa de migração\n\n<small>Leia o post completo em <a href="https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks/">discourse.org</a>. Este post foi criado automaticamente e as respostas serão mostradas no website.</small>'
};

discourseEmbedRaw sendo equivalente ao valor raw num pedido regular da API para /posts.json.

Mas compreendo que isto possa ser um requisito de caso extremo e não seja relevante para a maioria dos utilizadores. Suponho que tentarei resolver isto criando os tópicos através da API antes que o snippet JS tente fazê-lo.

Eu não recomendaria isso.

Isso causaria vários problemas. Vamos deixar isso de lado por enquanto.

Agradeço que, idealmente, você queira controle total sobre tudo, mas tenha paciência enquanto tento traduzir suas necessidades em melhorias viáveis para o sistema atual. Tenha em mente que estas são apenas sugestões e eu não tenho controle sobre o que é aceito pela equipe do Discourse.

Um post incorporado no Discourse é essencialmente composto por duas coisas:

  1. HTML “importado de” (ou seja, o link)
  2. Conteúdo HTML da página vinculada, completo ou truncado.

1. Controle sobre o HTML “importado de”

Atualmente, este HTML é codificado como:

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

Você gostaria de personalizar isso para ser, por exemplo, apenas a URL para que ele se torne um onebox. Acho que uma melhoria viável seria uma configuração do site que simplesmente a alterasse para “apenas URL”, para que você não precisasse permitir que os administradores inserissem HTML em algum lugar.

2. Controle sobre o conteúdo HTML truncado

Você já pode fazer isso. Basta definir a configuração do site allowed embed classnames para um nome de classe de um elemento que você usou para envolver o trecho que deseja em seu site, por exemplo:

No Discourse

Defina estas configurações do site:

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

Na sua página de blog

<div class="discourse-excerpt">
Nós estamos felizes em compartilhar a migração da comunidade Spiceworks para o Discourse! A equipe Spiceworks trabalhou em estreita colaboração com nossa equipe de migração
</div>

3. Controle sobre a ordem do HTML “importado de” e o Conteúdo HTML

Se eu entendi corretamente, você quer que a parte “importado de” (por exemplo, apenas a URL) venha antes do conteúdo HTML (ou conteúdo truncado). Novamente, a maneira mais simples de fazer isso seria uma configuração booleana do site, algo como embed imported from above content.

Então, em resumo, se eu entendi corretamente, você poderia alcançar isso com a adição de duas novas configurações booleanas e alguns pequenos ajustes na classe TopicEmbed. Você notará que todas essas alterações são no discourse/discourse em si, pois o processamento tem que acontecer lá.

Como mencionei acima, estas são apenas sugestões de como eu alcançaria o que você deseja fazer. Para que estas, ou algo semelhante, sejam implementadas, seria necessário o acordo da equipe do Discourse.

1 curtida

Obrigado por anotar isso! :+1:

Sim, foi exatamente com isso que brinquei, o problema é que o conteúdo será envolvido em várias tags HTML, e é por isso que o onebox não será acionado. Tentei separar a URL com tags <br> (para acionar o onebox), mas coisas assim parecem ser aparadas automaticamente.

Hmm, ok, por quê? :slight_smile:

Eu definiria o valor de embed_url, é claro.

Obter seu URL de incorporação para onebox é um problema separado. Use allowed embed classnames apenas para definir o trecho de texto como no meu exemplo.

Porque você estará efetivamente reinventando a roda ao tentar contornar o que é realmente um problema de análise de TopicEmbed. Isso também abrirá um novo conjunto de problemas, como o que acontece se seu código não for executado na ordem esperada, por exemplo, se houver uma condição de corrida ou alguma outra exceção intermediária. Esses tipos de problemas acontecem com relativa frequência com uma mistura de código em um site externo com o plugin WP Discourse. Em resumo, não vale a pena.

Você parece entender de código :slight_smile: . Você efetivamente precisa fazer duas alterações simples nesta classe (esta classe).

  1. Insira uma condicional controlada por uma configuração do site aqui
  1. Insira outra condicional controlada por uma configuração do site aqui

Você nem precisaria construir o aplicativo discourse. Apenas escreva dois testes rspec primeiro, depois faça as alterações e, uma vez que os tenha funcionando, faça um PR :slight_smile:

1 curtida

Para que valha a pena, aqui está o que acabei fazendo:

  1. No meu blog, tenho uma <div> com um ID de forum-excerpt, que está oculta com display:none, mas contém o HTML que eu gostaria de mostrar na postagem do Discourse. (Eu faço isso usando alguma lógica Jekyll / Liquid, mas isso realmente não deve importar.)

  2. No meu Discourse, defini o Seletor CSS para elementos que são permitidos em incorporações para #forum-excerpt. Embora a div esteja oculta na minha página real, o conteúdo aparece no fórum.

  3. Eu também desmarco Truncar postagens incorporadas.

  4. Na seção CSS incorporado, dou à .button uma fonte maior. Esta é uma pequena mudança, mas torna o botão para adicionar um comentário maior.

  5. Eu também personalizei o texto embed.continue, embed.start_discussion e embed.imported_from, o que muda o que aparece na seção de comentários do meu site.

Isso significa que tenho controle total sobre o HTML que aparece na postagem do fórum. O HTML que eu forneço é basicamente o equivalente a um OneBox - é uma miniatura grande e um link para a postagem principal.

Isso funciona praticamente perfeitamente para mim, obrigado atrasado pela ajuda!

2 curtidas

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