Override template only on specific page

Just to clarify this bit first

This is not correct, you don’t lose your changes when you update if they’re made in a theme. They persist. The only way you lose your changes is if you directly edit the files on your server, which you obviously shouldn’t do.

Now, there is a certain amount of risk involved in overriding templates in that an update in core might mean that your changes are not compatible anymore and would need to be updated. If you’re fine with that risk then you can technically achieve what you’re asking for here.

To start, you need someway to distinguish when the user is on the homepage. In the case of the categories-only component one way is to check the searchContext. When you’re on a subcategory page, the search context is set to “category”. If there’s no search context, it means you’re on the homepage.

The way to pass that to your template is by adding something like this

<script type="text/discourse-plugin"
        version="0.8">
  const categoriesOnlyComponent = require('discourse/components/categories-only').default;
  categoriesOnlyComponent.reopen({
    isHomepage: function() {
      return !this.parentView.searchService.contextType
    }.property()
  });
</script>

and what that does is allows you to use isHomepage in the template for categories-only it returns true if there’s no search context which means you’re on the homepage. Otherwise, it returns false.

Next you need to copy over the default template like so

<script type='text/x-handlebars'
        data-template-name='components/categories-only'>
  {{#if categories}}
  ... rest of the template
  {{/if}}
</script>

and use isHomepage that we added. For this you need to use the handlebars {{#if}} helper. Essentially what you need is something like this

<script type='text/x-handlebars'
        data-template-name='components/categories-only'>
  {{#if categories}}
    {{#if isHomepage}}
      ... template for homepage only
    {{else}}
    ... rest of the default template if not on the homepage
  {{/if}}
</script>

You can now use whatever you want in the isHomepage section. You can edit it right there or you can create a new template for that section like so

<script type='text/x-handlebars'
        data-template-name='components/categories-only-homepage'>
  <h1>You're on the homepage!</h1>
  <p>
    Use this section to render the template for the categories-only component if the user is on the homepage.
  </p>
</script>

The last thing you need to do is to call that template as a partial in the categories-only template inside the isHomepage section like so

<script type='text/x-handlebars'
        data-template-name='components/categories-only'>
  {{#if categories}}
    {{#if isHomepage}}
      {{partial 'components/categories-only-homepage'}}
    {{else}}
    ... rest of the default template if not on the homepage
  {{/if}}
</script>

The result is that when you visit the homepage you’d see this

but the component in subcategories should remain unchanged.

This is optional but you might also be interested in looking at

because that’s the new recommended way to work on themes and avoid using script tags.

10 Likes