My second plugin - List of top sellers

In this second tutorial, we will dive deeper into developing plugins. Before you continue, we recommend finishing the My first plugin tutorial.

In this tutorial, you will learn how to develop a plugin which renders your top-selling items in the browser. The top items will be displayed as bootstrap cards with the following item information:

  • Name
  • ID
  • First linked image
  • Item description
  • Price

Further reading

Step 1: Creating the plugin files

In the first tutorial, you learned how to set up the folder structure with a minimum of required files to create a working plugin. Our new plugin has a similar structure, but it also has additional content in the resources folder. Create the following basis for your plugin.

    ├-- resources/
    │   └── views/
    │       ├── content/
    │       │   └── TopItems.twig // actual content
    │       │
    │       └── PageDesign.twig // frame for the content
    ├── src/
    │   ├── Controllers/
    │   │   └── ContentController.php
    │   │
    │   └── Providers/
    │       ├── TopItemsServiceProvider.php
    │       └── TopItemsRouteServiceProvider.php
    └── plugin.json // plugin information

Step 2: Filling the source files

We start by creating the plugin.json file. We will also need a ServiceProvider, a RouteServiceProvider and a ContentController in the src folder of our plugin. Create these files and copy the code examples.

Code for the plugin.json

    "name"              :"TopItems",
    "description"       :"Plugin to render a list of top items",
    "namespace"         :"TopItems",
    "author"            :"Your name",
    "type"              :"template",
    "serviceProvider"   :"TopItems\\Providers\\TopItemsServiceProvider"

Code for the ServiceProvider


namespace TopItems\Providers;

use Plenty\Plugin\ServiceProvider;

class TopItemsServiceProvider extends ServiceProvider
    public function register()

Code for the RouteServiceProvider


namespace TopItems\Providers;

use Plenty\Plugin\RouteServiceProvider;
use Plenty\Plugin\Routing\Router;

class TopItemsRouteServiceProvider extends RouteServiceProvider
    public function map(Router $router)
        $router->get('topitems', 'TopItems\Controllers\ContentController@showTopItems');

Code for the ContentController


namespace TopItems\Controllers;

use Plenty\Plugin\Controller;
use Plenty\Plugin\Templates\Twig;
use Plenty\Modules\Item\DataLayer\Contracts\ItemDataLayerRepositoryContract;

class ContentController extends Controller
    public function showTopItems(Twig $twig, ItemDataLayerRepositoryContract $itemRepository):string
        $itemColumns = [
            'itemDescription' => [
            'variationBase' => [
            'variationRetailPrice' => [
            'variationImageList' => [

        $itemFilter = [
            'itemBase.isStoreSpecial' => [
                'shopAction' => [3]

        $itemParams = [
            'language' => 'en'

        $resultItems = $itemRepository
            ->search($itemColumns, $itemFilter, $itemParams);

        $items = array();
        foreach ($resultItems as $item)
            $items[] = $item;
        $templateData = array(
            'resultCount' => $resultItems->count(),
            'currentItems' => $items

        return $twig->render('TopItems::content.TopItems', $templateData);

Step 3: Creating the page design

In this step, we create the template file that contains the page design. This file is the HTML frame for our content retrieved from the database. The content itself and its layout will be discussed in step 4. Add a new twig file in the resources/views folder and name the file PageDesign.twig. Insert the code example below.

<!DOCTYPE html>
<html lang="en">
        <!-- Required meta tags always come first -->

        <title>Top items</title>

        <!-- CSS -->
        <link href="" rel="stylesheet" type="text/css">

        <div id="page-body">
            {% block PageBody %}
                <!-- inserts content of TopItems.twig here -->
            {% endblock %}

Step 4: Creating the output file

Last but not least, we need a file for the item information retrieved from the database. Create a new content subfolder in the resources/views folder and add a TopItems.twig file.

{% extends "TopItems::PageDesign" %}

{% block PageBody %}
    <h1 style="text-align: center">{{ resultCount }} top items found!</h1>
    <div class="col-xs-12 card-deck-wrapper" style="overflow: auto">
    <ul class="list-unstyled card-deck" style="height: 380px">
        {% if currentItems is not null %}
            {% for item in currentItems %}
                <li class="card" style="width: 280px">
                    <div class="card-block">
                        <h4 class="card-title">{{ item.itemDescription.name1 }}</h4>
                        <h6 class="card-subtitle text-muted">ID: {{ }}</h6>
                    {% set image = item.variationImageList | first %}
                    <img class="col-lg-12" src="{{ image.path }}" alt="{{ image.cleanImageName }}">
                    <div class="card-block">
                        <p class="card-text">{{ item.itemDescription.description }}</p>
                    <div class="card-footer bg-primary">
                        <h4 style="text-align: center">Price: {{ item.variationRetailPrice.price }} €</h4>
            {% endfor %}

            {% else %}
                <li>No items found!</li>
        {% endif %}
{% endblock %}

Playing your cards right

Provided that you have already set up some top items in your plentymarkets backend, the plugin will be filled with the requested data. To display the top item cards, open a new browser tab and type in your domain adding /topitems at the end. Don't forget to push your changes to GitHub. You also have to update the plugin in your plentymarkets inbox by pulling the changes from GitHub. Finally, you have to deploy the plugin again to display your top items in your browser. Good job!

Is this article helpful?


Thank you for your Feedback

you can close this field now!