Is there any artificial intelligence familiar with the Kirby CMS? If not, are there any plans to integrate AI into Kirby CMS?
Thank you, that is a great tool. I think of an AI that knows Kirby and helps to build a site, for instance, by assisting to create a custom plugin.
I have used Codex to help me build exactly that. As with any AI tool you have to keep an eye on it. Don’t get too carried away. When properly handled it can be very usefull.
I have even included AGENTS.md file in the repo.
http://getkirby.com/llms.txt has a llms.txt, pointing to Markdown version of the docs, as well as an entry on context7 MCP you can utilize in your AIDD toolchain.
There is an alpha-stage community built MCP for Kirby by @thguenther which you can find on the getkirby Discord channel dedicated to AI.
Oh, I didn’t know about that. Thanks!
I created a block plugin following the screencast. I had problems to code the index.js. So, I asked claude.ai and I succeeded with it. Today, I tried the same with ChatGPT and GitHub Copilot. Both failed totally. My goal was to create an accordion block that is editable inline like the Kirby native blocks (heading, list, etc.). I will publish the plugin soon. Anyway, I would like to get feedback from someone who can program Vue.js and tell me whether this is solid or not. Perhaps @bastianallgeier? @Bogdan_Condorachi Do you think it is possible to adapt the Table Field Plugin so that rows and columns can also be added in the preview? And that the table in the preview looks as minimalistic as the native Kirby blocks?
accordion.yml
fields:
items:
type: structure
fields:
summary:
type: writer
placeholder: A Heading here …
details:
type: writer
buttons: false
placeholder: Some details here …
index.css
.k-block-type-accordion {
margin: 0;
padding: 0;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.k-block-type-accordion .accordion-header {
display: flex;
align-items: center;
}
.k-block-type-accordion .accordion-header h2 {
flex: 1;
margin: 0;
font-size: 1.17em; /* Standard H2-Größe */
font-weight: bold;
}
.k-block-type-accordion .accordion-header h2 .k-writer-input {
font-size: inherit;
font-weight: inherit;
}
index.php
<?php
Kirby::plugin('getkirby/accordion', [
'blueprints' => [
'blocks/accordion' => __DIR__ . '/blueprints/blocks/accordion.yml'
],
'snippets' => [
'blocks/accordion' => __DIR__ . '/snippets/blocks/accordion.php'
]
]);
index.js
panel.plugin("getkirby/accordion", {
blocks: {
accordion: {
computed: {
summaryPlaceholder() {
return this.field('items')?.fields?.summary?.placeholder || 'Titel...';
},
detailsPlaceholder() {
return this.field('items')?.fields?.details?.placeholder || 'Inhalt...';
},
getSummaryText(item) {
return (value) => {
if (!value) return '';
if (typeof value === 'string') return value;
// Writer-Feld gibt HTML zurück, extrahiere nur Text
const div = document.createElement('div');
div.innerHTML = value;
return div.textContent || div.innerText || '';
};
},
getDetailsText(item) {
return (value) => {
if (!value) return '';
if (typeof value === 'string') return value;
const div = document.createElement('div');
div.innerHTML = value;
return div.textContent || div.innerText || '';
};
}
},
methods: {
updateItem(index, field, value) {
const items = [...(this.content.items || [])];
items[index] = {
...items[index],
[field]: value
};
this.update({ items });
},
addItem() {
const items = [...(this.content.items || [])];
const newIndex = items.length;
items.push({ summary: '', details: '' });
this.update({ items });
// Neues Item direkt öffnen
this.$nextTick(() => {
this.$set(this.openItems, 'item_' + newIndex, true);
});
},
removeItem(index) {
const items = [...(this.content.items || [])];
items.splice(index, 1);
this.update({ items });
},
toggleItem(index) {
const key = 'item_' + index;
this.$set(this.openItems, key, !this.openItems[key]);
}
},
data() {
return {
openItems: {}
};
},
watch: {
'content.items': {
handler(newItems) {
if (newItems) {
newItems.forEach((item, index) => {
const key = 'item_' + index;
// Nur setzen, wenn noch nicht definiert
if (this.openItems[key] === undefined) {
this.$set(this.openItems, key, true);
}
});
}
},
immediate: true,
deep: true
}
},
mounted() {
// Alle Items beim Laden aufklappen
if (this.content.items) {
this.content.items.forEach((item, index) => {
this.$set(this.openItems, 'item_' + index, true);
});
}
},
template: `
<div class="k-block-type-accordion">
<div
v-for="(item, index) in (content.items || [])"
:key="'accordion-' + index"
class="accordion-item"
>
<div class="accordion-header">
<button
type="button"
class="k-button"
@click="toggleItem(index)"
>
<k-icon :type="openItems['item_' + index] ? 'angle-down' : 'angle-right'" />
</button>
<h2 class="accordion-summary">
<k-writer-input
:value="item.summary"
@input="updateItem(index, 'summary', $event)"
:placeholder="summaryPlaceholder"
:inline="true"
/>
</h2>
<button
type="button"
class="k-button"
@click="removeItem(index)"
>
<k-icon type="trash" />
</button>
</div>
<div
v-if="openItems['item_' + index]"
class="accordion-content"
>
<k-writer-input
:value="item.details"
@input="updateItem(index, 'details', $event)"
:placeholder="detailsPlaceholder"
/>
</div>
</div>
<button
type="button"
class="k-button"
@click="addItem"
>
<k-icon type="add" />
Add
</button>
</div>
`
}
}
});
There is also a LLMS plugin for your website:
Thank you very much! Do you use this feature to develop together with an AI? If so, how do you give an AI access to it? GitHub Co-Pilot may have access to it via VSC, right?
Another question: For inline editing, I would like to co-develop plugins for missing fields and blocks for HTML tags such as details (accordion) and table, meeting the Kirby design guidlines. I appreciate the Table Field plugin but I think it can be improved. Also, I would like to create a plugin for uploading and using custom fonts. Is there anybody here interested in collaborating on these plugins?
getkirby.com/llms.txt is for introducing Kirby CMS to AI.
As far as I know, LLMS | Kirby CMS Plugins is for introducing your own site to AI.