Is this article helpful?
 
(optional) let us know why:

Introducing theme plugins

On this page, you will find an overview of relevant information about theme plugins. Theme plugins let you change the colour and style of your template in an easy and convenient way. In contrast to other plugins, you only have to deploy a theme once to then activate and deactivate it without further configuration.

Theme plugins make use of a template container in the Ceres template and extend the CSS of Ceres. In doing so, the CSS of the theme will override all concerned classes in the Ceres stylesheet. Classes that are not styled in the CSS of the theme but in the Ceres stylesheet are not affected.

Further reading

Creating a theme

Create the following files and develop a theme that changes the background colour of the template plugin. If you want to offer the theme in the plentyMarketplace, pay attention to our plugin requirements.

Changing the CSS of a template

This basic theme plugin for changing the CSS of a template consists of a plugin.json file, a ServiceProvider, a Container, a CSS file and a TWIG template.

Theme/
    ├── resources/
    │   ├── css/
    │   │   └── main.css // theme stylesheet
    │   │
    │   └── views/
    │       └── content/
    │           └── Theme.twig // content to be injected into the Ceres template container
    ├── src/
    │   ├── Containers/
    │   │   └── ThemeContainer.php
    │   │
    │   └── Providers/
    │       └── ThemeServiceProvider.php
    │
    └── plugin.json // plugin information

Code for the plugin.json

ThemePlugin/plugin.json
{
    "name"                  :"Theme",
    "description"           :"Basic theme plugin",
    "namespace"             :"Theme",
    "author"                :"Your name",
    "keywords"              : ["theme", "Ceres", "template"],
    "type"                  :"theme",
    "require"               : [],
    "serviceProvider"       :"Theme\\Providers\\ThemeServiceProvider",
    "dataProviders"         :
    [
        {
            "key"           :"Theme\\Containers\\ThemeContainer",
            "name"          :"Dark background",
            "description"   :"Change the background colour of the Ceres template"
        }
    ]
}

Code for the ServiceProvider

Theme/src/Providers/ThemeServiceProvider.php
<?php

namespace Theme\Providers;

use Plenty\Plugin\ServiceProvider;

class ThemeServiceProvider extends ServiceProvider
{

	/**
	 * Register the service provider.
	 */
	public function register()
	{

	}
}

Code for the Container

Theme/src/Containers/ThemeContainer.php
<?php

namespace Theme\Containers;

use Plenty\Plugin\Templates\Twig;

class ThemeContainer
{
    public function call(Twig $twig):string
    {
        return $twig->render('Theme::content.Theme');
    }
}

Code for the TWIG template

Theme/resources/views/content/Theme.twig
<link rel="stylesheet" href="{{ plugin_path('Theme') }}/css/main.css">

Code for the CSS file

Theme/resources/css/main.css
/* Change background colour */
body {
    background-color: #808080;
}

Activating a theme

Create the theme as described, then add the plugin to the plentymarkets inbox and deploy it in a plugin set. After deploying the theme plugin once, you can activate and deactivate it without further configuration.

  1. Open the plentymarkets back end.
  2. Go to CMS » Container links.
    → A list of all plugins that provide data will be displayed.
  3. Activate the Template: Style container in the Dark background (Theme) area.
  4. Save the settings.
  5. Refresh the browser window.
    → The new theme will be loaded.

Editing a template plugin

A theme plugin can not only extend the CSS file of the template plugin, but also change the entire markup of individual template components or the overall page design.

This facilitates adding your own markup and style to an existing template plugin. Maintaining the code of your theme plugin is not directly linked to the code of the template plugin, i.e. changes made in your theme plugin are not overwritten when the template plugin is updated.

Page structure

You can either change parts of the page design or edit the entire page design to meet your needs. The page design of Ceres consists of two main sections, the head and the body. The head contains the meta data of the page as well as the linked stylesheets. The body is divided into multiple sub-sections called wrappers. Wrappers include different components, partials or pages.

The most important wrapper is the main wrapper containing the following partials:

  • Header: includes the navigation, the login button, the search field etc.
  • PageBody: includes dynamic pages, e.g. the single item view, or static pages, e.g. the cancellation rights
  • Footer: includes store features, containers for icons as well as columns

Context classes

Context classes are php classes that retrieve and provide data for templates. You can include context classes in order to reduce the number of function calls in your .twig files. By using context classes you improve the performance and are able to maintain the template-relevant data concisely and in one central location. The controller passes the relevant parameters to the context via the init function. The context classes are located under src/contexts. The cookbook provides examples about how to modify and extend contexts.

List of context classes

The following context classes are available:

  • GlobalContext
  • CategoryContext
  • CategoryItemContext
  • ItemListContext
  • ItemSearchContext
  • ItemWishlistContext
  • OrderConfirmationContext
  • OrderReturnContext
  • PasswordResetContext
  • SingleItemContext

List of variables for each context

The following tables list the available variables for each of the context classes. In Twig, the output of context class variables is effected by including , whereby "myVariable" is a placeholder for the relevant class variable.

GlobalContext

The GlobalContext provides variables that are utilised by all other contexts. Therefore, the other contexts listed here automatically inherit variables from the global context.

Variable Description
$ceresConfig Contains the data of the current Ceres configuration.
$lang Contains the selected language.
$metaLang Contains the selected language for meta information.
$categories Contains the category tree.
$categoryBreadcrumbs Contains the category breadcrumb navigation.
$notifications Contains the notifications that can be displayed in the online store.
$basket Contains the shopping cart information.
$webstoreConfig Contains the configuration of the online store.

CategoryContext

Variable Description
$category Contains the current category.
$metaRobots Contains SEO-relevant settings for the category.

CategoryItemContext

The CategoryItemContext inherits variables from the CategoryContext. It does not provide data itself, but feeds parameters to the ItemListContext in order to load item data from ElasticSearch.

ItemListContext

Variable Description
$currentPage Contains the current page.
$pageMax Contains the maximum number of pages.
$itemsPerPage Contains the number of items to be displayed on one page.
$itemCountPage Contains the actual number of items on a page.
$itemCountTotal Contains the total number of items.
$itemSorting Contains the type of item sorting.
$query Contains the search query consisting of $itemsPerPage and $itemSorting.
$itemList Contains the results of ElasticSearch.
$facets Contains the facets.
$searchOptions Contains the search options that are avilable in the item search in the online store.
$searchOptions itself contains the following variables:
  • $itemsPerPage: Contains a list from which to select the number of items to be displayed on one page.
  • $defaultItemsPerPage: The default number of items to be displayed on one page.
  • $sorting: Contains the available sorting values.
  • $defaultSorting: The default sorting value.

ItemSearchContext

Variable Description
$isSearch Inquires whether the current template is a search.
$searchString Contains the search string.

ItemWishListContext

Variable Description
$wishList Contains the items of the wish list.

OrderConfirmationContext

Variable Description
$data Contains the current order of the order confirmation page.
$totals Contains the gross and net sums.
$showAdditionalPaymentInformation Contains additional payment information that is displayed on the order confirmation page.

OrderReturnContext

Variable Description
$orderData Contains the data for returns processing.

PasswordResetContext

Variable Description
$contactId Contains the ID of the user whose password is to be changed.
$hash Contains the hash for password verification.

SingleItemContext

Variable Description
$variations Contains the variations of an item.
$attributeNameMap Contains the combination of attributes that constitute the variation.
$customerShowNetPrices Determines whether net prices are displayed to the customer.

Template to context mapping

The following table depicts which context is applicable to which template.

Template Context
Homepage GlobalContext
CategoryContent CategoryContext
CategoryItem CategoryItemContext
PageDesign GlobalContext
SingleItemWrapper SingleItemContext
Basket GlobalContext
CheckoutView GlobalContext
MyAccount GlobalContext
OrderConfirmation OrderConfirmationContext
Login GlobalContext
Register GlobalContext
Guest GlobalContext
ResetPassword PasswordResetContext
Contact GlobalContext
ItemListView ItemSearchContext
WishListView ItemWishListContext
OrderReturnView OrderReturnContext
OrderReturnCofirmation GlobalContext
CancellationRights GlobalContext
CancellationForm GlobalContext
LegalDisclosure GlobalContext
PrivacyPolicy GlobalContext
TermsAndConditions GlobalContext
ItemNotFound GlobalContext
PageNotFound GlobalContext

The TWIG include statement is used for this purpose. In the example below the ThemeFooter.twig file is included in the PageDesign.twig file of Ceres. You can simply create your own footer template and replace the Ceres footer.

The code of the ServiceProvider must be updated to inject your own template paths into the template plugin.

Theme/src/Providers/ThemeServiceProvider.php
<?php

namespace Theme\Providers;

use IO\Extensions\Functions\Partial;
use Plenty\Plugin\Events\Dispatcher;
use Plenty\Plugin\ServiceProvider;
use Plenty\Plugin\Templates\Twig;

class ThemeServiceProvider extends ServiceProvider
{

	/**
	 * Register the service provider.
	 */
	public function register()
	{

	}

    /**
	 * Boot a template for the footer that will be displayed in the template plugin instead of the original footer.
	 */
	public function boot(Twig $twig, Dispatcher $eventDispatcher)
    {
        $eventDispatcher->listen('IO.init.templates', function(Partial $partial)
        {
           $partial->set('footer', 'Theme::content.ThemeFooter');
        }, 0);
        return false;
    }
}
Theme/resources/views/content/ThemeFooter.twig
<div class="footer">

    <!-- Insert footer markup here -->

</div>

Changing the template of a page

The extends tag is used to extend a template from another template. In the example below, the ThemeBasket.twig file extends the PageDesign.twig file of Ceres. TWIG blocks are used to define the content that will be inserted in the main wrapper of the page design. We only have to edit the ServiceProvider of our theme and create the page template, e.g. the basket.

Code for the ServiceProvider

Theme/src/Providers/ThemeServiceProvider.php
<?php

namespace Theme\Providers;

use IO\Helper\TemplateContainer;
use Plenty\Plugin\Events\Dispatcher;
use Plenty\Plugin\ServiceProvider;
use Plenty\Plugin\Templates\Twig;

class ThemeServiceProvider extends ServiceProvider
{

	/**
	 * Register the service provider.
	 */
	public function register()
	{

	}

    /**
	 * Boot a template for the basket that will be displayed in the template plugin instead of the original basket.
	 */
	public function boot(Twig $twig, Dispatcher $eventDispatcher)
    {
        $eventDispatcher->listen('IO.tpl.basket', function(TemplateContainer $container, $templateData)
        {
            $container->setTemplate('Theme::content.ThemeBasket');
            return false;
        }, 0);
    }
}

Code for the Basket template

Theme/resources/views/content/ThemeBasket.twig
{% extends getPartial('page-design') %}

{% block PageBody %}

    <!-- Insert markup for the basket here -->

{% endblock %}

Changing the template of a page component

Page components, e.g. the BasketList of the Basket template, can also be individualised. For this purpose, the template of the page where the component is used must be updated and a new template for the component must be created.

Code for the Basket template

Theme/resources/views/content/ThemeBasket.twig
{% extends getPartial('page-design') %}
{% import "Ceres::PageDesign.Macros.LayoutContainer" as LayoutContainer %}

{% block PageBody %}

    {{ component( "Theme::content.Components.ThemeBasketList" ) }}

    ...

    <div class="page-content basket container-max">

        <div class="row m-t-1">
            <div class="col-xs-12">
                <h1 class="h4">{{ trans("Ceres::Template.basket") }}</h1>
            </div>
        </div>

        <hr class="m-b-3">

        <div class="row">
            <div class="col-xs-12">
              <basket-list template="#theme-basket-list"></basket-list>
            </div>
        </div>

    ...

{% endblock %}

Code for the BasketList template

Theme/resources/views/content/Components/ThemeBasketList.twig
<script type="x/template" id="theme-basket-list">

    <!-- Insert BasketList markup here -->

</script>

Changing the template of a Vue component

Vue components, e.g. the SingleItem component of the SingleItemView template, can also be individualised. For this purpose, the ServiceProvider of your theme must be updated and a new template for the Vue component must be created.

Code for the ServiceProvider

Theme/src/Providers/ThemeServiceProvider.php
<?php

namespace Theme\Providers;

use IO\Helper\TemplateContainer;
use IO\Helper\ComponentContainer;
use Plenty\Plugin\Events\Dispatcher;
use Plenty\Plugin\ServiceProvider;
use Plenty\Plugin\Templates\Twig;

class ThemeServiceProvider extends ServiceProvider
{
  const PRIORITY = 0;

	/**
	 * Register the service provider.
	 */
	public function register()
	{

	}

    /**
	 * Boot a template for the basket that will be displayed in the template plugin instead of the original basket.
	 */
	public function boot(Twig $twig, Dispatcher $eventDispatcher)
    {
        $eventDispatcher->listen('IO.Component.Import', function (ComponentContainer $container)
        {
            if ($container->getOriginComponentTemplate()=='Ceres::Item.Components.SingleItem')
            {
                $container->setNewComponentTemplate('Theme::content.SingleItem');
            }
        }, self::PRIORITY);
    }
}

Code for the Vue component template

Theme/resources/views/content/SingleItem.twig

<!-- Insert SingleItem markup here -->

Overview of pages and page components

Find the template folder structure of Ceres as well as an overview of pages and page components used in the Ceres template plugin below.

Ceres template folder

The template folder is structured into 10 sub-folders that include the main pages of Ceres and the respective components.

Ceres/
    └── resources/
        └── views/
            ├── Basket/
            │   ├── Basket.twig
            │   └── Components/
            │       ├── AddItemToBasket.twig
            │       ├── AddItemToBasketOverlay.twig
            │       ├── BasketList.twig
            │       ├── BasketListItem_large.twig
            │       ├── BasketListItem_small.twig
            │       ├── BasketListItem.twig
            │       ├── BasketPreview.twig
            │       ├── BasketTotals.twig
            │       └── Coupon.twig
            │
            ├── Category/
            │   ├── Content/
            │   │   └── CategoryContent.twig
            │   └── Item/
            │       ├── CategoryItem.twig
            │       └── Partials/
            │           ├── CategoryListItem.twig
            │           ├── CategoryViewFilter.twig
            │           ├── ListControls.twig
            │           └── Pagination.twig
            │
            ├── Checkout/
            │   ├── Checkout.twig
            │   ├── OrderConfirmation.twig
            │   ├── Components/
            │   │   ├── OrderDetails.twig
            │   │   ├── PaymentProviderSelect.twig
            │   │   ├── PlaceOrder.twig
            │   │   └── ShippingProfileSelect.twig
            │   └── Macros/
            │       └── Address.twig
            │
            ├── Customer/
            │   ├── Guest.twig
            │   ├── Login.twig
            │   ├── Register.twig
            │   └── Components/
            │       ├── CountrySelect.twig
            │       ├── Login.twig
            │       ├── Registration.twig
            │       ├── UserLoginHandler.twig
            │       ├── AddressInputGroup/
            │       │   ├── AddressInputGroup.twig
            │       │   └── Locale/
            │       │       ├── AddressInputGroupDE.twig
            │       │       └── AddressInputGroupGB.twig
            │       └── AddressSelect/
            │           ├── AddressSelect.twig
            │           └── CreateUpdateAddress.twig
            │
            ├── Homepage/
            │   └── Homepage.twig
            │
            ├── Item/
            │   ├── SingleItem.twig
            │   ├── Components/
            │   │   ├── QuantityInput.twig
            │   │   ├── VariationImageList.twig
            │   │   └── VariationSelect.twig
            │   └── Partials/
            │       └── ItemRating.twig
            │
            ├── ItemList/
            │   ├── ItemListView.twig
            │   └── Components/
            │       ├── ItemList.twig
            │       ├── ItemSortingList.twig
            │       ├── ItemSearch.twig
            │       ├── ItemsPerPage.twig
            │       ├── LoadingAnimation.twig
            │       └── Pagination.twig
            │
            ├── MyAccount/
            │   ├── MyAccount.twig
            │   └── Components/
            │       ├── AccountSettings.twig
            │       ├── BankDataSelect.twig
            │       └── OrderHistory.twig
            │
            ├── PageDesign/
            │   ├── PageDesign.twig
            │   ├── Components/
            │   │   ├── Notifications.twig
            │   │   ├── ShippingCountrySelect.twig
            │   │   └── ShopLanguageSelect.twig
            │   ├── Macros/
            │   │   ├── IncludeComponents.twig
            │   │   └── LayoutContainer.twig
            │   └── Partials/
            │       ├── Footer.twig
            │       ├── Head.twig
            │       └── Header/
            │           ├── Breadcrumb.twig
            │           ├── Header.twig
            │           └── Navigation.twig
            │
            └── StaticPages/
                ├── CancellationRights.twig
                ├── ItemNotFound.twig
                ├── LegalDisclosure.twig
                ├── PageNotFound.twig
                ├── PrivacyPolicy.twig
                └── TermsAndConditions.twig

Ceres page templates

Ceres uses individual templates containing the markup of the main pages. Some templates include partials or components. Find a table of all page templates and their respective location in the resources/views folder below:

Template Description
Basket The template for the shopping cart of your online store. It can be found in the Basket sub-folder of Ceres. This template includes the following components:
  • BasketList
  • Coupon
  • BasketTotals
CategoryItem The template for the category view of your online store. It can be found in the Category/Item sub-folder.
Checkout The template for the checkout of your online store. It can be found in the Checkout sub-folder. This template includes the following components:
  • AddressSelect
  • PaymentProviderSelect
  • ShippingProfileSelect
  • PlaceOrder
  • Coupon
  • BasketList
  • BasketTotals
Guest The template for guest orders. It can be found in the Customer sub-folder. This template includes the following components:
  • Registration
HomePage The template for the homepage of your online store. It can be found in the Homepage sub-folder.
ItemListView The template for the item list view of your online store. It can be found in the ItemList sub-folder. This template includes the following components:
  • ItemList
  • ItemsPerPage
  • ItemListSorting
  • Pagination
  • LoadingAnimation
Login The template for customer login. It can be found in the Customer sub-folder.
MyAccount The template for the My Account page of your online store. It can be found in the MyAccount sub-folder. This template includes the following components:
  • AddressSelect
  • AccountSettings
  • OrderHistory
  • BankDataSelect
  • OrderDetails
OrderConfirmation The template for the order confirmation page. It can be found in the Checkout sub-folder. This template includes the following components:
  • OrderDetails
PageDesign The general template for your online store. It can be found in the PageDesign sub-folder. This template includes the following partials and components:
  • Notifications
  • BasketPreview
  • Login
  • Registration
  • AddItemToBasketOverlay
  • Head
  • Header
  • Footer
Register The template for customer registration. It can be found in the Customer sub-folder. This template includes the following components:
  • Registration
SingleItem The template for the single item view of your online store. It can be found in the SingleItem sub-folder. This template includes the following components:
  • VariationSelect
  • VariationImageList
  • AddItemToBasket
CancellationRights The cancellation rights of your online store. It can be found in the StaticPages sub-folder.
ItemNotFound The Item not found page of your online store. It can be found in the StaticPages sub-folder.
LegalDisclosure The legal disclosure of your online store. It can be found in the StaticPages sub-folder.
PageNotFound The Page not found page. It can be found in the StaticPages sub-folder.
PrivacyPolicy The privacy policy of your online store. It can be found in the StaticPages sub-folder.
TermsAndConditions The general terms and conditions of your online store. It can be found in the StaticPages sub-folder.

Making a theme ShopBuilder compatible

You can make your theme compatible with the Shopbuilder with only a few adjustments. You should make sure that the scripts and styles of the ShopBuilder are loaded in the theme and that you provide several Ceres LayoutContainers in there as well. For information on how to create widgets for the ShopBuilder, see this tutorial.

Preparations

{{ get_shop_builder_styles() }}
{{ get_shop_builder_scripts() }}

General info

The ShopBuilder works with 3 different areas where widgets can be placed: the homepage, the header and the footer. Each of these three areas requires the integration of a LayoutContainer. In this container, a dropzone is initialised and all of the widgets that are already placed there are loaded. The user can also add further widgets. The identifiers of these containers are:

  • "Ceres::Homepage"
  • "Ceres::Header"
  • "Ceres::Footer"

See below for further information about each area.

Homepage

{% if config("Ceres.homepage.showShopBuilderContent") == "true" or request.get('isContentBuilder') == 1 %}
    ...
{% endif %}
{% for content in container("Ceres::Homepage") if content.plugin == "Plenty" %}
    {{ content.result | raw }}
{% endfor %}
{% if config("Ceres.homepage.showShopBuilderContent") == "true" or request.get('isContentBuilder') == 1 %}

    {% for content in container("Ceres::Homepage") if content.plugin == "Plenty" %}
        {{ content.result | raw }}
    {% endfor %}

{% endif %}
{% set headerContainer = LayoutContainer.show("Ceres::Header") | trim %}
{% if headerContainer is not empty %}
    {{ headerContainer | raw }}
{% endif %}
{% set footerContainer = LayoutContainer.show("Ceres::Footer") | trim %}
{{ footerContainer | raw }}