I'm trying to make a simple block helper but can't find any documentation for ember-cli on the subject
UPDATED
Here's the helper:
import Ember from 'ember';
export default function uiInput(options) {
return new Handlebars.SafeString(
'<div class="ui input">'
+ options.fn(this)
+ '</div>');
}
And in the template:
{{#ui-input}}
TEST
{{/ui-input}}
And the output should be:
<div class="ui input">
TEST
</div>
But the output I'm getting is:
TEST
<div class="ui input">
undefined
</div>
What am I doing wrong?
Original answer (see below for the ember way)
I first want to try to explain what is happening here: Ember (currently 1.9.1) does not return rendered templates as strings any more for quite some time now when calling options.fn
directly (despite all of the code samples out there that rely on this behavior). Instead, your content is rendering 'itself', meaning that it uses options.data.view
's appendChild
function to put things where they belong. You can see this in action e.g. by following the with
helper's code down to line 81 in ember-handlebars/lib/helpers/binding.js. You can also find a previous discussion on this in this thread.
So, what can you do about it? We need to create a custom view to take care of what we need. The following code works for me using ember-cli. In app/helpers/ui-input
:
import Ember from 'ember';
var UiInputView = Ember.View.extend({
classNames: ['ui', 'input']
});
export default function(options) {
var view = options.data.view;
var viewOptions = {
shouldDisplayFunc: function() {return true;},
template: options.fn,
inverseTemplate: options.inverse,
isEscaped: !options.hash.unescaped,
templateData: options.data,
templateHash: options.hash,
helperName: 'block-helper'
};
var childView = view.createChildView(UiInputView, viewOptions);
view.appendChild(childView);
}
Maybe not all the viewOptions are necessary...
I hope this helps.
Update: the ember way
When I came here to answer this question, I was stubbornly determined that I should be able to write my own helpers. Little did I know about the {{yield}}
helper. The correct code would thus look like this:
Component:
// app/components/ui-input.js
import Ember from 'ember';
export default Ember.Component.extend({
classNames: ['ui', 'input']
});
Template:
{{!-- app/templates/components/ui-input.hbs --}}
{{yield}}
Usage:
{{#ui-input}}
Test
{{/ui-input}}
I'm on ember-cli 0.1.4. When i try your ui-style helper in block notation:
{{#ui-input}}
TEST
{{/ui-input}}
i get a javascript error in the console saying this:
Assertion failed: registerBoundHelper-generated helpers do not support use with Handlebars blocks.
however, this works for me with a slight tweak to your helper:
helper:
import Ember from 'ember';
export default function uiInput(input) {
return new Handlebars.SafeString(
'<div class="ui input">'
+ input
+ '</div>');
}
template:
{{ui-input 'TEST'}}
getting this output:
<div class="ui input">
TEST
</div>