gatsby-core-theme 44.24.0 → 44.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## [44.24.1](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.24.0...v44.24.1) (2026-05-15)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * create a helper ([cb2ed80](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/cb2ed8017d0e54d9601f34227ccb1afba84a58a4))
7
+ * fix conflicts ([289ecb0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/289ecb06016672a5eb57ee335a78ea9d885f1c8c))
8
+ * fix tests ([6aa0c5c](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/6aa0c5c347a53b834ad93f40d66ee7fa5a075cb4))
9
+ * remove unecessary file ([7c45406](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/7c454069a47c049865debf83dffa13c6260479d8))
10
+ * resolve conflicts ([22811c1](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/22811c122fb21b707c0155b44c67a3acf3be25d9))
11
+ * resolve conflicts ([be13f4a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/be13f4a0024cefebf8eb46896f6f41108d199b52))
12
+ * resolve conflicts ([32635fe](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/32635feb30f7cfe1ee3b924e13ff396dd9a1ebbd))
13
+ * search field sensitivity ([f09469e](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/f09469eb08c0d286699ed1a50b2a007ec55f5037))
14
+ * update cleanup function ([48a370a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/48a370a7c28748336633de81e052a1991c64a827))
15
+ * update logic based on reviewer ([140d602](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/140d6026a0d42fa519dac8a094a50b2d42ba9b6f))
16
+ * update logic for short codes ([94269b9](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/94269b9d73cc54eff7867cdba65141e9db23c36f))
17
+ * update operator content shortcodes function ([64cf34f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/64cf34f7c50fbe6c7f17f853f79d295ecbea96cb))
18
+ * update shortcodes ([f3086c6](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/f3086c6b8caf11e186cecca530a0a7a4b96b26e0))
19
+ * update test ([8da172d](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/8da172db188d44f5bb5ea263c638db94572a69b5))
20
+ * update tests ([e3aa47f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/e3aa47f8d0aa0cf81d06c7bf19c16a4d9695691e))
21
+
22
+
23
+ * Merge branch 'EN-374/search-autocomplete-sensitivity' into 'master' ([eead52a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/eead52a1c4764af7253581e0229e18fe98660e59))
24
+ * Merge branch 'en-441-shortcodes' into 'master' ([1ab0088](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/1ab00883fae92dca395e467be511b67ac8c67215))
25
+ * Merge branch 'en-441-shortcodes' into 'master' ([1e9c25b](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/1e9c25bedc376a68025ff2257395cf507004b7b6))
26
+
1
27
  # [44.24.0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.23.2...v44.24.0) (2026-05-06)
2
28
 
3
29
 
package/gatsby-node.mjs CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  generateRedirects,
27
27
  generatePrettyLinkRedirects,
28
28
  } from "./src/resolver/redirect.mjs";
29
- import { translate, is404Page } from "./src/helpers/getters.mjs";
29
+ import { translate, is404Page, mapEntitiesByKey } from "./src/helpers/getters.mjs";
30
30
  import { getArchivePages, hasArchiveModule } from "./src/resolver/archive.mjs";
31
31
  import withDefaults from "./src/helpers/withDefaults.mjs";
32
32
 
@@ -80,6 +80,21 @@ export const createPages = async (
80
80
  preconnectLinks = themeOptions.preconnectLinks || [];
81
81
  console.log(chalk.magenta("info") + chalk.whiteBright(" starting processor"));
82
82
 
83
+ const includeAllOperators = process.env.ENABLE_SHORT_CODES_OPERATOR === "true";
84
+
85
+ const operatorsByShortName = includeAllOperators
86
+ ? mapEntitiesByKey({
87
+ data: operatorData,
88
+ keyField: "operator_id",
89
+
90
+ })
91
+ : {};
92
+
93
+ const gamesByShortName = includeAllOperators ? mapEntitiesByKey({
94
+ data: gamesData,
95
+ keyField: "game_id",
96
+
97
+ }) : {};
83
98
  // add data to modules
84
99
  const processed = processor.run(
85
100
  {
@@ -91,6 +106,10 @@ export const createPages = async (
91
106
  toplists: toplistData,
92
107
  content: contentData,
93
108
  ribbons: ribbonsData,
109
+ ...(includeAllOperators && {
110
+ operators: operatorsByShortName,
111
+ games: gamesByShortName,
112
+ }),
94
113
  relations: {
95
114
  operator: operatorData,
96
115
  payment_method: paymentData,
@@ -106,7 +125,7 @@ export const createPages = async (
106
125
  },
107
126
  themeOptions,
108
127
  fs,
109
- translationsData
128
+ translationsData,
110
129
  );
111
130
  pages = processed.pages;
112
131
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "44.24.0",
3
+ "version": "44.24.1",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -6,6 +6,7 @@ import PropTypes from "prop-types";
6
6
  import { BiSearchAlt } from "@react-icons/all-files/bi/BiSearchAlt";
7
7
  import { IoIosArrowForward } from "@react-icons/all-files/io/IoIosArrowForward";
8
8
  import loadSource from "../../../helpers/search-source";
9
+ import { normalizeForSearch } from "../../../helpers/search";
9
10
  import useTranslate from "~hooks/useTranslate/useTranslate";
10
11
  import { toggleScroll } from "~helpers/scroll";
11
12
  import { getComponent } from "../../../helpers/autocomplete";
@@ -117,8 +118,9 @@ const SearchForm = ({
117
118
  autoCompleteData.current ||
118
119
  (await loadSource(market, "data-simple.json"));
119
120
 
121
+ const normalizedQuery = normalizeForSearch(query);
120
122
  const filtered = autoCompleteData.current.filter((item) =>
121
- item.title.toLowerCase().includes(query.toLowerCase())
123
+ normalizeForSearch(item.title).includes(normalizedQuery)
122
124
  );
123
125
 
124
126
  setFilteredData(filtered.length > 0 ? filtered : null);
@@ -1,7 +1,7 @@
1
1
  import { months } from "./common.mjs";
2
2
 
3
3
  const generatorsPlaceholderRegex =
4
- /\[MONTH\]|\[YEAR\]|\[currentyear\]|\[sitename\]|\[currentmonth\]|\[title\]|\[currentdate\]|\[operator_name]|\[author_name]|\[link\]/gi;
4
+ /\[field=[^\]]+\]|\[MONTH\]|\[YEAR\]|\[currentyear\]|\[sitename\]|\[currentmonth\]|\[title\]|\[currentdate\]|\[operator_name\]|\[author_name\]|\[link\]/gi;
5
5
 
6
6
 
7
7
  const generatorsPlaceholderReplaceObject = (
@@ -1,5 +1,6 @@
1
1
  import generatorsConstant from "../constants/generators.mjs";
2
2
  import trackerTypePerSite from "../constants/trackerTypePerSite.mjs";
3
+ import { resolveOperatorContentShortcode } from "./operatorContentShortcode.mjs";
3
4
 
4
5
  export function generateTrackerLink(operator, trackerType, provider = false) {
5
6
  let defaultTrackerFormat = provider
@@ -43,24 +44,38 @@ export function generateTrackerLink(operator, trackerType, provider = false) {
43
44
  }
44
45
  }
45
46
 
46
- export function generatePlaceholderString(string = "", translations, data) {
47
+ export function generatePlaceholderString(
48
+ string = "",
49
+ translations,
50
+ data,
51
+ operators,
52
+ games,
53
+ ) {
47
54
  const date = new Date();
48
55
  const day = String(date.getDate()).padStart(2, "0");
49
56
  const month = String(date.getMonth() + 1).padStart(2, "0");
50
57
  const year = date.getFullYear();
51
58
  const regex = generatorsConstant.generatorsPlaceholderRegex;
59
+ string = string.replace(/=/g, "=");
52
60
 
53
- return string?.replace(
54
- regex,
55
- (match) =>
61
+ return string?.replace(regex, (match) => {
62
+ const key = match.toLowerCase();
63
+
64
+ if (key.startsWith("[field=")) {
65
+ const result = resolveOperatorContentShortcode(match, operators, games);
66
+ if (result !== null) return result;
67
+ }
68
+
69
+ return (
56
70
  generatorsConstant.generatorsPlaceholderReplaceObject(
57
71
  data,
58
72
  translations,
59
73
  month,
60
74
  day,
61
75
  year,
62
- )[match.toLowerCase()],
63
- );
76
+ )[key] ?? ""
77
+ );
78
+ });
64
79
  }
65
80
 
66
81
  export function generateArray(obj) {
@@ -573,3 +573,17 @@ export const sortArchivePages = (pages, sortBy, sortOrder) =>
573
573
  const dateB = new Date(b[sortBy].replace(" ", "T"));
574
574
  return sortOrder === "ascending" ? dateA - dateB : dateB - dateA;
575
575
  });
576
+
577
+
578
+ export const mapEntitiesByKey = ({ data = {}, keyField }) =>
579
+ Object.values(data).reduce((acc, item) => {
580
+ const key = item?.[keyField];
581
+
582
+ if (!key) return acc;
583
+
584
+ acc[String(key).toLowerCase()] = item;
585
+
586
+
587
+
588
+ return acc;
589
+ }, {});
@@ -0,0 +1,171 @@
1
+ import { resolveOperatorContentShortcode } from "./operatorContentShortcode.mjs";
2
+
3
+ describe("resolveOperatorContentShortcode", () => {
4
+ const operators = {
5
+ 1: {
6
+ id: 1,
7
+ name: "Bet365",
8
+ rating: 5,
9
+ currencies: [{ name: "Euro" }, { name: "USD" }],
10
+ deposit_methods: [{ name: "Visa" }, { name: "Mastercard" }],
11
+ withdrawal_method: [{ name: "Skrill" }, { name: "Neteller" }],
12
+ bonuses: {
13
+ main: {
14
+ one_liner: "100% Bonus + 50 Spins",
15
+ promo_code: "WELCOME",
16
+ terms_and_conditions: "<p>Bonus valid for 7 days</p>",
17
+ categories: [
18
+ { id: 1, name: "Slots Bonus" },
19
+ { id: 2, name: "Live Casino Bonus" },
20
+ ],
21
+ },
22
+ },
23
+ },
24
+
25
+ 2: { id: 2, name: "Unibet", rating: 4 },
26
+ };
27
+
28
+ const games = {
29
+ 10: { id: 10, title: "Book of Dead", provider: "Play'n GO" },
30
+ };
31
+
32
+ test("returns operator field value", () => {
33
+ const match = "[field=name type=operator id=1]";
34
+ const result = resolveOperatorContentShortcode(match, operators, games);
35
+
36
+ expect(result).toEqual("Bet365");
37
+ });
38
+
39
+ test("returns game field value", () => {
40
+ const match = "[field=title type=game id=10]";
41
+ const result = resolveOperatorContentShortcode(match, operators, games);
42
+
43
+ expect(result).toEqual("Book of Dead");
44
+ });
45
+
46
+ test("returns average_rating custom resolver", () => {
47
+ const match = "[field=average_rating type=operator id=1]";
48
+ const result = resolveOperatorContentShortcode(match, operators, games);
49
+
50
+ expect(result).toEqual(5);
51
+ });
52
+
53
+ test("returns currencies names", () => {
54
+ const match = "[field=currencies type=operator id=1]";
55
+ const result = resolveOperatorContentShortcode(match, operators, games);
56
+
57
+ expect(result).toEqual("Euro, USD");
58
+ });
59
+
60
+ test("returns deposit payment methods", () => {
61
+ const match = "[field=deposit_payment_methods type=operator id=1]";
62
+ const result = resolveOperatorContentShortcode(match, operators, games);
63
+
64
+ expect(result).toEqual("Visa, Mastercard");
65
+ });
66
+
67
+ test("returns withdrawal payment methods", () => {
68
+ const match = "[field=withdrawal_payment_methods type=operator id=1]";
69
+ const result = resolveOperatorContentShortcode(match, operators, games);
70
+
71
+ expect(result).toEqual("Skrill, Neteller");
72
+ });
73
+
74
+ test("returns bonus name", () => {
75
+ const match = "[field=bonus_name type=operator id=1]";
76
+ const result = resolveOperatorContentShortcode(match, operators, games);
77
+
78
+ expect(result).toEqual("main");
79
+ });
80
+
81
+ test("returns bonus text", () => {
82
+ const match = "[field=bonus_text type=operator id=1]";
83
+ const result = resolveOperatorContentShortcode(match, operators, games);
84
+
85
+ expect(result).toEqual("100% Bonus + 50 Spins");
86
+ });
87
+
88
+ test("returns promo code", () => {
89
+ const match = "[field=promo_code type=operator id=1]";
90
+ const result = resolveOperatorContentShortcode(match, operators, games);
91
+
92
+ expect(result).toEqual("WELCOME");
93
+ });
94
+
95
+ test("returns stripped terms and conditions", () => {
96
+ const match = "[field=terms_and_conditions type=operator id=1]";
97
+ const result = resolveOperatorContentShortcode(match, operators, games);
98
+
99
+ expect(result).toEqual("Bonus valid for 7 days");
100
+ });
101
+
102
+ test("returns bonus types", () => {
103
+ const match = "[field=bonus_types type=operator id=1]";
104
+ const result = resolveOperatorContentShortcode(match, operators, games);
105
+
106
+ expect(result).toEqual("Slots Bonus, Live Casino Bonus");
107
+ });
108
+
109
+ test("returns empty string when field does not exist", () => {
110
+ const match = "[field=unknown type=operator id=1]";
111
+ const result = resolveOperatorContentShortcode(match, operators, games);
112
+
113
+ expect(result).toEqual("");
114
+ });
115
+
116
+ test("returns null when entity does not exist", () => {
117
+ const match = "[field=name type=operator id=999]";
118
+ const result = resolveOperatorContentShortcode(match, operators, games);
119
+
120
+ expect(result).toBeNull();
121
+ });
122
+
123
+ test("returns null when type is invalid", () => {
124
+ const match = "[field=name type=unknown id=1]";
125
+ const result = resolveOperatorContentShortcode(match, operators, games);
126
+
127
+ expect(result).toBeNull();
128
+ });
129
+
130
+ test("returns null when missing field", () => {
131
+ const match = "[type=operator id=1]";
132
+ const result = resolveOperatorContentShortcode(match, operators, games);
133
+
134
+ expect(result).toBeNull();
135
+ });
136
+
137
+ test("returns null when missing id", () => {
138
+ const match = "[field=name type=operator]";
139
+ const result = resolveOperatorContentShortcode(match, operators, games);
140
+
141
+ expect(result).toBeNull();
142
+ });
143
+
144
+ test("returns null when missing type", () => {
145
+ const match = "[field=name id=1]";
146
+ const result = resolveOperatorContentShortcode(match, operators, games);
147
+
148
+ expect(result).toBeNull();
149
+ });
150
+
151
+ test("handles case-insensitive type", () => {
152
+ const match = "[field=name type=OPERATOR id=1]";
153
+ const result = resolveOperatorContentShortcode(match, operators, games);
154
+
155
+ expect(result).toEqual("Bet365");
156
+ });
157
+
158
+ test("handles numeric id as string internally", () => {
159
+ const match = "[field=rating type=operator id=2]";
160
+ const result = resolveOperatorContentShortcode(match, operators, games);
161
+
162
+ expect(result).toEqual(4);
163
+ });
164
+
165
+ test("returns null for completely invalid shortcode", () => {
166
+ const match = "[random=text]";
167
+ const result = resolveOperatorContentShortcode(match, operators, games);
168
+
169
+ expect(result).toBeNull();
170
+ });
171
+ });
@@ -0,0 +1,68 @@
1
+ const stripHtml = (html = "") => html.replace(/<[^>]*>/g, "").trim();
2
+
3
+ const getMainBonus = (operator) =>
4
+ Object.values(operator.bonuses || {})[0] || {};
5
+
6
+ const operatorFieldResolvers = {
7
+ average_rating: (operator) => operator.rating,
8
+
9
+ currencies: (operator) =>
10
+ operator.currencies?.map((currency) => currency.name).join(", ") || "",
11
+
12
+ deposit_payment_methods: (operator) =>
13
+ operator.deposit_methods?.map((method) => method.name).join(", ") || "",
14
+
15
+ withdrawal_payment_methods: (operator) =>
16
+ operator.withdrawal_method?.map((method) => method.name).join(", ") || "",
17
+
18
+ bonus_name: (operator) => Object.keys(operator.bonuses || {})[0] || "",
19
+
20
+ bonus_text: (operator) => getMainBonus(operator).one_liner || "",
21
+
22
+ promo_code: (operator) => getMainBonus(operator).promo_code || "",
23
+
24
+ terms_and_conditions: (operator) =>
25
+ stripHtml(getMainBonus(operator).terms_and_conditions || ""),
26
+
27
+ bonus_types: (operator) =>
28
+ getMainBonus(operator)
29
+ .categories?.map((category) => category.name)
30
+ .join(", ") || "",
31
+ };
32
+
33
+ // eslint-disable-next-line import/prefer-default-export
34
+ export const resolveOperatorContentShortcode = (match, operators, games) => {
35
+ const fieldMatch = match.match(/field=([^\s\]]+)/i);
36
+ const typeMatch = match.match(/type=([^\s\]]+)/i);
37
+ const idMatch = match.match(/id=(\d+)/);
38
+
39
+ const field = fieldMatch?.[1];
40
+ const type = typeMatch?.[1]?.toLowerCase();
41
+ const id = idMatch?.[1];
42
+
43
+ if (!type || !id || !field) return null;
44
+
45
+ const entityMaps = {
46
+ operator: operators,
47
+ game: games,
48
+ };
49
+
50
+
51
+ if (!entityMaps[type]) return null;
52
+
53
+ const entity = entityMaps[type]?.[String(id).toLowerCase()];
54
+
55
+ if (!entity) return null;
56
+
57
+ if (type === "operator") {
58
+ const customResolver = operatorFieldResolvers[field];
59
+
60
+ if (customResolver) {
61
+ return customResolver(entity);
62
+ }
63
+ }
64
+
65
+ const value = entity[field];
66
+
67
+ return value !== undefined ? value : "";
68
+ };
@@ -46,3 +46,7 @@ export function sortIntOn(key) {
46
46
  return intA - intB;
47
47
  };
48
48
  }
49
+
50
+ export function normalizeForSearch(str) {
51
+ return str.toLowerCase().replace(/\s+/g, "");
52
+ }
@@ -150,7 +150,10 @@ export function processSections(
150
150
  data,
151
151
  toplists,
152
152
  content,
153
- previewPageID
153
+ previewPageID,
154
+ operators = {},
155
+ games = {},
156
+
154
157
  ) {
155
158
  // pageId we will use it just on operator review pages
156
159
  const pageId = page ? page.id : null;
@@ -225,7 +228,9 @@ export function processSections(
225
228
  toplists,
226
229
  content,
227
230
  prefilledMarketModules,
228
- previewPageID
231
+ previewPageID,
232
+ operators,
233
+ games
229
234
  );
230
235
  sections[sectionKey].modules[key] = module;
231
236
  if (module?.filters) {
@@ -334,7 +339,7 @@ export function processExtraFields(
334
339
  });
335
340
  }
336
341
 
337
- function updatePlaceholders(page, data, translationsData) {
342
+ function updatePlaceholders(page, data, translationsData, operators = {}, games = {}) {
338
343
 
339
344
  page.title =
340
345
  page.title &&
@@ -342,6 +347,8 @@ function updatePlaceholders(page, data, translationsData) {
342
347
  siteName: data.site_name,
343
348
  pageTitle: page.title,
344
349
  market: page.market,
350
+ operators,
351
+ games
345
352
  });
346
353
 
347
354
  page.meta_title =
@@ -350,6 +357,7 @@ function updatePlaceholders(page, data, translationsData) {
350
357
  siteName: data.site_name,
351
358
  pageTitle: page.title,
352
359
  market: page.market,
360
+ operators
353
361
  });
354
362
 
355
363
  page.meta_description =
@@ -428,7 +436,7 @@ export default {
428
436
  relations,
429
437
  data.content
430
438
  );
431
- updatePlaceholders(page, generalData, translations);
439
+ updatePlaceholders(page, generalData, translations, data.operators, data.games);
432
440
 
433
441
  // Set Affiliate relations
434
442
  processRelations(
@@ -480,7 +488,9 @@ export default {
480
488
  siteName: generalData.site_name,
481
489
  pageTitle: page.title,
482
490
  market: page.market,
483
- }
491
+ },
492
+ data.operators,
493
+ data.games
484
494
  );
485
495
  }
486
496
 
@@ -633,7 +643,7 @@ export default {
633
643
  )
634
644
  return;
635
645
 
636
- //pre main games section will show only on inactive game page
646
+ // pre main games section will show only on inactive game page
637
647
  const isActiveGamePage = page?.relation?.type === "game" || page?.relation?.status === "active";
638
648
  if (isActiveGamePage && res === "pre_main_games") return;
639
649
 
@@ -659,7 +669,9 @@ export default {
659
669
  null,
660
670
  data.toplists,
661
671
  data.content,
662
- previewPageID
672
+ previewPageID,
673
+ data.operators || {},
674
+ data.games || {}
663
675
  );
664
676
  }
665
677
 
@@ -684,7 +696,9 @@ export default {
684
696
  data,
685
697
  data.toplists,
686
698
  data.content,
687
- previewPageID
699
+ previewPageID,
700
+ data.operators || {},
701
+ data.games || {}
688
702
  ),
689
703
  });
690
704
  }
@@ -476,7 +476,9 @@ export function processContentModule(
476
476
  translations,
477
477
  relationData,
478
478
  content,
479
- previewPageID
479
+ previewPageID,
480
+ operators,
481
+ games
480
482
  ) {
481
483
  module.value = previewPageID
482
484
  ? module.value
@@ -485,7 +487,9 @@ export function processContentModule(
485
487
  module.value = generatePlaceholderString(
486
488
  module.value,
487
489
  translations,
488
- relationData
490
+ relationData,
491
+ operators,
492
+ games
489
493
  );
490
494
 
491
495
  module.value = trailingSlash(module.value);
@@ -497,9 +501,12 @@ export function processContentModule(
497
501
  module.show_more_content = generatePlaceholderString(
498
502
  module.show_more_content,
499
503
  translations,
500
- relationData
504
+ relationData,
505
+ operators,
506
+ games
501
507
  );
502
508
  }
509
+
503
510
  }
504
511
 
505
512
  export function shouldSavePrefilled(module = {}, siteName) {
@@ -513,7 +520,7 @@ export function shouldSavePrefilled(module = {}, siteName) {
513
520
  );
514
521
  }
515
522
 
516
- export function processSpotlightModule(module = {}, content, relations, ribbons, previewPageID) {
523
+ export function processSpotlightModule(module = {}, content, relations, ribbons, previewPageID, translations, relationData, operators, games) {
517
524
  if (module.mode === "sport_odds") {
518
525
  module.items.forEach((item) => {
519
526
  item.relation = relations?.[item.page.relation_id];
@@ -524,9 +531,15 @@ export function processSpotlightModule(module = {}, content, relations, ribbons,
524
531
  item.content = trailingSlash(
525
532
  previewPageID ? item.content : (content && content[item.content]) || ""
526
533
  );
527
- item.text = trailingSlash(
534
+ item.text = generatePlaceholderString(
535
+ trailingSlash(
528
536
  previewPageID ? item.text : (content && content[item.text]) || "",
529
- );
537
+ ),
538
+ translations,
539
+ relationData,
540
+ operators,
541
+ games
542
+ );
530
543
  });
531
544
  }
532
545
 
@@ -540,32 +553,36 @@ export function processCarouselModule(module = {}, content) {
540
553
  return module;
541
554
  }
542
555
 
543
- export function processFaq(module = {}, content, relationData, previewPageID) {
556
+ export function processFaq(module = {}, content, relationData, previewPageID, operators, games) {
544
557
  // eslint-disable-next-line no-unused-expressions
545
558
  module.items &&
546
559
  // eslint-disable-next-line array-callback-return
547
560
  module.items.map((item) => {
548
561
  item.question = trailingSlash(
549
562
  previewPageID
550
- ? generatePlaceholderString(item.question, null, relationData)
563
+ ? generatePlaceholderString(item.question, null, relationData, operators, games)
551
564
  : (content
552
- ? generatePlaceholderString(
553
- content[item.question],
554
- null,
555
- relationData
556
- )
557
- : "") || ""
565
+ ? generatePlaceholderString(
566
+ content[item.question],
567
+ null,
568
+ relationData,
569
+ operators,
570
+ games
571
+ )
572
+ : "") || ""
558
573
  );
559
574
  item.answer = trailingSlash(
560
575
  previewPageID
561
- ? generatePlaceholderString(item.answer, null, relationData)
576
+ ? generatePlaceholderString(item.answer, null, relationData, operators, games)
562
577
  : (content &&
563
- generatePlaceholderString(
564
- content[item.answer],
565
- null,
566
- relationData
567
- )) ||
568
- ""
578
+ generatePlaceholderString(
579
+ content[item.answer],
580
+ null,
581
+ relationData,
582
+ operators,
583
+ games
584
+ )) ||
585
+ ""
569
586
  );
570
587
  });
571
588
  }
@@ -604,16 +621,18 @@ export function processModule(
604
621
  toplists,
605
622
  content,
606
623
  prefilledMarketModules,
607
- previewPageID
624
+ previewPageID,
625
+ operators,
626
+ games
608
627
  ) {
609
628
 
610
629
  module.module_title =
611
630
  module.module_title &&
612
- generatePlaceholderString(module.module_title, translations, relationData);
631
+ generatePlaceholderString(module.module_title, translations, relationData, operators, games);
613
632
  module.title =
614
633
  module.title &&
615
- generatePlaceholderString(module.title, translations, relationData);
616
-
634
+ generatePlaceholderString(module.title, translations, relationData, operators, games);
635
+
617
636
  module.anchor_slug =
618
637
  module.anchor_slug &&
619
638
  generatePlaceholderString(module.anchor_slug, translations, relationData);
@@ -624,7 +643,9 @@ export function processModule(
624
643
  module.module_introduction,
625
644
  translations,
626
645
  relationData,
627
- );
646
+ operators,
647
+ games
648
+ );
628
649
 
629
650
  // See more link
630
651
  if (
@@ -652,7 +673,9 @@ export function processModule(
652
673
  translations,
653
674
  relationData,
654
675
  content,
655
- previewPageID
676
+ previewPageID,
677
+ operators,
678
+ games
656
679
  );
657
680
  } else if (module.name === "bonus") {
658
681
  processBonus(module, relations, data);
@@ -667,11 +690,11 @@ export function processModule(
667
690
  translations
668
691
  );
669
692
  } else if (module.name === "faq") {
670
- processFaq(module, content, relationData, previewPageID);
693
+ processFaq(module, content, relationData, previewPageID, operators, games);
671
694
  } else if (module.name === "anchor") {
672
695
  processAnchor(module, relationData, translations);
673
696
  } else if (module.name === "spotlights") {
674
- processSpotlightModule(module, content, relations?.operator, data?.ribbons, previewPageID);
697
+ processSpotlightModule(module, content, relations?.operator, data?.ribbons, previewPageID, translations, relationData, operators, games);
675
698
  } else if (module.name === "menu" && menus && menus[module.menu_id]) {
676
699
  module = Object.assign(module, menus[module.menu_id]);
677
700
  } else if (module.name === "statistics_counter") {