Com a troca de esquema de cores (automática) disponível, estou me perguntando se também poderia haver alguma maneira de alternar entre os modos claro e escuro do Discourse quando incorporado como comentários em um blog. Especificamente, meu blog Ghost possui um alternador que os usuários podem clicar para mudar manualmente entre os modos claro e escuro. Sei que o CSS do meu blog não pode afetar o CSS dentro do iframe do Discourse, mas com essa nova adição, poderia haver outra maneira de o alternador também mudar o esquema de cores do Discourse? Você pode ver um exemplo de post com comentários na parte inferior deste post.
Isso é potencialmente viável, mas um pouco complicado. No momento, não adicionamos a troca automática do modo escuro ao endpoint de comentários incorporados. Podemos adicionar isso, e funcionaria se o seu site Ghost estivesse alternando automaticamente para o modo escuro quando o navegador muda para o modo escuro. Mas, pelo que pude perceber, o seu site Ghost usa um botão de modo escuro, o que não funcionará com a implementação do Discourse.
O que você pode fazer no seu caso específico é alternar uma classe no iframe de comentários incorporados do Discourse ao clicar no botão e, em seguida, usar essa classe para alternar as cores no seu estilo incorporado.
Parece bom. Enquanto estou montando vários temas (Ghost) que utilizam modo escuro para colegas meus, todos os quais compartilharão uma única instância do Discourse, isso ainda está um pouco mais adiante no futuro.
Infelizmente, não entendi muito bem o que você está sugerindo aqui. Atualmente, todos os elementos que quero estilizar com modo escuro dentro do meu blog têm seu CSS duplicado ao preceder esses itens com body.dark. Ou seja:
p {
color: #000;
}
body.dark p {
color: #FFF;
}
Você está sugerindo que eu use esse código body.dark para alterar coisas no iframe do Discourse? Porque tentei inserir o seguinte no campo de CSS Incorporado do Discourse, o que, infelizmente, não teve efeito:
.FF2F-discourse p {
color: #000;
}
body.dark .FF2F-discourse p {
color: #FFF;
}
Dito isso, você está sugerindo que eu tenha algum JS separado escrito para que o botão alterne uma mudança específica ao direcionar uma classe dentro do iframe? Porque, como mencionei no meu comentário anterior, eu não achava que código externo pudesse afetar CSS dentro de um iframe, daí minha confusão. Mas sou apenas um amador em HTML/CSS, então sem dúvida você sabe mais do que eu e/ou estou entendendo algo errado.
Sim, é isso que estou sugerindo. As folhas de estilo do seu blog não podem ser aplicadas ao iframe, mas você pode usar JS para alternar a classe dark no elemento html ou body do iframe e, em seguida, atualizar sua folha de estilo incorporada do Discourse de acordo.
Encontrei duas páginas explicando como alternar entre os modos claro e escuro para o embed do Discourse, mas o desenvolvedor que escreve meu JS está se perguntando se o método que você está sugerindo envolve o uso de postMessage (como as páginas que encontrei afirmam) ou algo diferente.
Aqui está uma página explicando como implementar comunicação entre janelas com postMessage:
Já esta outra é, na verdade, um tutorial sobre como alterar o CSS dentro de um iframe via postMessage, especificamente para alternar entre os modos claro e escuro:
Desculpe desenterrar um tópico tão antigo, mas há planos para implementar a troca automática de modo escuro para o endpoint de comentários incorporados?
No momento, não temos planos de adicionar esse recurso. Os sites podem adicionar estilos de modo escuro à sua folha de estilos incorporada como uma solução alternativa (ou usar a técnica postMessage discutida acima).
O bloco de código ① adiciona um ouvinte de eventos no iframe incorporado do Discourse, que enviará uma mensagem para o meu site que contém o iframe incorporado do Discourse assim que o Discourse incorporado for carregado.
Quando meu site recebe a mensagem do Discourse incorporado, ele fará uma validação, como mostrado no bloco de código ②, e se aprovado, chamará a função setIframeStyle para definir o Discourse incorporado.
A função setIframeStyle, mostrada no bloco de código ③, passa o modo de cor, “dark” ou “light”, para o iframe chamando postMessage. Além disso, uma vez que o modo escuro é alternado, a função pode ser chamada para manter o Discourse incorporado com o mesmo modo de cor do meu site.
O bloco de código ④ permite que o Discourse incorporado possa processar a mensagem do modo de cor enviada do meu site. Aqui eu alterno o modo de cor trocando o nome da classe para a tag body.
Adicionalmente, os blocos de código ① e ④ são adicionados pela página de administração do Discourse, como abaixo:
Obrigado pelo esboço acima @mikeguo, isso foi maravilhosamente explicado!
Observe também que você precisa estar na versão mais recente do Discourse para realizar isso, a capacidade de cabeçalho incorporado foi adicionada apenas há alguns dias.
Posso confirmar que o método acima ainda funciona, mas teria sido bom não ter que digitar o código de uma captura de tela Então, aqui está ele, ligeiramente atualizado:
Passos
O iframe de comentários termina de renderizar e envia uma mensagem para a janela principal do navegador, informando isso.
O navegador consulta sua configuração de modo escuro/claro e envia o valor de volta para o iframe.
O iframe recebe a mensagem e define um atributo de dados, classe ou similar, com base na configuração de modo escuro/claro.
Código
Assim que o iframe for carregado, envie uma notificação para a janela pai. Isso precisa ser inserido no Discourse, em Admin -> Personalizar -> (selecionar tema) -> Editar CSS/HTML -> Cabeçalho Embutido.
Manipule este gatilho de entrada na janela principal. Este código fica no seu site de blog:
<script type="text/javascript">
const discourse_url = "https://your.discourse-instance.org";
// Aqui, determinamos o tema e enviamos uma mensagem para o iframe para informá-lo sobre o tema
// Veja abaixo como configuramos notifyFrameStyle
const notifyIFrameOfTheme = () => {
const iframe = document.getElementById("discourse-embed-frame");
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage(
{
// Modifique a linha abaixo para capturar a configuração do modo escuro, dependendo de como você a armazena
theme: document.documentElement.getAttribute("data-theme")
},
discourse_url
);
}
};
// Chama setFrameStyle quando recebemos a mensagem "iframe loaded"
const handleMessageListener = (event) => {
var origin = event.origin;
if ((origin === discourse_url) && (event.data == "iframe loaded")) {
notifyIFrameOfTheme();
}
};
</script>
No bloco <script> de (1), adicione um listener para a mensagem de tema enviada por notifyFrameStyle:
window.addEventListener("message", (event) => {
const payload = event.data;
if (payload.theme) {
// Faça algo com a configuração do tema; eu defino o atributo `data-theme` no `<html>` do iframe,
// mas você pode querer definir um atributo de classe ou similar
document.documentElement.setAttribute("data-theme", payload.theme);
}
}, false);
Estilização
Em Admin -> Personalizar -> (selecionar tema) -> Editar CSS/HTML -> CSS Embutido, você agora pode fornecer CSS para cada modo. Por exemplo, você pode substituir as variáveis de estilo do Discourse: