|
| 1 | +--- |
| 2 | +group: php-developer-guide |
| 3 | +title: Private content |
| 4 | +redirect_from: |
| 5 | + - /guides/v2.2/config-guide/cache/cache-priv-priv.html |
| 6 | + - /guides/v2.2/config-guide/cache/cache-priv-context.html |
| 7 | + - /guides/v2.2/config-guide/cache/cache-priv-inval.html |
| 8 | +--- |
| 9 | + |
| 10 | +{::options syntax_highlighter="rouge" /} |
| 11 | + |
| 12 | +Since private content is specific to individual users, it is reasonable to handle it on the client side (i.e., web browser). |
| 13 | + |
| 14 | +Use our [customer-data]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Customer/view/frontend/web/js/customer-data.js){:target="_blank"} JS library to store private data in local storage, invalidate private data using customizable rules, and synchronize data with the backend. |
| 15 | + |
| 16 | +This example displays a customer's name on a cacheable page. |
| 17 | + |
| 18 | +## Create a section source {#config-cache-priv-how-source} |
| 19 | + |
| 20 | +The `section source` class is responsible for retrieving data for the section. As a best practice, Magento recommends that you put your code within `Vendor/ModuleName/CustomerData` namespace. Your classes must implement the [`Magento\Customer\CustomerData\SectionSourceInterface`]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Customer/CustomerData/SectionSourceInterface.php){:target="_blank"} interface. |
| 21 | + |
| 22 | +The public method `getSectionData` must return an array with private data. |
| 23 | + |
| 24 | +[Example]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Catalog/CustomerData/CompareProducts.php#L36-L45){:target="_blank"} |
| 25 | + |
| 26 | +Add the following to your component's [dependency injection](https://glossary.magento.com/dependency-injection) configuration (`di.xml`): |
| 27 | + |
| 28 | +```xml |
| 29 | +<type name="Magento\Customer\CustomerData\SectionPoolInterface"> |
| 30 | + <arguments> |
| 31 | + <argument name="sectionSourceMap" xsi:type="array"> |
| 32 | + <item name="custom-name" xsi:type="string">Vendor\ModuleName\CustomerData\ClassName</item> |
| 33 | + </argument> |
| 34 | + </arguments> |
| 35 | +</type> |
| 36 | +``` |
| 37 | + |
| 38 | +## Create a block and template {#config-cache-priv-how-block} |
| 39 | + |
| 40 | +To render private content, create a block and a template to display user-agnostic data; this data is replaced with user-specific data by the [UI component](https://glossary.magento.com/ui-component). |
| 41 | + |
| 42 | +{: .bs-callout-info } |
| 43 | +Do not use the `$_isScopePrivate` property in your blocks. This property is obsolete and will not work properly. |
| 44 | + |
| 45 | +Replace private data in blocks with placeholders (using [Knockout](http://knockoutjs.com/documentation/introduction.html){:target="_blank"} syntax). The init scope on the root element is `data-bind="scope: 'compareProducts'"`, where you define the scope name (`compareProducts` in this example) in your [layout](https://glossary.magento.com/layout). |
| 46 | + |
| 47 | +Initialize the component as follows: |
| 48 | + |
| 49 | +```html |
| 50 | +<script type="text/x-magento-init"> |
| 51 | + {"<css-selector>": {"Magento_Ui/js/core/app": <?php echo $block->getJsLayout();?>}} |
| 52 | +</script> |
| 53 | +``` |
| 54 | +
|
| 55 | +[Example]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Catalog/view/frontend/templates/product/compare/sidebar.phtml#L46-L48){:target="_blank"} |
| 56 | +
|
| 57 | +## Configure a UI component {#config-cache-priv-how-ui} |
| 58 | +
|
| 59 | +The UI component renders block data on the Magento [storefront](https://glossary.magento.com/storefront). To initialize the UI component, you must call the initialization method `_super()`. |
| 60 | +
|
| 61 | +[Example]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js){:target="_blank"} |
| 62 | +
|
| 63 | +All properties are available in the template. |
| 64 | +
|
| 65 | +[Example of defining a UI component in a layout]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Catalog/view/frontend/layout/default.xml#L11-L22){:target="_blank"} |
| 66 | +
|
| 67 | +## Invalidate private content |
| 68 | +
|
| 69 | +Specify actions that trigger cache invalidation for private content blocks in a `sections.xml` configuration file in the `Vendor/ModuleName/etc/frontend` directory. Magento invalidates the cache on a POST or PUT request. |
| 70 | +
|
| 71 | +Customer sections was designed to cache private data in browser storage. This means that any customer section will no be updated until proper action was made. |
| 72 | +
|
| 73 | +The are some exception cases: |
| 74 | +
|
| 75 | +- Store and website switching, after any of these action customer section `cart` will be updated. |
| 76 | +- Customer cart lifetime option `section_data_lifetime` which is 60 minutes by default. After scheduled time passe section `cart` will be updated. |
| 77 | +
|
| 78 | +{: .bs-callout-info } |
| 79 | +Product information will not be simultaneously updated in customer cart (product name, price, product enabled/disabled). Information will be updated after what comes first: `section_data_lifetime` time passed or an action that the update cart triggered. |
| 80 | +
|
| 81 | +The following example adds comments to [app/code/Magento/Catalog/etc/frontend/sections.xml]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Catalog/etc/frontend/sections.xml){:target="_blank"} so you can see what the code is doing. |
| 82 | +
|
| 83 | +```xml |
| 84 | +<?xml version="1.0"?> |
| 85 | +<!-- |
| 86 | +/** |
| 87 | + * Copyright © 2016 Magento. All rights reserved. |
| 88 | + * See COPYING.txt for license details. |
| 89 | + */ |
| 90 | +--> |
| 91 | +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| 92 | + xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd"> |
| 93 | + <!-- invalidates the "compare-products" section when a user |
| 94 | + adds a product to the comparison, resulting in a "catalog/product_compare/add" POST request --> |
| 95 | + <action name="catalog/product_compare/add"> |
| 96 | + <section name="compare-products"/> |
| 97 | + </action> |
| 98 | + <!-- invalidates the section when a customer removes a product from the comparison --> |
| 99 | + <action name="catalog/product_compare/remove"> |
| 100 | + <section name="compare-products"/> |
| 101 | + </action> |
| 102 | + <!-- invalidates the section when a customer clears all products from the comparison --> |
| 103 | + <action name="catalog/product_compare/clear"> |
| 104 | + <section name="compare-products"/> |
| 105 | + </action> |
| 106 | +</config> |
| 107 | +``` |
| 108 | +
|
| 109 | +{: .bs-callout .bs-callout-warning } |
| 110 | +Use only HTTP POST or PUT methods to change state (e.g., adding to a shopping cart, adding to a wishlist, etc.) and do not expect to see caching on these methods. Using GET or HEAD methods might trigger caching and prevent updates to private content. For more information about caching, see [RFC-2616 section 13](https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html){:target="_blank"} |
| 111 | +
|
| 112 | +Other examples: |
| 113 | +
|
| 114 | +- [Checkout]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Checkout/etc/frontend/sections.xml){:target="_blank"} |
| 115 | +- [Customer]({{ site.mage2bloburl }}/{{ page.guide_version }}/app/code/Magento/Customer/etc/frontend/sections.xml){:target="_blank"} |
| 116 | +
|
| 117 | +## Version private content {#config-priv-vers} |
| 118 | +
|
| 119 | +Private content, which is stored in the browser local storage, uses the `private_content_version` cookie to store the version. |
| 120 | +
|
| 121 | +Versioning works as follows: |
| 122 | +
|
| 123 | +1. The user performs some action, such as adding to a cart, that results in an POST or PUT request to the Magento application. |
| 124 | +1. The server generates the `private_content_version` cookie for this user and returns the response to the browser. |
| 125 | +1. Any future HTTP POST or PUT request changes the value of `private_content_version` and this version will be stored in the browser. |
| 126 | +
|
| 127 | +{: .bs-callout .bs-callout-warning } |
| 128 | +Please _note_ that the customer data ivalidation mechanism no longer relies on the `private_content_version`. |
| 129 | +
|
| 130 | +{% include cache/page-cache-checklists.md%} |
0 commit comments