Fazendo alterações personalizadas em um template bruto

Atualmente, nas nossas páginas de lista de tópicos, os avatares dos principais participantes em cada tópico são exibidos, juntamente com um link para a página de perfil do usuário. Isso pode ser visto aqui:


Quando um usuário não está conectado, este link não será clicável, pois, de outra forma, retornaria um redirecionamento para a página de login.

O problema é que nosso consultor de SEO determinou que isso é um problema para nós e quer que o link da página de perfil não seja visível para o Google.

Existem problemas semelhantes em coisas como posts de tópicos, mas todos eles estavam em widgets e foram relativamente fáceis de resolver com api.reopenWidge() e similares.

Não é assim com as páginas de lista de tópicos, onde precisamos alterar o conteúdo de raw-templates/list/posters-column.hbr!

Descreverei agora as coisas que tentei. Sinta-se à vontade para pular para o final, se preferir, e já souber a resposta.

No início, tentei montar um widget conforme as instruções do Guia para Iniciantes.

<td class='posters topic-list-data'>
    {{#each posters as |poster|}}
        {{#if poster.moreCount}}
            <a class="posters-more-count">{{poster.moreCount}}</a>
        {{else}}
          {{mount-widget widget="custom-list-avatar"}}
        {{/if}}
    {{/each}}
</td>

Nada disso pareceu fazer nada. Eventualmente, encontrei em um tema onde alguém estava usando uma extensão .raw no valor data-template-name, então assumo que o guia está desatualizado. Ele não dizia nada sobre templates raw! Usar .raw permite que as alterações acima sejam renderizadas, exceto que meu widget personalizado se recusou a carregar.

Isso é estranho, porque list/posters-column é referenciado apenas por topic-list-item.hbr, que também é um template raw, e é especificamente um dos templates usados nesse guia. Mas… novamente, acho que está desatualizado? Eventualmente, li em algum lugar que você não pode montar widgets em templates raw, então parece que isso nunca funcionaria.

Em seguida, descobri os partials e tentei usá-los. Achei que teria mais sorte, agora que essas partes não são um template raw.

<script type="text/x-handlebars" data-template-name="components/custom-avatar">
    <a href="{{poster.user.path}}" data-user-card="{{poster.user.username}}" class="{{poster.extraClasses}}">{{avatar poster avatarTemplatePath="user.avatar_template" usernamePath="user.username" namePath="user.name" imageSize="small"}}</a>
</script>

<script type="text/x-handlebars" data-template-name="list/posters-column.raw">
    <td class='posters topic-list-data'>
        {{#each posters as |poster|}}
            {{#if poster.moreCount}}
                <a class="posters-more-count">{{poster.moreCount}}</a>
            {{else}}
                {{partial 'components/custom-avatar'}}
            {{/if}}
        {{/each}}
    </td>
</script>

Infelizmente, parece que você também não pode usar partials em templates raw, então essa abordagem não deu certo.

Então, encontrei este tópico que parecia conter o que eu precisava. Com base nessa abordagem, e sabendo que list/topic-list-item (que chama list/posters-column) é usado pelo componente topic-list-item, cheguei ao seguinte:

<script type="text/x-handlebars" data-template-name="list/posters-column.raw">
    <td class='posters topic-list-data'>
        {{#each posters as |poster|}}
            {{#if poster.moreCount}}
                <a class="posters-more-count">{{poster.moreCount}}</a>
            {{else}}
                {{#if hideFromAnonUser}}
                    <div data-user-card="{{poster.user.username}}" class="{{poster.extraClasses}}">{{avatar poster avatarTemplatePath="user.avatar_template" usernamePath="user.username" namePath="user.name" imageSize="small"}}</div>
                {{else}}
                    <a href="{{poster.user.path}}" data-user-card="{{poster.user.username}}" class="{{poster.extraClasses}}">{{avatar poster avatarTemplatePath="user.avatar_template" usernamePath="user.username" namePath="user.name" imageSize="small"}}</a>
                {{/if}}
            {{/if}}
        {{/each}}
    </td>
</script>

<script type="text/discourse-plugin" version="1.1.0">
    const settings = Discourse.SiteSettings;
    const user = api.getCurrentUser();
    const hideFromAnonUser = settings.hide_user_profiles_from_public && !user;
    const topicListItemComponent = require('discourse/components/topic-list-item').default;
    topicListItemComponent.reopen({
        hideFromAnonUser: function() {
            return hideFromAnonUser
        }.property()
    });
</script>

Infelizmente, hideFromAnonUser nunca parece estar visível para o template raw. Talvez hideFromAnonUser precise ser calculado de dentro da função atribuída à chave hideFromAnonUser? Não parece importar. Mesmo que eu comente as três primeiras atribuições de const e apenas defina para retornar False, ou adicione uma chamada console.log() dentro dela antes da instrução de retorno, posso ver que a função nunca é executada por nada.

Neste ponto, estou perdido. Nunca tendo trabalhado com nada disso antes, sinto que estou em águas profundas. Talvez eu tenha negligenciado algo, mas parece que muita informação é enganosa ou desatualizada, ou estou olhando nos lugares errados, ou de outra forma apenas entendendo algo errado.

Como posso substituir as tags <a></a> por tags <div></div> para avatares nas páginas de listagem de tópicos? Obrigado.

1 curtida

Olá @boltronics :wave:

Isso substituirá o template list/posters-column. Provavelmente é melhor do que substituir o template topic-list-item.

<script type="text/x-handlebars" data-template-name="list/posters-column.hbr">
  <td class='posters topic-list-data'>
  {{#if currentUser}}
    {{#each posters as |poster|}}
      {{#if poster.moreCount}}
        <a class="posters-more-count">{{poster.moreCount}}</a>
      {{else}}
        <a href="{{poster.user.path}}" data-user-card="{{poster.user.username}}" class="{{poster.extraClasses}}">{{avatar poster avatarTemplatePath="user.avatar_template" usernamePath="user.username" namePath="user.name" imageSize="small"}}</a>
      {{/if}}
    {{/each}}
  {{else}}
    {{#each posters as |poster|}}
      <div data-user-card="{{poster.user.username}}" class="{{poster.extraClasses}}">{{avatar poster avatarTemplatePath="user.avatar_template" usernamePath="user.username" namePath="user.name" imageSize="small"}}</div>
    {{/each}}
  {{/if}}
  </td>
</script>

E você tem que adicionar um CSS também porque ele tem como alvo a e queremos que seja div para anônimos.

Desktop / CSS

html.anon {
  .topic-list {
    .posters {
      width: 146px;
      > div {
        float: left;
        margin-right: 4px;
        &:last-of-type {
          margin-right: 0;
        }
      }
      div:first-child .avatar.latest:not(.single) {
        box-shadow: 0 0 3px 1px rgba(var(--tertiary-rgb), 0.35);
        border: 1px solid rgba(var(--tertiary-rgb), 0.5);
        position: relative;
        left: -2px;
      }
    }
  }
}
7 curtidas

Vale a pena notar que o sistema de template bruto (e o widget!) está desaparecendo em breve, mas é claro que isso não resolve seu problema imediato.

Apenas esteja preparado para uma refatoração, potencialmente com mais ferramentas à sua disposição, pois os Componentes Glimmer provavelmente os substituirão:

6 curtidas

@Don você é incrível. Testei e ele resolve meu problema perfeitamente.

É um pouco de trapaça abordar o problema de uma maneira diferente (eu não estava ciente de que a variável currentUser era acessível de lá), mas não posso argumentar com os resultados. :smile:

Obrigado também @merefield por apontar a refatoração que se aproxima. Vou configurar um teste para monitorar nosso ambiente para possíveis regressões.

Obrigado, pessoal.

3 curtidas

Fico feliz que funcione para você, no entanto, fiz algumas correções na postagem acima. :slightly_smiling_face:
O posters-more-count aparece na lista de tópicos de mensagens privadas, portanto, é desnecessário para anônimos. Removi isso do template e do CSS também.

3 curtidas

Obrigado, Don. Inicialmente suspeitei que pudesse ter sido esse o caso, como nas minhas tentativas originais, mas não investiguei para confirmar. Bom saber.

1 curtida

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