I decided to live on the edge and switched my site over to RC1 a couple days ago and it’s been great so far and has felt very stable. This has led me to dig into some of the new features. One of which I’m interested in implementing is the custom toolbar buttons though I’m wondering what I might be doing wrong (or missing) in getting a test working.
I started with the sample code here in a plugin. The button appears after adding to a blueprint, but nothing seems to happen when I click on it (with or without something selected in the field). Not sure how to debug this and no errors in the console.
Debug is enabled and I’m running via the built in php server. Any suggestions? I’m going to try with a fresh install in the meantime just in case.
update: same problem with a clean Kirby 4rc1 install.
Following up on this – looks to be a regression or change between 4.0b2 and b3. The sample code posted works as expected in beta 2 but fails in beta 3. Looking under the hood, there seems to be significant changes in the panel ➝ index.js file.
I was hoping the blockquote sample button would’ve been included, but alas. One project needs that button, since they use quotes all the time on their site.
Will be watching this.
I’m a bit bemused still by this. I’ve upgraded to the 4.0 release and the sample code from the website is still not working for me. Checked against a clean starterkit too and get the same error. What am I doing wrong/missing?
TypeError: this.command is not a function. (In 'this.command("toggle", "<mark", "</mark>")', 'this.command' is undefined)
Full code from index.js in a new plugin (from here) is:
Experiencing the same thing on my end. Fresh install of the 4.0.0 Plainkit (Exciting!)
Using standard/traditional function notation, the plugin works perfectly. With arrow notation, the button quietly fails…
I don’t know enough about to explain why (scope I guess? anybody?). If you compare the two notations you’ll see the arrow function doesn’t have a binding with Vue to this. It’s just the window.
click: function () {console.log(this)}
click: () => console.log(this)
The custom toolbar button still has some issues. The above code works as expected with a single textarea. When I navigate to another page that has the button, it no longer works. If I have a blueprint with two different textareas using the custom button
Matt, thanks so much for at least getting something functioning! That change did indeed also work for me. I have to think this is a bug at this point. Will look at flagging the issue if it hasn’t already been noted on GitHub.
In JavaScript, arrow functions don’t have their own this. So when you use this in an arrow function it looks for it in the parent scope, which in this case is the whole script.
To have a function with its own this value, you need the function keyword or the short function form:
Now, what the function’s own this value resolves to can be a bit tricky. By default in an object literal which has a function as a property, it should resolve to that object:
let test = {
value: 'red',
click() {
console.log(this.value); // 'red'
console.log(this.command); // undefined
}
}
But it looks like in this case, Kirby’s JS code is going to bind the click function to a different object, or call it with something like options.click.call(someObject, someArguments) (in which case the this in the click function will be someObject).
So basically when you’re providing a function or object with a function to a JS API that tells you to use this.someMethod, then you’re relying on that JS API to provide a this value which has that someMethod function.
Another possible API design is APIs where the functions you pass as values will receive parameters with more data and methods from that API: