How to have if "string === string" in template?

AI-generated summary

The discussion is about how to implement an if statement in a Discourse template to evaluate whether a string matches a value. The original poster, JQ331, tried using a helper but was unsuccessful.

merefield suggested using computed properties, but JQ331 was unsure how to apply this to their specific use case.

justin explained that Handlebars templates have limited boolean logic, and more complex logic should be performed in the associated Ember JS file. He provided an example of using a computed property to compare two strings.

JQ331 attempted to implement this solution but was unsure about the correct syntax and file placement. They asked for further clarification and a full working example.

Unfortunately, JQ331 was unable to get the solution working and had to move on. oca and JQ331 both expressed interest in a detailed example of how to implement this functionality.

The key takeaway is that when working with Discourse templates, complex logic should be performed in the associated Ember JS file using computed properties. However, a clear and working example of how to implement an if statement to compare two strings is still lacking.

In my plugin, I want to have an if statement in a template, that evaluates whether a string matches a value.

Like this:

{{#each groups as |group|}}
  {{#if group.name === "AwesomeName"}}
      <div>There is a match!</div>
  {{/if}}
{{/each}}

How can I do this in Discourse?


I understand that doing a straight {{if}} does not work in Ember/Handlebars. It looks like I have to register a helper. Something like this:

plugin/assets/javascripts/discourse/helpers/eq/js/es6

import { registerHelper } from 'discourse-common/lib/helpers';

registerHelper('eq', function(arg1, arg2) {
     if (arg1 === arg2) {
         return true
    } else {
       return false
    }
})

plugin/assets/javascripts/templates/components/my-component.hbs

{#each groups as |group|}}
  {{#eq group.name "AwesomeName"}}
      <div>There is a match!</div>
 {{/eq}}
{{/each}}

This doesn’t work. (There are no errors provided.)

I tried the solution here, which tries to use “makeBoundHelper”, but it doesn’t work for me either–there I get errors about “makeBoundHelper” is not a function.

I just want to be able to do an if statement for matching a string to a value. How do I do it?

You want to use Computed Properties - The Object Model - Ember Guides

Look at the Discourse source code for their particular code style though.

Computed properties are interesting, but I’m not seeing the link to what I’m focused on here.

In my example, the key property is group.name, and I want to evaluate in the template whether that property matches “AwesomeName”. Not sure how computed properties would get around the need to use a particular type of {{if}} statement in the template that I haven’t been able to figure out.

Handlebars templates only have rudimentary boolean logic. You can do which checks the property for truthy values.

To do anything more complicated, you need to perform the logic in the Ember JS file associated with the template.

So say you have a template under templates/components/my-component.hbs. You’d have to use the JS file components/my-component.js to do the computation.

In that file you’d do something like this:

import discourseComputed from "discourse-common/utils/decorators";
import Component from "@ember/component";

export default Component.extend({
  @discourseComputed("string1", "string2")
  property(string1, string2) {
    return string1 === string2;
  }
});

property is just the name of a function, but it could be any name.

Then in the template, you’d do something like this:

{{#if property}}
 blah blah...
{{/if}}

This pulls the computed property in from the JS file and shows the content in the #if block only if property returns true.

Thanks for this–it helps clarify a lot.

Haven’t quite gotten it to work yet–in part bc I’m not finding examples out there of using computed properties to do this kind of operation.

In my case, in my plugin, I am making the change in the group index template. So in the file: plugin/assets/javascripts/discourse/groups/index.hbs (I just put the entire groups index code there and add changes on top of it.)

Do you mean that the computed property js would go in a file I create that is: plugin/assets/javascripts/discourse/groups/index.js? Or can I just put that code in an initializer?

This is my best attempt to implement what you are talking about–is this what you had in mind:

js:

export default Component.extend({
  @discourseComputed("group.name", "Amazing_Name")
  property(group.name, Amazing_Name) {
    return group.name === Amazing_Name
  }
})

hbs:

 {{#if property}}
    <div>Yep There is a Match!</div>
 {{/if}}

Or did you mean that I should literally enter general values like “string1” and “string2” in @discourseComputed, and then change the template to {{#if property group.name "Amazing_Name"}} ? (only that way could I account for each value being dynamic in the template.)

Haven’t gotten either approach to quite work yet.

Thank you for your help.

Have you managed to make it work ? I crave for a detailed example of how to do that (add what content, in which file, and where in that file if that’s relevant).

I actually never got this to work myself and had to move on. It seemed silly to spend so much time on what normally would be a basic coding exercise. In my case I think it was likely a bit of incorrect syntax here and incorrect syntax there, but I never found full working examples. I would also be grateful for a full working example of how to do an if string === string.