For our very first Panel view, we will query a public API and display the results in a nice card layout.
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.
Let's start by creating a new folder in the plugins folder, which we will call
moviereviews. Inside this folder, we first create a
package.json file with the contents copied from the Pluginkit example mentioned above.
This will take care of compiling our source files into an
index.js file in the root of our
moviereviews plugin folder.
moviereviews folder, we create an
index.php with the Kirby plugin wrapper. And inside this wrapper, we create a custom API route that serves as our data provider. It requests the data from the selected API with a
Remote::get() request and returns it, so that we can later use it in our component.
For this example, we reuse the NYT Movie Reviews API we already used in the Virtual Pages guide. To follow this example, create an account and an example app by following their instructions. Then get your API key and add it to the code below.
You can test if the route returns the desired data by opening the API URL in your browser. Make sure to login to the panel first and set a custom CSRF token for the API in your config.
The custom CSRF should only be set for debugging and removed afterwards unless it is required for the specific use-case.
You can now access the following API URL by using the temporary CSRF. The
pretty option helps to render the JSON output in a human-readable way.
This will give you a nice overview of the data structure.
Next, we create a new folder called
/src inside our
moviereviews folder. Inside the
src folder, we create an
Inside this file, we register the new custom
moviereviews view component called
View. The view itself will be defined in the
components subfolder and called
View.vue, we reuse the Kirby
k-header components for our basic view setup.
Now let's run
in our plugin folder, and Parcel will compile an
index.js in the
If all went well, we will now see a new menu entry in the Panel dropdown navigation, and when we click on it, we can visit the newly created view that's still empty at this time.
But how do we get our data in? To achieve this, we create a new Vue component, let's call it
reviews. This new component will show each data item from our data provider in a cards layout, another component Kirby provides for us. We also add an empty
When we visit our Panel view, nothing has changed yet. That's because we haven't registered the new component yet. Let's do that now.
View component, we do three things:
- We import the `Reviews.vue" component
- In our
exportobject, we register the component
- We add the new
<reviews/>component to the template below the header
If we now return to the Panel, our view has changed and will show the cards component with a single empty card in it.
We are almost there. Here is the final
Reviews.vue component which we will explain in more detail in a minute.
Let's first look at the script part:
export object, we have to define the data our component returns as a function.
Once the Vue component is created, we call the
load() method calls the
moviereviews route from the API, and then assigns the result to
We can now loop through the data and create a card for each review:
Here we fill the props of the card component with life. We loop through each review (
v-for="review in reviews") and assign the data items to the
image props. We also add a
link to the original review.
Once you are happy with your plugin, you can create minified and optimized versions of the
index.css with …
To get more familiar with how this all plays together, play around a bit. Try to get other data in, from a database, a .csv file, another API or try to fetch some data from your Kirby installation. Adjust the data provider route as needed. Change the layout to a table. Try to add events…