The plugin cookbook is a collection of recipes for plentymarkets plugin scenarios. On this page, you will find answers to questions that might arise when developing plentymarkets plugins.
By default, content categories are not displayed in the navigation bar of Ceres. If you want to display a category of the Content type in the navigation bar of the online store, you have to change a parameter in one of the Twig templates. You can do this in your own theme or fork of Ceres, or in the plentymarkets back end when using Ceres from plentyMarketplace.
{% set categories = services.category.getNavigationTree("item", lang, 6) %}
.{% set categories = services.category.getNavigationTree("all", lang, 6) %}
.After enabling the other category types in the Ceres online store, create a category of the Content type. The following steps must be taken into account:
Scripts of your plugin defined using the HTML <script>
tag can be added to the scripts of the template plugin Ceres without creating a data provider and linking the content with a template container. Simply extend the ServiceProvider of your plugin and import your script resource into Ceres.
Theme/src/Providers/ThemeServiceProvider.php
<?php namespace Theme\Providers; use IO\Helper\TemplateContainer; use IO\Helper\ResourceContainer; 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.Resources.Import', function (ResourceContainer $container) { // The script is imported in the Footer.twig of Ceres $container->addScriptTemplate('Theme::content.SingleItemScript'); }, self::PRIORITY); } }
ResourceContainer
, the Dispatcher
and Twig
classes.boot()
function and use the dispatcher for listening to the resource import event IO.Resources.Import
. Use the addScriptTemplate()
method and specify the location of your script resource, e.g. a twig template. In this template, use <script>
tags to define the scripts to be added to the scripts of Ceres.
Inline style of your plugin defined using the HTML <style>
tag can be added to the style of the template plugin Ceres without creating a data provider and linking the content with a template container. Simply extend the ServiceProvider of your plugin and import your style resource into Ceres.
Theme/src/Providers/ThemeServiceProvider.php
<?php namespace Theme\Providers; use IO\Helper\TemplateContainer; use IO\Helper\ResourceContainer; 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.Resources.Import', function (ResourceContainer $container) { // The style is imported in the <head> on the PageDesign.twig of Ceres $container->addStyleTemplate('Theme::content.SingleItemStyle'); }, self::PRIORITY); } }
ResourceContainer
, the Dispatcher
and Twig
classes.boot()
function and use the dispatcher for listening to the resource import event IO.Resources.Import
. Use the addStyleTemplate()
method and specify the location of your style resource, e.g. a twig template. In this template, use <style>
tags to define the style information for your plugin.
Contexts provided by your own theme plugin can overwrite and extend the PHP context classes of the template plugin Ceres without creating a data provider and linking the content with a template container. Simply extend the ServiceProvider of your plugin and import your context resource into Ceres.
Theme/Providers/ThemeServiceProvider.php
namespace Theme\Providers; use IO\Helper\TemplateContainer; use Plenty\Plugin\Events\Dispatcher; use Plenty\Plugin\ServiceProvider; use Plenty\Plugin\Templates\Twig; use Theme\Contexts\MyContext; class ThemeServiceProvider extends ServiceProvider { /** * Register the service provider. */ public function register() { } public function boot(Twig $twig, Dispatcher $eventDispatcher) { /** * Extend the context for the basket template with MyContext. */ $eventDispatcher->listen('IO.ctx.basket', function (TemplateContainer $templateContainer, $templateData = []) { $templateContainer->setContext( MyContext::class); return false; }, 0); } }
TemplateContainer
, the Dispatcher
and Twig
classes.boot()
function and use the dispatcher for listening to the context event IO.ctx.TEMPLATENAME
. Specify the template for which you want to modify the context, e.g. IO.ctx.basket
. Use the setContext()
method and specify which context should be used, e.g. MyContext. In your context, define the elements to be added to the PHP context classes of Ceres. You can find an example for how the context class MyContext extends the GlobalContext below.
Theme/src/Contexts/MyContext.php
<?php namespace Theme\Contexts; use IO\Helper\ContextInterface; class MyContext extends GlobalContext implements ContextInterface { public $myVariable; public function init($params) { parent::init($params); $this->myVariable = “This is how you extend context classes.“; } }
extends
elements in your own context.
If you want to add one or multiple custom address fields to the address form of the template plugin Ceres, you can use the template container Additional address fields. Create a plugin that provides the data to be displayed in the container, e.g. with the help of this tutorial. Then add the following code to the .twig
template:
<div class="col-xs-12 col-sm-4"> <div class="input-unit" data-validate="text"> <input type="text" name="town" id="txtPackstationNo${_uid}" v-model="addressData.packstationNo"> <label for="txtPackstationNo${_uid}">Packstation</label> </div> </div>
data-validate="text"
for the property of the String
type.AddressInputGroupDE.twig
file in the Ceres template for further reference.
Template plugins that want to validate address fields using the validators in IO must have a configuration file following certain rules. IO can get the configuration values set in the template plugin and validate addresses based on these settings. The easiest way to do this is to copy part of the config.json
file of Ceres and edit the code. Then, the namespace of the template plugin must be specified in IO.
... { "tab" : "Checkout and My account", "key" : "billing_address.require", "label" : "Enable invoice address field validation", "type" : "multi_select", "possibleValues" : { "billing_address.name1" : "Company", "billing_address.vatNumber" : "VAT number", "billing_address.birthday" : "Date of birth", "billing_address.name4" : "Name affix", "billing_address.address3" : "Additional address 1 / Building name", "billing_address.address4" : "Additional address 2", "billing_address.stateId" : "State" }, "default" : "billing_address.birthday, billing_address.name4, billing_address.address3, billing_address.address4" }, ...
possibleValues
will be validated with the help of the BillingAddressValidator
of IO.
<?php namespace IO\Validators\Customer; use Plenty\Validation\Validator; use IO\Services\TemplateConfigService; class BillingAddressValidator extends Validator { private $requiredFields; public function defineAttributes() { /** * @var TemplateConfigService $templateConfigService */ $templateConfigService = pluginApp(TemplateConfigService::class); $requiredFieldsString = $templateConfigService->get('billing_address.require'); $this->requiredFields = explode(', ', $requiredFieldsString); foreach ($this->requiredFields as $key => $value) { $this->requiredFields[$key] = str_replace('billing_address.', '', $value); } $this->addString('name2', true); $this->addString('name3', true); $this->addString('address1', true); $this->addString('address2', true); $this->addString('postalCode', true); $this->addString('town', true); if(count($this->requiredFields)) { $this->addString('name1', $this->isRequired('name1')); $this->addString('vatNumber', $this->isRequired('vatNumber')); $this->addString('birthday', $this->isRequired('birthday')); $this->addString('name4', $this->isRequired('name4')); $this->addString('address3', $this->isRequired('address3')); $this->addString('address4', $this->isRequired('address4')); $this->addString('stateId', $this->isRequired('stateId')); } } private function isRequired($fieldName) { return in_array($fieldName, $this->requiredFields); } }
If you want to disable the lazy load function in Ceres item lists, simply add a line of code to the <category-image-carousel>
block:
<category-image-carousel template="#vue-category-image-carousel" :image-urls="itemData.images | itemImages imageUrlAccessor" :alt-text="texts | itemName " :item-url="itemData | itemURL" :show-dots=""true"" :show-nav=""false"" :disable-lazy-load="true"> </category-image-carousel>
:disable-lazy-load="true"
has been added.
If you want to add one or multiple custom sorting values to the item sorting drop-down menu of the template plugin Ceres, add the following code in the service provider of your plugin:
<?php namespace Feedback\Providers; ... use Plenty\Plugin\Events\Dispatcher; /** * @param Dispatcher $dispatcher */ public function boot(Dispatcher $dispatcher) { // Add sorting by customer reviews $dispatcher->listen('IO.initAdditionalSorting', function (ItemService $itemService) { // addAdditionalItemSorting(field name, translation key) $itemService->addAdditionalItemSorting('item.feedbackDecimal_desc', 'Feedback::Feedback.customerReviews'); }); }
Event dispatcher
which listens to the itemService
of the plugin IO. For adding a new value, the field name
and translation must be provided.
We created the new helper PHP class BuildHash.php. This class serves to create a hash, which is renewed every time the plugin set is built. That way, the cache can be reset when the plugins are assembled. The global context class in Ceres (/src/Contexts/GlobalContexts.php) provides the global variable "buildHash", which can be used as a GET parameter. The "buildHash" variable can also be used as a suffix for ressource URLs for Javascript, CSS, image ressources, etc. which makes it possible that these ressources are removed from the cache when the plugins are saved and published again.