Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

Commit 8655b1d

Browse files
authored
Merge pull request #5547 from eduard13/patch-layout-plugin
Replacing the layout existing plugin with a proper one
2 parents 73e2228 + 9909ce1 commit 8655b1d

File tree

2 files changed

+86
-154
lines changed

2 files changed

+86
-154
lines changed

guides/v2.2/frontend-dev-guide/layouts/xml-manage.md

Lines changed: 43 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -407,101 +407,67 @@ class Class implements \Magento\Framework\View\Element\Block\ArgumentInterface
407407
}
408408
```
409409

410-
## Modify functionality with plugins (interceptors) {#layout_markup_modify_with_plugins}
410+
## Modify layout with plugins (interceptors) {#layout_markup_modify_with_plugins}
411411

412-
To substitute or extend the behavior of original, public methods for any class or interface, we can make use of plugins, or interceptors, which are classes that modify the behavior of public class functions by intercepting a function call and running code before, after, or around that function call in the form of listeners.
412+
Plugins can be also useful, when we need to make some layout updates.
413+
Here is an example of how a css class can be added to `<body>` tag on product view page.
413414

414-
This interception approach reduces conflicts among extensions that change the behavior of the same class or method, with a Plugin class implementation changing only the behavior of a class function, rather than overriding the entire class.
415-
416-
In order to use plugins (interceptors), we must first define them in the di.xml of the module:
417-
418-
```xml
419-
<config>
420-
<type name="{ObservedType}">
421-
<plugin name="{pluginName}" type="{PluginClassName}" />
422-
</type>
423-
</config>
424-
```
425-
426-
Before listeners are used whenever we want to change the arguments of an original method or wish to add additional behavior before an original method is called. They do not need a return value.
427-
428-
Around listeners are used when we want to change both the arguments and the returned values of an original method or add new behavior before and after an original method is called. Because of this, return values are required.
429-
430-
After listeners are used when we want to change the values returned by an original method or want to add some behavior after an original method is called. As such, they also require return values.
431-
432-
Let us say we want to change the behavior of an addProduct method in the Magento\Checkout\Model\Cart module by adding plugins. We first define the di.xml of this module as the following:
415+
> `etc/frontend/di.xml`
433416
434417
```xml
435-
<config>
436-
<type name="Magento\Checkout\Model\Cart">
437-
<plugin name="MagentoCart" type="Company\Sample\Model\Cart" />
438-
</type>
418+
<?xml version="1.0"?>
419+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
420+
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
421+
<type name="Magento\Catalog\Helper\Product\View">
422+
<plugin name="add_custom_body_class_to_product_page"
423+
type="OrangeCompany\Learning\Plugin\AddBodyClassToProductPagePlugin"/>
424+
</type>
439425
</config>
440426
```
441427

442-
Now in the Company\Sample\Model\Cart directory, we will create our plugin in a file we will call Cart.php. To call the before listener, it is customary to add the prefix 'before' to the method name, meaning we can call something like the following:
428+
> `OrangeCompany/Learning/Plugin/AddBodyClassToProductPagePlugin.php`
443429
444430
```php
445431
<?php
446432

447-
namespace Company\Sample\Model;
448-
449-
class Cart
450-
{
451-
public function beforeAddProduct(
452-
\Magento\Checkout\Model\Cart $subject,
453-
$productInfo,
454-
$requestInfo = null
455-
) {
456-
$requestInfo['qty'] = 10; // increasing quantity to 10
457-
return array($productInfo, $requestInfo);
458-
}
459-
}
460-
```
461-
462-
Often we use before listeners when we want to change parameters of a method. In this case, we are setting the quantity to 10, meaning it will now always add 10 of a product whenever a product is added to the cart.
433+
namespace OrangeCompany\Learning\Plugin;
463434

464-
If we wanted to add an around listener to the same addProduct method, we could use the same file. Since we want to call an around listener, we would want to add the prefix 'around' to the method name, giving us the following:
435+
use Magento\Catalog\Helper\Product\View as ProductViewHelper;
436+
use Magento\Framework\View\Result\Page;
465437

466-
```php
467-
<?php
468-
469-
namespace Company\Sample\Model;
470-
471-
class Cart
438+
/**
439+
* Class AddBodyClassToProductPagePlugin
440+
*/
441+
class AddBodyClassToProductPagePlugin
472442
{
473-
public function aroundAddProduct(
474-
\Magento\Checkout\Model\Cart $subject,
475-
\Closure $proceed,
476-
$productInfo,
477-
$requestInfo = null
478-
) {
479-
$requestInfo['qty'] = 10; // setting quantity to 10
480-
$result = $proceed($productInfo, $requestInfo);
481-
// change result here
482-
return $result;
443+
/**
444+
* Adding a custom class to body
445+
*
446+
* @param ProductViewHelper $subject
447+
* @param Page $resultPage
448+
* @param $product
449+
* @param $params
450+
*
451+
* @return array
452+
*/
453+
public function beforeInitProductLayout(
454+
ProductViewHelper $subject,
455+
Page $resultPage,
456+
$product,
457+
$params
458+
): array {
459+
$pageConfig = $resultPage->getConfig();
460+
461+
if (/*add your logic here*/) {
462+
$pageConfig->addBodyClass('my-new-body-class');
463+
}
464+
465+
return [$resultPage, $product, $params];
483466
}
484467
}
485468
```
486469

487-
For an around listener, the return value is formed in such way that the parameters following the $closure parameter in the around listener method definition are passed to the $closure function call in a sequential order.
488-
489-
Finally, let us say that we want to change the behavior of the getName method of Magento\Catalog\Model\Product with an after listener. Assuming we have properly set the di.xml file of the Magento\Catalog\Model\Product module with the plugin, we can create a file called Product.php in the Company\Sample\Model.
490-
491-
Similar to the other listeners, an after listener is usually called by adding a designated prefix, which is ‘after’ in this case, to the method name. We can then get the corresponding after listener for our getName method:
492-
493-
```php
494-
<?php
495-
496-
namespace Company\Sample\Model;
497-
498-
class Product
499-
{
500-
public function afterGetName(\Magento\Catalog\Model\Product $subject, $result) {
501-
return "Apple ".$result; // Adding Apple in product name
502-
}
503-
}
504-
```
470+
As result, the `<body>` tag has a new `my-new-body-class` class on all product pages.
505471

506472
## Manage the 'My Account' dashboard navigation links
507473

guides/v2.3/frontend-dev-guide/layouts/xml-manage.md

Lines changed: 43 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -410,101 +410,67 @@ class Class implements \Magento\Framework\View\Element\Block\ArgumentInterface
410410
}
411411
```
412412

413-
## Modify functionality with plugins (interceptors) {#layout_markup_modify_with_plugins}
413+
## Modify layout with plugins (interceptors) {#layout_markup_modify_with_plugins}
414414

415-
To substitute or extend the behavior of original, public methods for any class or interface, we can make use of plugins, or interceptors, which are classes that modify the behavior of public class functions by intercepting a function call and running code before, after, or around that function call in the form of listeners.
415+
Plugins can be also useful, when we need to make some layout updates.
416+
Here is an example of how a css class can be added to `<body>` tag on product view page.
416417

417-
This interception approach reduces conflicts among extensions that change the behavior of the same class or method, with a Plugin class implementation changing only the behavior of a class function, rather than overriding the entire class.
418-
419-
In order to use plugins (interceptors), we must first define them in the di.xml of the module:
420-
421-
```xml
422-
<config>
423-
<type name="{ObservedType}">
424-
<plugin name="{pluginName}" type="{PluginClassName}" />
425-
</type>
426-
</config>
427-
```
428-
429-
Before listeners are used whenever we want to change the arguments of an original method or wish to add additional behavior before an original method is called. They do not need a return value.
430-
431-
Around listeners are used when we want to change both the arguments and the returned values of an original method or add new behavior before and after an original method is called. Because of this, return values are required.
432-
433-
After listeners are used when we want to change the values returned by an original method or want to add some behavior after an original method is called. As such, they also require return values.
434-
435-
Let us say we want to change the behavior of an addProduct method in the Magento\Checkout\Model\Cart module by adding plugins. We first define the di.xml of this module as the following:
418+
> `etc/frontend/di.xml`
436419
437420
```xml
438-
<config>
439-
<type name="Magento\Checkout\Model\Cart">
440-
<plugin name="MagentoCart" type="Company\Sample\Model\Cart" />
441-
</type>
421+
<?xml version="1.0"?>
422+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
423+
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
424+
<type name="Magento\Catalog\Helper\Product\View">
425+
<plugin name="add_custom_body_class_to_product_page"
426+
type="OrangeCompany\Learning\Plugin\AddBodyClassToProductPagePlugin"/>
427+
</type>
442428
</config>
443429
```
444430

445-
Now in the Company\Sample\Model\Cart directory, we will create our plugin in a file we will call Cart.php. To call the before listener, it is customary to add the prefix 'before' to the method name, meaning we can call something like the following:
431+
> `OrangeCompany/Learning/Plugin/AddBodyClassToProductPagePlugin.php`
446432
447433
```php
448434
<?php
449435

450-
namespace Company\Sample\Model;
451-
452-
class Cart
453-
{
454-
public function beforeAddProduct(
455-
\Magento\Checkout\Model\Cart $subject,
456-
$productInfo,
457-
$requestInfo = null
458-
) {
459-
$requestInfo['qty'] = 10; // increasing quantity to 10
460-
return array($productInfo, $requestInfo);
461-
}
462-
}
463-
```
464-
465-
Often we use before listeners when we want to change parameters of a method. In this case, we are setting the quantity to 10, meaning it will now always add 10 of a product whenever a product is added to the cart.
436+
namespace OrangeCompany\Learning\Plugin;
466437

467-
If we wanted to add an around listener to the same addProduct method, we could use the same file. Since we want to call an around listener, we would want to add the prefix 'around' to the method name, giving us the following:
438+
use Magento\Catalog\Helper\Product\View as ProductViewHelper;
439+
use Magento\Framework\View\Result\Page;
468440

469-
```php
470-
<?php
471-
472-
namespace Company\Sample\Model;
473-
474-
class Cart
441+
/**
442+
* Class AddBodyClassToProductPagePlugin
443+
*/
444+
class AddBodyClassToProductPagePlugin
475445
{
476-
public function aroundAddProduct(
477-
\Magento\Checkout\Model\Cart $subject,
478-
\Closure $proceed,
479-
$productInfo,
480-
$requestInfo = null
481-
) {
482-
$requestInfo['qty'] = 10; // setting quantity to 10
483-
$result = $proceed($productInfo, $requestInfo);
484-
// change result here
485-
return $result;
446+
/**
447+
* Adding a custom class to body
448+
*
449+
* @param ProductViewHelper $subject
450+
* @param Page $resultPage
451+
* @param $product
452+
* @param $params
453+
*
454+
* @return array
455+
*/
456+
public function beforeInitProductLayout(
457+
ProductViewHelper $subject,
458+
Page $resultPage,
459+
$product,
460+
$params
461+
): array {
462+
$pageConfig = $resultPage->getConfig();
463+
464+
if (/*add your logic here*/) {
465+
$pageConfig->addBodyClass('my-new-body-class');
466+
}
467+
468+
return [$resultPage, $product, $params];
486469
}
487470
}
488471
```
489472

490-
For an around listener, the return value is formed in such way that the parameters following the $closure parameter in the around listener method definition are passed to the $closure function call in a sequential order.
491-
492-
Finally, let us say that we want to change the behavior of the getName method of Magento\Catalog\Model\Product with an after listener. Assuming we have properly set the di.xml file of the Magento\Catalog\Model\Product module with the plugin, we can create a file called Product.php in the Company\Sample\Model.
493-
494-
Similar to the other listeners, an after listener is usually called by adding a designated prefix, which is ‘after’ in this case, to the method name. We can then get the corresponding after listener for our getName method:
495-
496-
```php
497-
<?php
498-
499-
namespace Company\Sample\Model;
500-
501-
class Product
502-
{
503-
public function afterGetName(\Magento\Catalog\Model\Product $subject, $result) {
504-
return "Apple ".$result; // Adding Apple in product name
505-
}
506-
}
507-
```
473+
As result, the `<body>` tag has a new `my-new-body-class` class on all product pages.
508474

509475
## Manage the 'My Account' dashboard navigation links
510476

0 commit comments

Comments
 (0)