moeli
February 2, 2019, 6:41pm
1
I am trying to customize parts of the pages section. To do so, want to extend components that are used in k-pages-section
, e.g. k-empty
. In my test case is also a files section included.
# Blueprint
title: Test
sections:
pages_section:
headline: Pages Section
type: pages
files_section:
headline: Files Section
type: files
To extend the components is no problem.
// index.js
panel.plugin('my/plugin', {
components: {
'k-empty': {
extends: 'k-empty',
template: `<p>lalala</p>`
},
'k-headline': {
extends: 'k-headline',
template: `<p>headline</p>`
}
},
});
Instead of the original template “lalala” and “headline” are displayed.
But when I want to extend the pages section at the same time, the other component changes are ignored inside the pages section.
// index.js
panel.plugin('my/plugin', {
components: {
'k-empty': {
extends: 'k-empty',
template: `<p>lalala</p>`
},
'k-headline': {
extends: 'k-headline',
template: `<p>headline</p>`
},
'k-pages-section': {
extends: 'k-pages-section'
}
},
});
empty
and headline
for the files section are correctly overwritten. But not for the pages section.
changing the order of extended components (e.g. extend k-pages-section
first) has no effect.
Console Output:
Plugin is replacing "k-empty" app.js:1:236187
Plugin is replacing "k-headline" app.js:1:236187
Plugin is replacing "k-pages-section" app.js:1:236187
It looks like components nested inside the pages section are not overwritten…why?
1 Like
Sounds like a bug to me. Could you please open an issue on GitHub?
Thanks
Depending on whether you actually need to extend k-empty
and k-headline
; if you don’t, you might get away with something like this:
// index.js
const empty = {
template: `<p>lalala</p>`
};
const headline = {
template: `<p>headline</p>`
};
panel.plugin('my/plugin', {
components: {
'k-pages-section': {
extends: 'k-pages-section',
components: {
'k-empty': empty,
'k-headline': headline
}
}
},
});
This way you override the components only for the pages section, which isn’t necessarily bad if what you want is to “customize parts of the pages section”.
If you need to also extend (and not only override) k-empty and k-headline it becomes more complicated
1 Like
moeli
February 12, 2019, 1:38pm
5
That’s an excellent solution to redefine components locally.
I am still looking for a solution to extend them. E.g. If I wanted to adjust the page create dialog only in my custom pages section, I’ll have to copy a lot of code.
I guess you need to either wait for this to be fixed or go the “differently supported” way:
// index.js
const empty = {
mounted: function() {
console.log('Hello');
}
};
const headline = {
mounted: function () {
console.log('World');
}
};
const pages = {
mounted: function() {
console.log('extending stuff like a pro here')
},
components: {
'k-empty': empty,
'k-headline': headline
}
}
panel.plugin('my/plugin', {
use: [
function(Vue) {
empty.extends = Vue.options.components['k-empty'];
headline.extends = Vue.options.components['k-headline'];
pages.extends = Vue.options.components['k-pages-section'];
Vue.component('k-pages-section', pages);
}
],
});
try this.
Everything will look normal (because you extend the components), but you’ll see from the console that your components are actually used. (I used the mounted hook just for demo purposes).
use
plugins get raw access to the Vue “vm”, so you can do pretty much anything. But you lose all safety nets and features that the kirby wrapper code offers you.
moeli
February 12, 2019, 2:25pm
7
That’s what I was looking for. Awesome.
Is there more than this ?
Hi
I want to extend k-page-create-dialog
as well and having it available in all other components.
Applying your suggestions led me to the following solution:
const PAGE_CREATE_DIALOG = {
extends: 'k-page-create-dialog',
// place custom code here...
}
panel.plugin('my/plugin', {
components: {
'k-page-create-dialog': PAGE_CREATE_DIALOG
},
use: [
function(Vue) {
const
VUE_COMPONENTS = Vue.options.components;
Object.keys(VUE_COMPONENTS).forEach(componentName => {
const COMPONENT = {
components: {
'k-page-create-dialog': PAGE_CREATE_DIALOG
},
extends: VUE_COMPONENTS[componentName]
};
Vue.component(componentName, COMPONENT);
});
}
]
});
Not sure if this will work out in any case. But so far it works for me.
Thanks for all valuable hints!