Preview Configuration Attributes play a double role in the Storefront Preview Configuration Framework. The first role relates to the configuration process. A Preview Configuration Model is set up using the component framework. A Preview Configuration Model consists of several Preview Configuration Attributes. In
apps.components this Preview Configuration Model is wired to the application.
You can choose from two different Model implementations: MapBasedPreviewConfigurationModel and ListBasedPreviewConfigurationModel. One is a list-based implementation, the other one is map-based (default - shown below). A list-based implementation pertains the order in which Preview Configuration Attributes are wired, but its runtime performance is proportional to the amount of attributes it contains. The (hash) map-based implementation performs better but does not pertain the order of wiring.
... <instance name="intershop.B2CWebShop.PreviewConfigurationModel" with="PreviewConfigurationModel"> <fulfill requirement="configurationAttributeFactory"> <instance with="PreviewDateFactory" /> <instance with="PreviewLocaleFactory" /> <instance with="PreviewCurrencyFactory" /> <instance with="PreviewPromotionFactory" /> <instance with="PreviewUserGroupFactory" /> <instance with="PreviewCampaignFactory" /> <instance with="PreviewABTestGroupFactory" /> <instance with="PreviewTargetUrlFactory" /> <instance with="PreviewApplicationFactory" /> </fulfill> <fulfill requirement="configurationAttributeFactory" with="CatalogCategoryOnlineIgnoredAttributeFactory" /> <fulfill requirement="configurationAttributeFactory" with="ProductOnlineIgnoredAttributeFactory" /> <fulfill requirement="configurationAttributeFactory" with="ProductAvailabilityIgnoredAttributeFactory" /> </instance> ... <instance name="intershop.enfinity.B2CWebShop" with="ApplicationType"> ... <fulfill requirement="namedObject"> <instance with="NamedObject"> <fulfill requirement="name" value="PreviewConfigurationModel" /> <fulfill requirement="object" with="intershop.B2CWebShop.PreviewConfigurationModel" /> </instance> </fulfill> ... </instance>
For each specific
PreviewConfigurationModel needs the corresponding factory. These factories create the
The second role relates to the preview process. An instance of the
PreviewContextBO class is created based on the Preview Configuration Model of the previewed application. Each Preview Configuration Attribute of a
PreviewContextBO instance holds specific information (e.g values) the back office user has given to control a certain storefront preview.
Several specific Preview Configuration Attributes are available. The following table describes the properties which all Preview Configuration Attributes have in common.
Each Preview Configuration Attribute has a unique identifier which is used for access.
An attribute is selected if it contains at least one selected value. The returned value is calculated based on (user or default) selected values.
An attribute is enabled if it is allowed to contain values or if it is not in conflict with any other selected value of depending attribute instances.
An attribute is single-valued if it is only allowed to contain one or zero selected values during its lifetime.
Defines whether the attribute is visible in the back office preview panel.
The (display) group of this attribute. The group is set by the factory that creates this attribute.
PreviewConfigurationAttribute<T> holds a collection of instances of
PreviewConfigurationAttributeValue. Every instance represents a selectable value for the preview configuration process (=Design View). All
PreviewConfigurationAttribute<T> implementations delivered in this release have their own inner class factory implementations to create new instances of themselves. Instances of
PreviewConfigurationAttributeValue hold a semantic giving value object of any given class (T).
PreviewConfigurationAttribute<Date> and holds a single instance of
PreviewConfigurationAttributeValue. The class of this value instance is
PreviewDateAttributeValue holds an instance of the class
Date as semantic giving value.
In contrast to
PreviewLocaleAttribute holds several instances of
PreviewLocaleAttributeValue. Each instance of
PreviewLocaleAttributeValue holds a value object of class
LocaleInformation which stands for an available
LocaleInformation object the user may choose from. One
PreviewLocaleAttributeValue holds the default locale which is always (without user interaction) the selected value for preview.
The following picture gives an overview:
The following table lists all Preview Configuration Attributes available in this release:
Value Object Type
Pipeline Dictionary Keys (mandatory|optional)
The Date being used for storefront rendering.
Its instantiation time
The LocaleInformation being used for storefront rendering.
The target application default locale or the systems lead locale.
The Currency being used for storefront rendering.
The target applications default currency or the systems lead currency.
Conceptually, the back office item to be previewed must be used to create an application-specific URL using the call interface (described later). The implemented attribute is the place where this URL is expected to be stored.
We need this attribute to allow switching between all available applications within the given channel. The target URL of the preview panel must use the URL identifier of the selected application.
The preferred preview application that has been selected in the user profile for the given channel, or the default application of the channel.
To select a frame size in which the previewed application will be displayed, making it possible to display a storefront on limited screen size.
The browser calculated frame size.
Tells the Application that evaluates this setting whether a catalog category that is not online should be rendered or not.
Tells the application that evaluates this setting whether a product that is not online should be rendered or not.
Tells the application that evaluates this setting whether a product that is not available should be available for checkout or not.
Tells the application that evaluates this setting whether a product for which a configured inventory service has delivered a result should be available for checkout or not.
Some of the above-listed Preview Configuration Attributes receive further information from variables found in the pipeline dictionary (Pipeline Dictionary Keys). For instance, in order to determine all consumer groups of a given channel, a
PreviewUserGroups attribute needs to know the channel for which attribute values should be returned. The purpose of
PreviewConfigurationAttributeContext is to allow remapping values from the pipeline dictionary to the internal API PD keys (shown above). A Preview Configuration Attribute can declare depending keys using the
PreviewConfigurationAttributeContextKey annotation. During the creation of
PreviewConfigurationAttributeContext (via pipelet) a lookup will be executed for value existence of all mandatory PD keys of preview configuration attributes contained in the given model. If any value of a mandatory PD key is missing, a pipelet execution exception is thrown. There is no general way to provide these values except the caller of the pipelet has to make sure that all mandatory values of the site's preview configuration model are available.
PreviewConfigurationAttributeContext default implementation can be replaced by your own custom implementation. A factory instance can simply be "wired" using the IS7 componentization framework. The create pipelet is looking for a named instance to create new
PreviewConfigurationAttributeContext objects. bc_preview registers the default implementation in its component files.
The ID value to access the different Preview Configuration Attribute (PCA) objects (e.g. PreviewDateAttribute) has to be maintained by a Java enum type. All PCAs defined in cartridge bc_preview are aggregated in such an enum named
PreviewConfigurationAttributeSet. Each cartridge which defines new Preview Configuration Attributes should follow this example. All pipelets (described below) that work with a particular PCA can use this enum mechanism to identify an object. Your own attribute set enum has to implement
PreviewConfigurationAttributeID and it can automatically be used in all PCA pipelets. To be precise, besides providing the enum class you also have to specify the enum value as a string (e.g.
The following three tables list all pipelets of bc_preview available in this release:
Has Error Connector
Has Error Connector
Returns a PreviewConfigurationAttribute from a PreviewContextBO. The PreviewConfigurationAttribute is selected either by the given PreviewConfigurationAttributeID or by the attribute set enum (described above) in combination with an enum value.
Returns a PreviewConfigurationAttributeID value from a given (PreviewConfiguration)AttributeSet in combination with an AttributeSetValue (which is the enum value)
Deselects all selected values of a
Sets one attribute value of a
Sets several attribute values of a
Get all selected (attribute) values of a preview configuration attribute in the context of the given
Has Error Connector
Creates a new
Returns the found
Removes the given
From a given
This pipelet copies attribute settings from one
PreviewContextcan consist of various
PreviewConfigurationAttributes, there has to be a way to dynamically access them and display them in a preview panel like this:
This concept describes how this can be done.
PreviewConfigurationAttribute - refers to the interface
PreviewConfigurationAttributeValue - refers to the interface
PreviewContextBO - refers to the interface
The following picture outlines the schematic overview:
The picture shows the tactic while getting all
PCA from a given
getPreviewConfigurationAttributes() a list of all available
PCA is fetched. For any of these
PCA a webform file must exist which is looked up. If one is found, the
com.intershop.beehive.emf.webform.FormParameterDefinition in this file is used to create a new
com.intershop.beehive.core.capi.webform.FormParameter which afterwards is put into a newly created
Inside ISML a loop over the form members is performed and an ISML snippet for any contained
FormParameter will be looked up. If again one is found, the
FormParameter will be rendered with this particular ISML snippet (using a <isinclude> call).
So we can make sure that we have a dynamic way of showing the different
PCA and to display them in the proper HTML style (like text inputs, select boxes, radio buttons, ...).
The identifier for all the different parts (webform file, ISML snippet) is always the (unique) ID of the
The name of the webform file has to be the ID of the
PCA. According to the webform "convention", the name of the
FormDefinition has to be the same as the file name, so this also has to be the ID of the
PCA. We do create one webform file for each
PCA, so in every webform file only one
FormParameterDefintion should be present - which will represent the
You can use existing and self-written form validators, both will be supported by the webform framework.
FormParameter can have an object assigned, which represents the value of the
FormParameter. Using the
CreateConfigurationPanelWebform piplet, this object will always be the
PCA behind the parameter type (i.e.
FormParameterDefintion). This fact is important as some information cannot be provided in the
FormParameter but is important for displaying the
PCA in the preview panel (like visible, enabled, ...).
Note that if you want to update a preview webform with values from a submitted HTML form, you need to perform two steps (following the general webform pattern): 1) create a webform and 2) update the webform. For these purposes a pipeline was created, using a number of pipelets (see below).
An enhancement of the
FormParameter class has been created, which is specialized to use a
PCA as its value object. The class inherits any functionality that the
FormParameter provides but in addition it ensures that the value object is of type
PCA. The class is
However, this implementation is added via the
CreateConfigurationPanelWebform to the resulting webform and acts like any other
FormParameter. So no problem occurs when using it within other forms.
To validate the values for a
PreviewFormParameter that are sent within the request, a number of new validators were created. These validators were enhanced to contain a
PrevCon and will be used for validating the request values. Therefore, an interface was created:
The validators are:
PCAis selected using a boolean value
PCAis updated with a collection of values that is part of the
PCAis only updated with one value that is also part of the
PCA - PreviewTargetURL
PCAVobjects according to the webform; this means there is no validation whatsoever.
These validators were defined in the sld_preview/staticfiles/webforms/previewpanel/Preview.webform file, so that they can easily be attached to any form definition.
This pipelet uses a given
PrevCon and builds up a
Form which can be used to display on an HTML page (using ISML code). The pipelet loops over all given
PCA and tries to find corresponding
FormDefinitions with proper
FormParameterDefinitions (see above). The pipelet uses the
PreviewFormParameter class to add to the form, so that it is ensured that the value object is the
This pipelet acts like the existing core pipelet
ValidateForm but a
PrevCon is added to the validation. The reason for this is that some
PCA need the context as their value source for the context validation.
Since 7.3, an additional parameter
ValidatorContextParams of type
Map<String,String> has been added which adds additional configuration parameters as key-value-pairs to the
ValidatorContext. This allows to e.g. provide the preview validators with additional necessary dynamic info for validation.
Note: The pipelet not only validates, it also updates the value of the created form (by using
CreateConfigurationPanelWebform) with all values given within the current request. This means you need to use this pipelet also to get the values from the request into your webform. The pipelet performs two steps: 1) update the webform and 2) validate the values of the webform parameters with the attached value objects (which are
One process pipeline with two start nodes was created to handle webform creation and webform validation. The pipeline is called
ProcessConfigurationPanelWebform, and the start nodes are
Create for creating a new webform and
Update for updating a webform and validating it.
This ISML snippet defines an ISModule that is used to determine the proper ISML snippet for a specific
PreviewFormParameter. The module is defined in
preview/Modules and uses the formParameter, the previewContext and the CurrentRequest as attributes. The form parameter and context are mandatory. If they are not set, the module will not proceed.
Based upon the ID of the formParameter (
formParameter.getID()) the module tries to determine an ISML code snippet with
"preview/" + ID + ".isml". This snippet will be loaded, and the form parameter and context will be passed through.
The form parameter ISML snippets are used to display the
PCA in their proper presentation in an HTML page. The snippets should only contain HTML form elements (like radio buttons, selects and so on) but not a new form declaration itself.
There is a major aspect of these snippets: if the given form parameter is invalid (
formParameter:Invalid EQ 'true'), the values that should be shown shall be taken from the form parameter or from the form parameter's fields - not from the attached value object. The reason for that is that, if you submit a form, the
ValidateConfigurationPanelWebform first validates the submitted string values, and if they are valid, it updates the corresponding
PCA. If they are not valid, they will be set at the form parameter (to show the user the wrong values) but not set at the
PCA. This behavior also means that if the form parameter is valid (
NOT formParameter:Invalid EQ 'true'), you should get the values to display from that attached
PCA as if they represent the current state.
The form parameter ISML snippets should also take care about the
PCA's visibility attributes. If
enabled are set to
false, the webform elements should not be shown. They should either be hidden or not added to the HTML at all.
isPreviewPanelError is created to dynamically display error messages based upon the form parameters that failed in the validation process. The module takes an attribute called previewFormParameter and either shows an error message if an error was defined within that module or tries to load another ISML snippet from the following source:
"preview/error/" + previewFormParameter:ID.
With this module you will be able to create independent ISML snippets to display error messages for failed form parameter validation.
ViewPreviewConfiguration-UpdateSession. The cartridge sld_preview contains such a pipeline. Its only task is to create a new preview context for the receiving storefront application and reload its content with the transferable pieces part of the current request.
If you feel that this solution is a potential risk for your system (live or edit stage), be aware that technically you can switch off the whole preview feature. With a purpose there is no code dependency between an application cartridge and sld_preview.
In addition, the transferable pieces of data are encrypted before transmission.
As described in the present concept document, to create a preview context one necessary step is to provide a none-empty Preview Configuration Attribute Context.
ViewPreviewConfiguration-UpdateSession is executing a call to
ProcessPreviewAttributeContext-CreateConfigurationAttributesMap in order to do that.
With the full site preview function you can open a complete separate browser window and view the storefront with the preview settings given in "Design View".
The values stored in the "Design View" preview context are made persistent using a
PreviewContextPO instance. In preparation of the full site preview the system performs the following steps:
PreviewContextPOobject by using
All of the above-listed processes are incorporated in a pipelet
CreateFullSitePreviewContextBO. The caller of this pipelet must provide a
PreviewContextBORepository value so that the first step is actually hidden behind the create-method of the given value. Now, the
PreviewContextBORepository implementation that actually delivers the creation of a
PreviewContextPO can be accessed via this object path:
PreviewContextBO carries a unique ID (per domain) which is used to identify the created full site preview context. Its value is encrypted and is part of the full site preview URL. The domain name of the source application and their URL identifier, which will be used to identify the source application, are also part of this URL. The preview URL can also be sent via mail or IM.
The goal of full site preview is to create a distraction-free preview of the storefront with a URL that can be shared with others. As explained above, the persistent preview context is identified by a unique ID. This ID value is encrypted for security reasons and must be decrypted prior to the lookup of the object identified.
Getting the full site preview context involves the retrieval of a
PreviewContextBORepository value. This is done using the same object path when creating the full site preview context (chapter above). Obviously finding the correct
ApplicationBO is a prerequisite of full site preview context lookup. This is done via domain name and URL identifier of the source application. Both values are also a part of the Full Site Preview Link.
If the preview for past dates is disabled then the
PreviewContextBORepository uses a
PreviewConfigurationAttributeMapper for the preview date attribute. This mapper does not return the persistently stored preview date if this date refers to the past. Instead, it behaves like an unselected preview date attribute (which means use current time). If the stored preview date refers to the future, it is safe for the mapper to behave like a selected preview date attribute (which means use the fixed time). All that is to guarantee that the preview date is not in the past if the preview for past dates is disabled.
A URL of a created full site preview context can be shared with others. Such URLs just have a certain life time ( 180 days by default) that can be configured via the Preview purge job's attribute set. Log on to the SMC in order to manage the life time of preview links.
These settings are made persistent for each preview and stored as a PreviewContext object in a database. These objects are never updated; instead, a new link implies a new PreviewContext object. As for each preview a new object is created, the related database table might grow very big. This is why a regular cleanup has to be performed. Any obsolete PreviewContext is deleted via a Job Preview Context Cleanup.
The preview purge job is created during dbinit/dbmigrate of cartridge bc_preview_orm. For the parameters configured during creation the job is executed after a definite time interval. A job with the name "Preview Context Cleanup" is introduced that performs a cleanup. The job details are as follows:
The attribute LifeTime is n number of days, any PreviewContext that is n days older than the current date is considered as obsolete by this job.
All job-related artifacts are in cartridge bc_preview_orm. The job pipeline start node ProcessPreviewContextCleanup-Start is a strict node with LifeTime as one of the mandatory parameters. The algorithm of the job is as follows:
The job pipeline first computes the date which needs to be used when retrieving the obsolete PreviewContext objects. The calculation logic is:
ComputedDate = CurrentDate - LifeTime(no of days)
lastmodified < ComputedDate.
To help users out of this misery, an application page fallback has been requested. The concept behind the implementation of this request will be described in this document.
An application switch means that preview settings are always stored per "storefront" application inside a
PreviewContextBO object. As described in other concept papers of storefront preview the configuration model itself is configured at the application type level, leaving the configuration model also application- or application type-specific - e.g., a mobile application might have other display size values than a full-blown storefront. In reaction to this the settings panel has to show only the attributes and values that are valid with regard to a newly selected application -> application switch.
PreviewApplication changes its value. The pipeline that is executed is called
EditView-ChangeApplication. The preview context that is currently "active" (the one where attributes and attribute values are shown in the settings panel) will not be updated by this switch. It just determines the ID of the new application value, semantically speaking that is the
Url-Identifier value. With that value the
Application and the
ApplicationBO can be retrieved. A new
PreviewContextBO based on the
ApplicationBO is created and values of common preview attributes are copied from the "active" context (if attribute has been changed by user). Based on the newly created and synchronized context a webform is created and shown in the settings panel dialog.
For direct item preview we already introduced a call interface that takes the user from any (supported) back office item list or detail page to the position in the storefront where this item is shown. Documentation about this is necessary as this mechanism is only successful if the application developer tells the preview framework where to go. The cookbook explains the required implementation steps in more detail.
The existing interface will contain a new method
public String resolve(String urlString) to resolve a string-based URL and return a new URL capable of executing a storefront call in a new application context.
This class is the reference implementation of an application call interface. Let us concentrate on the
resolve method as this document only explains the concept behind the page fallback.
The internal implementation delegates to a set of configured (i.e., /sld_ch_b2c_app/staticfiles/cartridge/config/applicationcallinterface.properties) classes. Each class is responsible for handling specific "view pipeline" URLs for their associated type. E.g., class
B2CApplicationCallInterfaceProduct tries to resolve URLs that show a product, class
B2CApplicationCallInterfaceCatalogCategory tries to resolve URLs that show a catalog category and so on. It is the responsibility of the application to deliver the logic necessary for such URL conversions.
If the above resolving fails to return a none
null value, it asks the new application context whether or not the pipeline (taken from the method parameter
urlString) exists. An existing pipeline means that the given URL can just be returned. A none-existing pipeline means that a call to the given URL is likely to fail.
At this point only
Default-Start can be resolved as the pipeline that receives the URL call.
The information provided in the Knowledge Base may not be applicable to all systems and situations. Intershop Communications will not be liable to any party for any direct or indirect damages resulting from the use of the Customer Support section of the Intershop Corporate Web site, including, without limitation, any lost profits, business interruption, loss of programs or other data on your information handling system.