Page Fragments#
Available in version 10.10.00, Fragments are a specialized type of page that can be directly referenced within page templates using the new
Fragments operate at a level above Content Sections, offering the ability to assign items and execute template code. However, they don’t function as fully independent runtime pages—they sit between Content Sections and full pages in terms of capabilities. Fragments are versioned across branches and support item assignment, but they cannot be directly accessed at runtime and do not support caching or URI generation, similar to admin and layout pages.
The ‘Fragments’ tab within the User Interface screen, enables the creation and modification of fragments directly within the admin. Fragments can be copied, but unlike full pages and layouts, they cannot be copied across other page types, maintaining their unique use case within the system
User Interface: Fragments Tab#
A “Fragments” tab within User Interface > Templates tab is available with three default fragments; Global Header (global_header
), Global Footer (global_footer
), and Product List Additional Data (product_list_additional_data
).
Note
Copying a fragment is available however, copying a page/layout to a fragment and vice versa is not supported.
Fragment Items#
Only items implementing the component_frag
feature can be assigned to fragments. This feature requires the implementation of the ComponentModule_Initialize_Fragment
API function, which will be invoked during fragment initialization, before rendering. It’s important to note that modules associated with these items must not raise UI exceptions during initialization, as UI exceptions will not be handled.
Example: ComponentModule_Initialize_Fragment
#
<MvFUNCTION NAME = "ComponentModule_Initialize_Fragment" PARAMETERS = "module var, item, page_all_settings var, page_item_settings var, fragment_all_settings var, fragment_item_settings var, merged_all_settings var, merged_item_settings var" STANDARDOUTPUTLEVEL = "">
<MvASSIGN NAME = "l.merged_item_settings" VALUE = "{ l.fragment_item_settings }">
<MvFUNCTIONRETURN VALUE = "{ ComponentModule_Initialize( l.module, l.item, l.merged_all_settings, l.merged_item_settings ) }">
</MvFUNCTION>
The ComponentModule_Initialize_Fragment
function requires access to the following parameters:
page_all_settings
page_item_settings
fragment_all_settings
fragment_item_settings
merged_all_settings
merged_item_settings
Explicitly passing these settings allows the module to determine how to manage and prioritize them. The merged_all_settings
and merged_item_settings
will be used for rendering the fragment’s template.
There are three common scenarios when ComponentModule_Initialize_Fragment
is invoked:
- Page-Specific Settings: Settings should not be shared across pages/fragments.
- Shared Settings: Settings can be shared across fragments.
- No Specific Settings: The module does not use specific settings.
Scenario 1: Page-Specific Settings Should Not Be Shared#
For example the Sequence Items module, merged_item_settings
(which is a reference within merged_all_settings
) is overwritten with the fragment_item_settings
value. This ensures that the fragment’s specific settings, whether they exist or not, are used when rendering the fragment. Once the settings are configured, the ComponentModule_Initialize
function is called.
Scenario 2: Shared Settings#
For modules that initialize settings based on non-page/non-fragment-specific data (e.g., Country Selector, Address Book), settings should only be initialized if the top-level page settings haven’t already done so. This check is performed using the TemplateManager_Item_Initialized
function. If the item has not been initialized, ComponentModule_Initialize
should be called. Otherwise, the settings in merged_all_settings
and merged_item_settings
will be used, and they will be accessible in the fragment template.
Scenario 3: No Specific Settings#
Modules like CSSUI Head Tag Content and CSSUI HTML Profile do not rely on page-specific settings. These modules can directly call ComponentModule_Initialize_Fragment
without additional checks.
Default Fragments#
Global Header and Footer#
The Global Header and Global Footer fragments have the sequence
and flex
items assigned as well as the sequence
item rendered on the template. These fragments are then rendered in the Global Header and Global Footer templates within the Global Settings. For more information on this section please view the Global Flex Component documentation here.
Product List Additional Data#
This page fragment is used in conjunction with the MMX Product Carousel, MMX Featured Product, and MMX Product List flex components to render Affirm’s “As Low As” feature. Previously, it wasn’t feasible to render Affirm’s “As Low As” pricing display for dynamically loaded products because the products were loaded in runtime through an AJAX function and the data was not available in that function. With the addition of Page Fragments and their ability to be rendered via Runtime_ProductList_Load_Query
using filters, we can now efficiently utilize a fragment to render Affirm’s “mvaffirm_configuration” content section.
Public Fragments#
When editing fragments a “Public” checkbox is displayed. This checkbox controls whether the fragment can be rendered as part of the Runtime JSON API functions (Runtime_ProductList_Load_Query and variants). When “Public” is left unchecked the fragment will not be rendered by the Runtime API functions. The “Public” checkbox has no affect on whether a fragment is rendered or not when called from template code.
This checkbox works in a similar fashion to the “Public” custom fields that were added as part of Miva Merchant 10.05.00.
Syntax#
Fragments can be referenced in template code using the following syntax where the code
value is the code of the fragment. Additionally, the share
attribute allows data sharing between the caller of the fragment and the fragment itself.
<mvt:fragment code="xxx" />
<mvt:fragment code="xxx" share="member" />
<mvt:fragment code="xxx" share="member1:member2" />
<mvt:fragment code="xxx" share="global:member" />
<mvt:fragment code="xxx" share="global:member1:member2" />
code
: [Required] This value represents the fragment code.share
: [Optional] Variable to be used to share data between the page and fragment. Data can be shared bidirectionally.
share
Attribute#
The share
parameter works in a similar fashion to the the <mvt:foreach />
array attribute. If the value is prefixed with the keyword global
the variable will be a global variable, otherwise a local variable of the l.settings
will be created. The specified page share variable will always be linked to l.settings:fragment:share
within the fragment page. See examples below.
Simple fragment#
<mvt:fragment code="xxx" />
Fragment with local share#
<mvt:fragment code="xxx" share="shared_data" />
&mvt:shared_data;
<mvt:eval expr="l.settings:shared_data" />
Fragment with local share (nested members)#
<mvt:fragment code="xxx" share="shared_data:member1:member2:member3" />
&mvt:shared_data:member1:member2:member3;
<mvt:eval expr="l.settings:shared_data:member1:member2:member3" />
Fragment with global share#
<mvt:fragment code="xxx" share="global:shared_data" />
&mvt:global:shared_data;
<mvt:eval expr="g.shared_data" />
Fragment with global share (nested members)#
<mvt:fragment code="xxx" share="global:shared_data:member1:member2:member3" />
&mvt:global:shared_data:member1:member2:member3;
<mvt:eval expr="g.shared_data:member1:member2:member3" />
Share between page and fragment#
page - pre-fragment call#
<mvt:assign name="l.settings:shared_data" value="'hello world'" />
<mvt:fragment code="xxx" share="shared_data" />
fragment#
&mvt:fragment:share; <mvt:comment> outputs "hello world" </mvt:comment>
<mvt:assign name="l.settings:fragment:share" value="'super duper'" />
page - post-fragment call#
&mvt:shared_data; <mvt:comment> outputs "super duper" </mvt:comment>
Fragments can be referenced from any interpreted template, including standard pages, layouts, and fragment-specific templates.
StoreMorph Tokens#
The fragment settings will contain both the page and fragment page record. The page settings will contain the page record of the runtime page. In the case the fragment was not executed by a runtime page (i.e. via Runtime_ProductList_Load_Query
) the page settings will be blank. The fragment settings will contain the page record of the fragment being executed.
l.settings:page:id
l.settings:page:templ_id
l.settings:page:version_id
l.settings:page:admin
l.settings:page:code
l.settings:page:name
l.settings:page:title
l.settings:page:xref_id
l.settings:page:user_id
l.settings:page:layout
l.settings:page:fragment
l.settings:page:secure
l.settings:page:public
l.settings:page:ui_id
l.settings:page:cache
l.settings:page:cacheset
l.settings:fragment:id
l.settings:fragment:templ_id
l.settings:fragment:version_id
l.settings:fragment:admin
l.settings:fragment:code
l.settings:fragment:name
l.settings:fragment:title
l.settings:fragment:xref_id
l.settings:fragment:user_id
l.settings:fragment:layout
l.settings:fragment:fragment
l.settings:fragment:secure
l.settings:fragment:public
l.settings:fragment:ui_id
l.settings:fragment:cache
l.settings:fragment:cacheset
PageBuilder Support#
Page Builder will be utilizing page fragments within specific components to render global content. By default the Product Carousel component will include the fragment for rendering extra product content from Affirm.
The flex component fragment
property will allow you to dynamically select different fragments to be included within a flex component (either via the template or through a dynamic runtime loader like Runtime_ProductList_Load_Query
). The fragment
property can be found on the mmx-product-carousel
flex component.
Provisioning#
<Page_Add>
<Fragment>true/false</Fragment> <!-- Optional, default to 0, only one of admin, layout, fragment can be set at once -->
</Page_Add>
<Page_Update code="xxx">
<Fragment>true/false</Fragment> <!-- Optional, default to 0, only one of admin, layout, fragment can be set at once -->
</Page_Update>
<CopyPageRules_Add>
<Public>1/0/true/false/yes/no</Public>
</CopyPageRules_Add>
<CopyPageRules_Update name="xxx">
<Public>1/0/true/false/yes/no</Public>
</CopyPageRules_Update>
API Support#
The Runtime_ProductList_Load_Query
and PageList_Load_Query
API functions support fragments. To use, add the fragments
filter with a comma separated list of fragments to your JSON request. The PageList_Load_Query
will return fragment
with a true
/false
value and the Runtime_ProductList_Load_Query
will return the values of each fragment requested.
Example Request#
{
"Store_Code": "STORE_CODE",
"Function": "Runtime_ProductList_Load_Query",
"Session_Type": "runtime",
"Filter": [
{
"name": "fragments",
"value": [
"fragment_1",
"fragment_2",
"fragment_3"
]
}
]
}
Example Runtime_ProductList_Load_Query
Response#
{
"code": "product1",
...
"fragments": {
"fragment_1": "this is my cool fragment referencing product1",
"fragment_2": "this is my second cool fragment referencing product1",
"fragment_3": "this is my third cool fragment referencing product1",
...
}
}
Example PageList_Load_Query
Response#
{
...
"layout": false,
"fragment": false,
"secure": true,
"public": false,
...
}
Additional Notes#
- Fragments can be nested so care should be taken to not create recursive references as this could crash the server
- Care should be taken to avoid outputting / calculating sensitive content in public fragments