In this recipe, we will create a custom Panel section that displays a list of links with an icon, a title and a description. This is what it will look like once we are ready:
For the purposes of this recipe, we assume that Parcel is already installed globally as described in the Panel plugin setup guide.
You can install the Pluginkit as a basis or create the file structure we need manually, that's up to you. Also, it doesn't matter if you use the Plainkit or the Starterkit as a starting point.
Please read the chapter about custom sections in the reference before starting with this example.
Let's get started with the plugin folder, we'll call it
/linksection. Inside this folder, we create a
package.json file which is needed so that Parcel knows what to do.
This will take care of compiling our source files into an
index.js file in the root of our
linksection plugin folder.
We also need an
index.php file that contains the Kirby plugin wrapper, in which we define the section. The section definition itself goes into a separate file, which we will put into a separate
/sections folder and require from there.
Note that while we could put the props array we now outsource to
links.php into our
index.php, the purpose here is to get an idea how we can structure our files in more complex plugins.
links.php, we set the section's properties. We keep it simple and only set a headline, a layout and a links property. These are the properties we can later define in the blueprint for the section.
Our new section also needs an
index.js in which we register the section for the Vue part of the plugin.
Inside this file, we import the
Links.vue component and assign this component to the
links section. The
Links.vue is stored inside a sections subfolder. This is not a required folder structure, but it makes sense to start using such subfolders for your components, when you work with different types of components (ie. fields, sections, views, etc.)
Finally, we need the
Links.vue component that contains the template and data for the section.
At this point, we are ready to run…
linksection folder to compile our code into the main
If this went smoothly, we are ready to use the section in a blueprint, e.g.
If we now open the Panel start page, we will not see anything yet in the browser. However, on inspecting the source code, there will be an empty
div tag with a class of
k-section k-section-name-links. Hurray!
Links.vue. We now define the same properties that we already defined in
links.php inside the data function of the component object. Unlike fields plugins, we cannot use regular Vue's props here. All sections are lazy-loaded individually and we have to fill our component data manually, once the props that we've defined in PHP have been loaded from the API.
As a next step, we finalize our template, so it can later display the data:
Kirby makes this really easy for us by providing default components we can reuse all over the place. Here we use the
k-collection component. The
k-collection components makes it easy to switch between the cards and list layouts. All we have to do is bind our data to the
:items property and our
layout to the
Still, nothing to see in the Panel.
We can now quickly add some placeholder data so that we finally get something to see in the Panel:
Inside the data array, we use the keywords the
k-collection component expects, and add a value to each. Et voilà, there is our first section entry in the Panel.
The bit that is left to do, is to load the data from the API and let it replace the placeholder values. We do that within the
created hook that is triggered when the component is ready, using the
load() method. The load method is automatically injected into every section component and handles fetching the PHP properties from our
When we get a response, we assign the values to our properties.
Once our props are correctly loaded from the backend, we can remove our hard-coded placeholder values:
We now have a working connection between our section backend and our section frontend and we can freely pass data from blueprints and computed PHP props to our Vue component.
Finally, let's add the data we want to show in the section to the section definition:
Change the layout to
list in the blueprint to see how your section is now displayed as a list.
Once you are happy with your plugin, you can create minified and optimized versions of the
index.css (if you have added custom styles) with…
This is a very basic example that should still have given you an understanding of how the different parts play together and enable you to set up your first custom sections for your clients. The data to fill this section can come in fact come from anywhere, you can provide it through a route, a database or whatever you see fit. And you probably don't just want to display stuff, but add actions to each item etc. We'll cover that in future recipes.
You don't have to use the components Kirby provides, either, but can come up with your own markup and design. The possibilities are pretty much endless.