While creating cachespec.xml, decision about widgets can be either :
- Do not cache
- Cache separately
- Consume within parent servlet ( cache along with parent JSP )
Do not cache
Widgets like MiniShopCartWidget, InventoryWidget, DiscountWidget etc
will not be cached. An entry in cachespec.xml with attributes do-not-cache and
do-not-consume set to true will be sufficient for these widgets
<cache-entry>
<class>servlet</class>
<name>/Widgets_701/xxx/InventoryAvailability.jsp</name>
<name>/Widgets_701/Common/Discounts/Discounts.jsp</name>
<name>/Widgets_701/xxx/Discounts.jsp</name>
<property name="do-not-consume">true</property>
<property name="do-not-cache">true</property>
<cache-id>
<component id="storeId" type="parameter">
<required>false</required>
</component>
</cache-id>
</cache-entry>
Cache separately
Widgets like productRecommendations, CategoryRecommendations etc can be
cached separately so that it can be reused across layout JSPs. An entry in
cachespec.xml with attribute do-not-consume = true will be sufficient for these
widgets
<cache-entry>
<class>servlet</class>
<name>/Widgets_701/xxxx/BreadcrumbTrail.jsp</name>
<property name="save-attributes">false</property>
<property name="ignore-get-post">true</property>
<property name="consume-subfragments">true</property>
<property name="do-not-consume">true</property> <!-- cache separately.. -->
<property name="do-not-cache">false</property>
<cache-id>
<component id="DC_storeIdentifier" type="attribute">
<required>true</required>
</component>
...
...
</cache-id>
</cache-entry>
Emarketing Widgets
Emarketing spot widgets are handled separately. Since activities associated with eMarketing spots can be dynamic or static, the decision about whether to cache the widget or not should be done dynamically at run time based on the activities associated with widget. So general recommendation is to set do-not-cache = true and do-not-consume = true and let the marketing component decide whether to cache the widget or not and whether to cache separately or consume along with parent servlet.
Also you need to include the following metaDataGenerator in cachespec.xml. This metaDataGenerator will make appropriate decision about caching and adding dependency Ids
<metadatagenerator>
com.ibm.commerce.marketing.cache.EMarketingSpotMetaDataGenerator
</metadatagenerator>
Consuming widgets
Widgets like CatalogEntry widgets can be consumed within the parent layout JSP like CategoryDisplayPage or SubCategoryDisplay pages.
When a widget is consumed by a parent JSP, no entries were made for the consumed JSP in cachespec.xml. But the dependency id's of the consumed JSP were added directly to the parent JSP cache entry in cachespec.xml. So assuming ProductPage imports PriceDisplay.jsp, price:<productId> dependency id was added to ProductPage. Whenever the price of a product changes, price:<productId> invalidation id will be published by server and hence ProdcutPage cache gets invalidated.
When a Store is not using commerce composer tooling, IT developer will create the ProductPage and cachespec.xml. So IT developer will know that productPage consumes PriceDisplay widget and hence adds price dependency id's to the ProductPage cache entry.
But with commerce composer tool, business user has full control over layout widgets and can pick and choose the widgets which goes into layout. So during Code and UT phase, IT developer will have no idea about widgets present in a page and hence cannot add dependency Id's directly to the parent servlet.
For example, assume ProductPage contains price widget and hence developer adds price dependency id to ProductPage entry. Now for some reason, business user removes price widget from the ProductPageLayout widget and adds inventory widget in that slot. Now what happens when price changes ? The entire productPage gets invalidated, even though it doesn't display price. What happens when inventory changes? The page will still be served from cache and it doesn't display the updated inventory status. We cannot expect business user to take help of developers to modify the cachespec.xml as and when he changes the layout widgets.
The answer to this issue is <wcpgl:pageLayoutWidgetCache/> JSTL tag. When this tag gets executed, it adds the dependency id's to the parent servlet cache entry dynamically.
Follow these 3 high level steps to consume the widget with the parent servlet:
- Add <wcfpgl:pageLayoutWidgetCache/> to the main widget JSP.
- Make an entry in cachespec.xml for the widget JSP. Add all the cache-ids and dependency ids for the entry
- Set do-not-consume = true and do-not-cache = true.
Now if the widget is included in the layout by business user, then during runtime, the widget JSP gets executed. Since we have <wcpgl:pageLayoutWidgetCache/> tag inside the widget JSP, this tag gets executed. This tag reads the dependency ids from the cachespec.xml and sets it on the parent servlet. It also resets do-not-consume and do-not-cache values to false.
If the widget is not included in the layout by business user, then widget JSP doesn't get executed and parent page will not contain any additional dependency IDs.
So far so good. But what happens if someone wants to genuinely set do-not-consume and do-not-cache to true. How does someone tell that the values set in cachespec.xml shouldn't be modified by the included <wcfpgl:pageLayoutWidgetCache/> tag. This is where special dependency id ignoreDoNotConsume comes into picture. So if you want to let the pageLayoutWidgetCache tag to reset the do-not-consume and do-not-cache values and add dependency id's to the parent servlet, then add this dependency tag to the widget cache entry in cachespec.xml
<dependency-id>ignoreDoNotConsume</dependency-id>
This special tag tells the pageLayoutWidgetCache handler to ignore the do-not-consume setting on cachespec.xml and reset it to false. If this dependency id is not present, then pageLayoutWidgetCache will not do any additional processing and lets the cache component of application server to handle it appropriately.