Adicione conteúdo personalizado que aparece apenas na sua página inicial

A very common situation you’ll find yourself in as a theme developer is the need to create content that only shows on the homepage of your community.

You might add some HTML to the “After Header” section of your theme, which will then appear on every page. You can jump through some hoops in CSS to hide this everywhere except the homepage… but instead let’s use a Discourse theme to create a component with content that is only visible on your homepage.

If you’re unfamiliar with Discourse themes check out Beginner's guide to using Discourse Themes and Structure of themes and theme components

In your Discourse theme you’ll need to setup the following directory structure:

:file_folder: javascripts/discourse/components/
:file_folder: javascripts/discourse/connectors/

From here we’re going to create an Ember component. You can find more about Ember components from their documentation: Ember.js Guides - Guides and Tutorials - Ember Guides

But for now this will be a simple component. The component will consist of two files, one containing the logic and another the template.

:page_facing_up: javascripts/discourse/components/custom-homepage-content.js

import Component from "@glimmer/component";
import { service } from "@ember/service";
import { defaultHomepage } from "discourse/lib/utilities";

export default class CustomHomepageContent extends Component {
  @service router;

  get isHomepage() {
    const { currentRouteName } = this.router;
    return currentRouteName === `discovery.${defaultHomepage()}`;
  }
}

This creates a isHomepage getter, which checks the router service for the currentRouteName — if the route name matches your homepage (as dictated by site settings) then it will return true

Now we need our template

:page_facing_up: javascripts/discourse/components/custom-homepage-content.hbs

{{#if this.isHomepage}}
  <h1>This is my homepage HTML content</h1>
{{/if}}

The template checks the isHomepage getter, and will display your content if it’s true. You can add any HTML you want between the {{#if}} blocks.

Now that our component is created, we need to add it to Discourse somewhere. For this step you’ll need to decide which plugin outlet to utilize. These are areas throughout Discourse where we’ve added a little code for developers to hook into. You can search Discourse for these on Github, or browse for them using the (deprecated) Plugin outlet locations theme component.

For custom homepages, above-main-container is a common choice, so let’s use that.

We need to create our connector file in the correct directory:

:page_facing_up: javascripts/discourse/connectors/above-main-container/custom-homepage-connector.hbs

<CustomHomepageContent />

:point_up: and that’s all, it just needs a single line calling for your component :tada:


This document is version controlled - suggest changes on github.

47 curtidas

Olá @awesomerobot,

Obrigado pela explicação. Tentei os passos que você sugeriu, mas o after_header que implementei ainda está aparecendo nas páginas de detalhes das postagens. Você pode recomendar como posso corrigir isso para que apareça apenas na minha página inicial?

1 curtida

Oi @Cornelius, posso ver seu código?

2 curtidas

Seria ótimo reescrever isso para o uso moderno do sistema de arquivos em vez de colocar tudo nas tags de cabeçalho.

A maioria desses guias antigos para temas está desatualizada em relação a como as coisas são feitas agora.

7 curtidas

Sim, isso estava bastante desatualizado! Atualizei para refletir a estrutura de temas remotos e nossos componentes Ember modernos.

6 curtidas

Isso é incrível!

E esse getter é a mesma coisa que isso http://ember-cli-page-object.js.org/docs/v1.11.x/api/getter.html? Eu sei o suficiente para ser perigoso. Se for o mesmo, então editarei o OP para vinculá-lo.

3 curtidas

@awesomerobot Olá Kris, instalei o Discourse localmente no meu sistema. Qual é o caminho correto para adicionar esses arquivos na minha instância local do Discourse? Eu queria adicionar um novo componente de tema na minha instância local do Discourse.

1 curtida

Você criaria seu componente de tema e o instalaria através do ux.

Instalar um tema ou componente de tema

Instalar o aplicativo de console Discourse Theme CLI para ajudá-lo a criar temas

4 curtidas

Se eu construir minha página inicial em cima da visualização de categoria, consequentemente ainda receberei meu conteúdo personalizado, mesmo que eu vá para /categories, que não é o URL inicial. Quero limitar isso apenas ao URL raiz /, que acredito ser o que o código anterior estava fazendo, mas me pergunto se defaultHomepage() deveria fazer isso.

3 curtidas

discovery.${defaultHomepage()} corresponderá à rota definida como rota de aterrissagem pela configuração top-menu. Ela corresponderá tanto à URL raiz / QUANTO à rota específica, como /categories.

Na minha experiência, há duas complicações ao construir uma página inicial personalizada com base em defaultHomepage():

  • a rota em que ela é construída não está mais disponível como uma visualização de lista simples
  • os membros podem definir sua própria página inicial padrão nas configurações de sua interface. Portanto, é preciso desativar esse recurso ou ter um conceito de página inicial que funcione em qualquer uma das rotas do menu superior

Para construir uma página inicial personalizada apenas na URL raiz, pode-se verificar router.currentURL === '/'. Por padrão, isso corresponde apenas à URL raiz / e não à rota de aterrissagem definida pela configuração do menu superior. No entanto, agora existe uma lógica nos links da barra lateral que também visa corresponder a uma determinada URL a uma rota. Portanto, por padrão, não funcionará nos links da barra lateral. Acabei de postar um tópico sobre isso: Posso ter links na barra lateral que não resolvem uma URL para uma rota?

Pelo que entendo, atualmente não há uma maneira padrão de construir uma página inicial personalizada na URL raiz sem direcionar também uma rota do menu superior ou ter problemas com a barra lateral. Seria ótimo ter essa opção.

4 curtidas

Certo, é um tipo de solução alternativa de longa data que / e a rota correspondente /route possam renderizar conteúdo diferente. Temos um “a fazer”:

  1. Permitir que a página inicial seja definida independentemente da configuração top_menu.
  2. Adicionar um novo modelo de página inicial autônomo que possa ser personalizado sem assumir uma rota existente.

Páginas iniciais personalizadas são uma solicitação muito comum neste momento, então certamente poderíamos usar mais flexibilidade aqui.

6 curtidas