对原始模板进行自定义更改

目前,在我们的话题列表页面上,会显示每个话题主要参与者的头像,以及指向用户个人资料页面的链接。您可以在此处看到:


当用户未登录时,此链接将不可点击,因为否则会重定向到登录页面。

问题是,我们的 SEO 顾问已确定这对我们来说是个问题,并希望 Google 完全看不到该个人资料页面链接。

在话题帖子等内容上也有类似的问题,但这些都包含在小部件中,并且使用 api.reopenWidge() 等方法相对容易解决。

话题列表页面则不然,我们需要更改 raw-templates/list/posters-column.hbr 的内容!

我现在将描述我尝试过的方法。如果您已经知道答案,请随时跳到最后。

起初,我尝试按照初学者指南中的说明挂载一个小部件。

<script type="text/x-handlebars" data-template-name="list/posters-column">
    <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>
</script>

这一切似乎都没有起到任何作用。最终,我在一个主题中发现有人在 data-template-name 值中使用了 .raw 扩展名,所以我假设该指南已过时。它没有提到原始模板!使用 .raw 可以渲染上述更改,但我的自定义小部件无法加载。

这很奇怪,因为 list/posters-column 仅由 topic-list-item.hbr 引用,而 topic-list-item.hbr 本身也是一个原始模板,并且是该指南中使用的模板之一。但是……我猜它又过时了?我最终在某处读到,您不能在原始模板中挂载小部件,所以这似乎永远行不通。

接下来,我发现了部分模板并尝试使用它们。我想,既然那些部分不是原始模板,我可能会有更多机会。

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

不幸的是,似乎您也不能在原始模板中使用部分模板,所以该方法行不通。

然后,我找到了这个帖子,看起来可能包含我需要的东西。基于该方法,并且知道 list/topic-list-item(调用 list/posters-column)被 topic-list-item 组件使用,我提出了以下方法:

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

可惜的是,hideFromAnonUser 似乎从未对原始模板可见。也许 hideFromAnonUser 需要从分配给 hideFromAnonUser 键的函数内部计算?似乎无关紧要。即使我注释掉前三个 const 赋值并将其设置为返回 False,或者在返回语句之前在其内部添加一个 console.log() 调用,我也能看到该函数从未被任何东西执行。

此时我束手无策。我以前从未接触过这些,感觉自己力不从心。也许我忽略了什么,但似乎很多信息要么具有误导性,要么已过时,或者我找错了地方,或者只是误解了什么。

如何用 <div></div> 标签替换话题列表页面上头像的 <a></a> 标签?谢谢。

1 个赞

你好 @boltronics :wave:

这将覆盖 list/posters-column 模板。这可能比覆盖 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>

而且你还需要添加一些 CSS,因为它针对的是 a 标签,而我们希望它针对匿名用户的 div 标签。

桌面 / 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 个赞

值得注意的是,原始模板(以及 widget!)系统很快就会消失,但这当然不能解决你目前的问题。

请做好重构的准备,随着 Glimmer Components 很可能取而代之,你可能会拥有更多的工具:

6 个赞

@Don 你太棒了。我已经测试过了,它完美地解决了我的问题。

这有点像作弊,因为它用不同的方式解决了问题(我不知道 currentUser 变量可以从那里访问),但我无法反驳结果。:smile:

也要感谢 @merefield 指出即将进行的重构。我将设置一个测试来监控我们的环境,以防出现潜在的回归。

谢谢你们。

3 个赞

很高兴它对您有效,但我对上面的帖子做了一些更正。 :slightly_smiling_face:
posters-more-count 出现在私信主题列表中,因此对匿名用户来说是不必要的。我已将其从模板和 CSS 中删除。

3 个赞

谢谢 Don。正如我最初尝试的那样,我最初怀疑可能是这种情况,但我没有深入研究以确认。很高兴知道。

1 个赞

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