import Utils from './utils';
/**
* Init settings by merging various settings:
* boostPFSConfig - in app lib
* boostPFSAppConfig - in snippets/boost-pfs.liquid
* boostPFSThemeConfig - in sections/collection-template.liquid, templates/search.liquid
* boostPFSFilterConfig - in boost-pfs-filter.js
* boostPFSInstantSearchConfig - in boost-pfs-search.js
*/
const init = () => {
var mergedSettings = Settings;
if (typeof boostPFSConfig != 'undefined' && boostPFSConfig.hasOwnProperty('settings') && boostPFSConfig.settings !== null) {
mergedSettings = Utils.mergeObject(mergedSettings, boostPFSConfig.settings);
}
if (typeof boostPFSAppConfig !== 'undefined' && Object.keys(boostPFSAppConfig).length > 0) {
mergedSettings = Utils.mergeObject(mergedSettings, boostPFSAppConfig);
}
if (typeof boostPFSThemeConfig !== 'undefined' && Object.keys(boostPFSThemeConfig).length > 0) {
mergedSettings = Utils.mergeObject(mergedSettings, boostPFSThemeConfig);
}
if (typeof boostPFSFilterConfig !== 'undefined' && Object.keys(boostPFSFilterConfig).length > 0) {
mergedSettings = Utils.mergeObject(mergedSettings, boostPFSFilterConfig);
}
if (typeof boostPFSInstantSearchConfig !== 'undefined' && Object.keys(boostPFSInstantSearchConfig).length > 0) {
mergedSettings = Utils.mergeObject(mergedSettings, boostPFSInstantSearchConfig);
}
// Merge label from translations
if (typeof Shopify !== 'undefined'
&& Shopify.hasOwnProperty('locale')
&& mergedSettings.hasOwnProperty('label')
&& mergedSettings.hasOwnProperty('labelTranslations')
&& mergedSettings.labelTranslations !== undefined
&& mergedSettings.labelTranslations.hasOwnProperty(Shopify.locale)
) {
var labelTranslations = mergedSettings.labelTranslations[Shopify.locale];
mergedSettings.label = Utils.mergeObject(mergedSettings.label || {}, labelTranslations);
}
Settings = mergedSettings;
};
/**
* Get value from setting based on id
* @param {string} id - The setting id, for example 'general.showLoading'
* @returns {string}
*/
const getSettingValue = (id) => {
// If settings are overrided in a specific theme, merge settings's theme with default settings
var result = '';
if (Settings.hasOwnProperty(id)) {
return Settings[id];
} else {
if (id.indexOf('.') > -1) {
var indexArr = id.split('.');
for (var k = 0; k < indexArr.length; k++) {
if (result == '') {
if (Settings.hasOwnProperty(indexArr[k])) {
result = Settings[indexArr[k]];
} else {
return '';
}
} else {
if (result.hasOwnProperty(indexArr[k])) {
result = result[indexArr[k]];
} else {
return '';
}
}
}
}
}
return result;
};
/**
* List of all settings in the app
*/
var Settings = {
general: {
/* Filter Tree Settings */
// Filter tree
enableFilter: true,
filterTreeMobileStyle: 'style2', // 'style2', 'style3'
filterTreeMobileStyleFullWidth: false, // true, false
filterHorizontalColumn: '1', // 1, 2, 3, 'full'
// Refine by
showRefineBy: true, // Show Filter Selections on PC
separateRefineByFromFilter: false, // Place <div class='boost-pfs-filter-refine-by-wrapper-v/h'><div> in the DOM to render refine-by.
refineByHorizontalPosition: 'bottom', // 'bottom', 'top'
// Mobile button
changeMobileButtonLabel: false, // Change label when clicking Refine By button on mobile
breakpointMobile: '767', // Start showing mobile
// Loading icon
showLoading: false, // Show Loading icon when requesting API
showMobileLoading: false, // Show Loading icon on mobile
showLoadMoreLoading: true, // Show Loading icon when infinite loading
positionShowInfiniteLoading: 700,
// Scroll to top
activeScrollToTop: false, // Display Scroll to top button
styleScrollToTop: 'style1', // Color of Scroll to top button: style1(black), style2(gray)
/* Filter Options Settings */
// Filter option general
showSingleOption: true, // True = hide filter option with only one item
showOutOfStockOption: false, // Show Out of Stock filter option
showFilterOptionCount: true, // Display number of product of a filter option
requestInstantly: false, // On Horizontal, make API request when clicking on filter item (no need to click apply)
// Filter option label
capitalizeFilterOptionValues: true, // Only cap 1st leter, change nothing else: hello wORLD => Hello WORLD
forceCapitalizeFilterOptionValues: false, // Lower case then caps 1st letter each word: HELLO World => Hello World
capitalizeFirstLetterFilterOptionValues: false, // Lower case then caps 1 letter only: HELLO World => Hello world
// Filter option collapse
collapseOnPCByDefault: false, // Collapse on PC by default
collapseOnMobileByDefault: false, // Collapse on Mobile by default
keepScrollState: true, // Keep the scroll position of each filter options after filtering
keepToggleState: true, // On vertical, keep the collapsed state after filtering
keepTabOpenState: false, // On horizontal, keep the tab open after applying
// Filter option scroll bar
activeFilterScrollbarPC: true, // Enable scrollbar (on PC)
activeFilterScrollbarMobile: true, // Enable scrollbar (on Mobile)
scrollFirstLoadLength: 24, // Only show x filter item initially, and load more on scroll
// Filter option view more
startViewMore: { list: 5, box: 3, swatch: 10 },
startViewMoreH: { list: 10, box: 20, swatch: 10 }, // This option is used when filterHorizontalColumn = 'full'. Otherwise its (veritical setting x column)
// Filter option - Range slider
removePriceDecimal: true, // Remove '.00'
rangeSliderMoneyFormat: '', // Take shop's moneyFormat if left empty.
oneValueRangeSlider: false, // Show range slider when there's one value
rangeSlidersStyle3: [], // List of filter option id to turn into range slider style3 (text box on bottom)
rangeSlidersSingleHandle: [], // List of filter option id to turn into range slider style4: single handle
advancedRangeSliders: [], // List of filter option id to turn into range slider. Ex: ['pf_t_size', 'pf_t_weight']
shortenPipsRange: false, // Shorten range slider label. Example: 1000 -> 1k
formatPipsRange: [
{ node: 1000, symbol: 'K', fix: 0, suffix: false },
{ node: 1000000, symbol: 'M', fix: 2, suffix: false }
], // Fix: number of decimal: 1k, 1.2k, 1.23k. Suffix: 1.2k (suffix = true) or 1k2 (suffix = false).
enable3rdCurrencySupport: false,
// Filter option - Swatch
imageExtension: ['jpg', 'JPG', 'png', 'PNG', 'jpeg', 'JPEG', 'gif', 'GIF'], // Use to build image URL
swatchStyle: '', // 'circle-grid', 'circle-list', 'square-grid', 'square-list'. Default vertical is 'circle-grid', default horizontal is 'circle-list'
swatchImageVersion: '1111111', // the '?v=' in swatch image URL
removePrefixFromSwatchFile: true, // Remove filter option prefix from swatch file name.
// Filter option - Box
enableFilterOptionBoxStyle: true, // Auto adjust box item width
filterOptionBoxCharWidth: 14, // Calculate box item width based on (character width x label length)
// Filter option - Multi-level
openMultiLevelByDefault: [], // [1] or [1,2] or [2] or []: level to open by default
multiLevelCollectionSelectType: 'single', // Use 'single' or 'multiple' for the tags inside multi level collection
/* Filter API Settings */
// API options
filterPrefixParam: 'pf_', // Default filter prefix param
limit: 16, // Total products per page
vendorParam: 'pf_v_vendor', // Used to build filter query param on vendor page
typeParam: 'pf_pt_product_type', // Used to build filter query param on product type page
priceMode: '', // max: use price_max to build price slider
tagMode: '', // Used in Tag Page - if = 2: apply OR condition if there are multiple tags like this "/Outerwear+Coat+Outerwear-Bomber-Jacket"
// Address bar URL
urlScheme: 1, // 0: dont change url, 1: example 'color=red&color=blue', 2: example 'color=red,blue'
isShortenUrlParam: false, // Use the 'shortenUrlParamList' to shorten param
shortenUrlParamList: [], // List of ['filter_option_id:short_id']. Example: ['pf_otp_color:color', 'pf_t_size:size']. Make sure the values are unique, and don't contain special characters.
/* Filter Product list Settings */
// Product
productAvailable: false, // Return products in stock or not from the first load
variantAvailable: false, // Return variants in stock or not from the first load
availableAfterFiltering: false, // Return products & variants in stock when filter option params exist on the url
loadProductFirst: true, // True = Load product list from Shopify liquid on first load
loadProductFirstBestSelling: false, // True = Load product list from Shopify liquid on first load with sort by 'best-selling'
enableKeepScrollbackPosition: true, // Scroll to the previous position after going back from Product page
addCollectionToProductUrl: true,
showVariantImageBasedOnSelectedFilter: '', // Filter option id to change variant image based on that. Ex: 'pf_opt_color'
// Pagination
paginationType: 'default', // Pagination type: default, infinite, load_more
paginationTypeAdvanced: true, // Append "page" param to url, used to Scroll to the previous position after returning from Product page
activeLoadPreviousPage: false, // active load the previous page feature
sessionStorageCurrentPreviousPage: 'boostPFSCurrentPreviousPage', // integer - the load previous page data: current previous page
sessionStorageCurrentPage: 'boostPFSCurrentPage', // integer - the load previous page data: current page
sessionStorageCurrentNextPage: 'boostPFSCurrentNextPage', // interger - the load previous page data: current next page
sessionStoragePreviousPageEvent: 'boostPFSPreviousPageEvent', // 0 or 1: the load previous page data: current previous page event
// Sorting
sortingList: ['relevance', 'best-selling', 'manual', 'price-ascending', 'price-descending', 'title-ascending', 'title-descending', 'created-descending', 'created-ascending'],
customSortingList: '',
extraSortingList: '',
sortingAvailableFirst: false,
// Limit
showLimitList: '4,8,12,16', // Define number list of Show limit dropdown
// Display
defaultDisplay: 'grid', // Default display type of product list
collageNumber: 3, // Number of product items that is contained in Collage
// Product placeholder
showPlaceholderProductList: false,
placeholderImageRatio: 1.4, //It is used for ratio of image area of Skeleton product item. (height / width)
placeholderProductGridItemClass: '', //In case the theme have grid/list mode, we need to define the classes for Product Grid mode.
placeholderProductPerRow: 3,
// Load product html from liquid
loadProductFromLiquid: false,
loadProductFromLiquidType: 'ajax', // 'ajax': call ajax to the store to get the html, 'sync': sync and return the html from our server
/* OTP Settings */
otpProductItemClass: '', // In case product grid has extra elements that's not product item, make OTP buttons bind to the right element
enableAjaxCart: false,
ajaxCartStyle: 'slide', // 'slide' or 'popup'
showAjaxCartOnAdd: true,
autoCloseMiniCart: false,
autoCloseMiniCartDuration: 2000,
selectOptionInProductItem: false, // Append the quickview's option inside the product item, instead of opening pop up when clicking "select option"
selectOptionContainer: '',
/* Analytics Setting */
enableTrackingOrderRevenue: true,
/* Other settings */
enableSeo: true,
boostCollection: 'boost-all' // A collection handle that we use for full-sync
},
search: {
enableSearch: true,
enableSuggestion: true,
suggestionBlocks: [
{ type: 'suggestions', label: 'Suggestions', status: 'active', number: 3 },
{ type: 'collections', label: 'Collections', status: 'active', number: 2 },
{ type: 'pages', label: 'Pages', status: 'active', number: 2 },
{ type: 'products', label: 'Products', status: 'active', number: 3 },
],
suggesionMaxItems: 10,
suggestionDymLimit: 2,
suggestionMinLength: 1, // The minimum number of characters a user must type before a search is performed
suggestionPosition: '', // left or right
suggestionDelay: 200,
suggestionWidth: 'auto', // auto, fullwidth, number: 100, 200.....
suggestionTypes: [],
suggestionStyle: '', // '', style2
suggestionStyle2MainContainerSelector: 'header:first',
suggestionStyle2ReverseProductBlock: false, // for style2 - swap position of product block and other blocks
suggestionStyle2ProductPerRow: 3, // for style2: 2, 3
suggestionMobileStyle: 'style1', // style1, style2
showSuggestionLoading: true,
showSuggestionProductVendor: true,
showSuggestionProductPrice: true,
showSuggestionProductSalePrice: true,
showSuggestionProductImage: true,
showSuggestionProductSku: false,
showSearchBtnMobile: false,
enableDefaultResult: true,
enableFuzzy: true,
productAvailable: false,
removePriceDecimal: false,
highlightSuggestionResult: true, // Highlight Text in the Search result
openProductNewTab: false, // Open product in the new tab
suggestionMode: 'prod', // prod or test,
termKey: 'q',
skipFields: [],
reduceMinMatch: false, // false (default): results to 85% match. true: results to 50% match. An Integer Number: requires min match exact this number
fullMinMatch: false, // Search results match 100% if the search term has more than 2 words. reduce_min_match will override the full_min_match
enablePlusCharacterSearch: false, // Enable search with Plus character
// Style Suggestion Header
fontSizeSuggestionHeader: '',
bgSuggestionHeader: '',
colorSuggestionHeader: '',
// SEO head-title
enableFixHeadTitle: true,
searchPanelList: ['products', 'collections', 'pages'],
searchPanelDefault: 'products',
searchPanelBlocks: {
'products': {'label': 'Products', 'pageSize': 25, 'active': true},
'collections': {'label': 'Collections', 'pageSize': 25, 'active': false},
'pages': {'label': 'Pages', 'pageSize': 25, 'active': false}
},
suggestionNoResult: {
search_terms: {
label: '"Popular suggestions',
status: true,
data: []
},
products: {
label: 'Products',
status: true,
data: []
}
}
},
init: init,
getSettingValue: getSettingValue,
}
export default Settings;