Skip to content

Commit c189e70

Browse files
authored
Merge pull request #144 from episerver/feature/CMS-44289-global-row-column
Define "_Row" and "_Column" in the registry
2 parents 8d75b44 + f6b438a commit c189e70

File tree

6 files changed

+145
-99
lines changed

6 files changed

+145
-99
lines changed
Lines changed: 2 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,3 @@
1-
import {
2-
BlankSection,
3-
Component1,
4-
Component1A,
5-
Component1B,
6-
Component2,
7-
Component2A,
8-
Component3,
9-
Component3C,
10-
ct1,
11-
ct2,
12-
ct3,
13-
dt1,
14-
dt2,
15-
dt3,
16-
} from '@/components/with-display-templates';
17-
import {
18-
initContentTypeRegistry,
19-
initDisplayTemplateRegistry,
20-
} from '@optimizely/cms-sdk';
21-
import { initReactComponentRegistry } from '@optimizely/cms-sdk/react/server';
1+
import RootLayout from '@/app/en/layout';
222

23-
initContentTypeRegistry([ct1, ct2, ct3]);
24-
initDisplayTemplateRegistry([dt1, dt2, dt3]);
25-
initReactComponentRegistry({
26-
resolver: {
27-
test_c1: {
28-
default: Component1,
29-
tags: {
30-
tagA: Component1A,
31-
tagB: Component1B,
32-
},
33-
},
34-
test_c2: Component2,
35-
'test_c2:tagA': Component2A,
36-
test_c3: {
37-
default: Component3,
38-
tags: {
39-
tagC: Component3C,
40-
},
41-
},
42-
BlankSection: BlankSection,
43-
},
44-
});
45-
46-
export default function RootLayout({
47-
children,
48-
}: Readonly<{
49-
children: React.ReactNode;
50-
}>) {
51-
return (
52-
<html lang="en">
53-
<body>{children}</body>
54-
</html>
55-
);
56-
}
3+
export default RootLayout;

__test__/test-website/src/app/en/layout.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import {
22
BlankSection,
3+
BlankSection2,
4+
Column,
5+
ColumnA,
36
Component1,
47
Component1A,
58
Component1B,
@@ -13,6 +16,11 @@ import {
1316
dt1,
1417
dt2,
1518
dt3,
19+
dt4,
20+
dt5,
21+
dt6,
22+
Row,
23+
RowA,
1624
} from '@/components/with-display-templates';
1725
import {
1826
initContentTypeRegistry,
@@ -21,7 +29,7 @@ import {
2129
import { initReactComponentRegistry } from '@optimizely/cms-sdk/react/server';
2230

2331
initContentTypeRegistry([ct1, ct2, ct3]);
24-
initDisplayTemplateRegistry([dt1, dt2, dt3]);
32+
initDisplayTemplateRegistry([dt1, dt2, dt3, dt4, dt5, dt6]);
2533
initReactComponentRegistry({
2634
resolver: {
2735
test_c1: {
@@ -40,6 +48,15 @@ initReactComponentRegistry({
4048
},
4149
},
4250
BlankSection: BlankSection,
51+
'BlankSection:tagA': BlankSection2,
52+
_Row: {
53+
default: Row,
54+
tags: {
55+
tagA: RowA,
56+
},
57+
},
58+
_Column: Column,
59+
'_Column:tagA': ColumnA,
4360
},
4461
});
4562

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
export const metadata = {
2-
title: 'Next.js',
3-
description: 'Generated by Next.js',
4-
}
1+
import RootLayout from '@/app/en/layout';
52

6-
export default function RootLayout({
7-
children,
8-
}: {
9-
children: React.ReactNode
10-
}) {
11-
return (
12-
<html lang="en">
13-
<body>{children}</body>
14-
</html>
15-
)
16-
}
3+
export default RootLayout;

__test__/test-website/src/app/preview/page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ export default async function Page({ searchParams }: Props) {
1919
)
2020
.catch((err) => {
2121
console.log(err.errors);
22-
console.log(err.request.query);
22+
console.log(err.request);
23+
24+
if (err.request?.query) {
25+
console.log(err.request.query);
26+
}
2327
throw err;
2428
});
2529

__test__/test-website/src/components/with-display-templates.tsx

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,33 @@ export const dt3 = displayTemplate({
6060
tag: 'tagC',
6161
});
6262

63+
export const dt4 = displayTemplate({
64+
key: 'test_dt4',
65+
baseType: '_section',
66+
displayName: 'test dt4',
67+
isDefault: false,
68+
settings: {},
69+
tag: 'tagA',
70+
});
71+
72+
export const dt5 = displayTemplate({
73+
key: 'test_dt5',
74+
nodeType: 'row',
75+
displayName: 'test dt5',
76+
isDefault: false,
77+
settings: {},
78+
tag: 'tagA',
79+
});
80+
81+
export const dt6 = displayTemplate({
82+
key: 'test_dt6',
83+
nodeType: 'column',
84+
displayName: 'test dt6',
85+
isDefault: false,
86+
settings: {},
87+
tag: 'tagA',
88+
});
89+
6390
type Props1 = { opti: Infer<typeof ct1> };
6491
type Props2 = { opti: Infer<typeof ct2> };
6592
type Props3 = { opti: Infer<typeof ct3> };
@@ -106,19 +133,55 @@ export function Component3C({ opti }: Props3) {
106133
);
107134
}
108135

109-
function Row({ children, node }: StructureContainerProps) {
136+
export function Row({ children, node }: StructureContainerProps) {
137+
return (
138+
<>
139+
<h3>This is row (Row) {node.key}</h3>
140+
{children}
141+
</>
142+
);
143+
}
144+
145+
export function Column({ children, node }: StructureContainerProps) {
110146
return (
111147
<>
112-
<h3>This is row {node.key}</h3>
148+
<h4>This is column (Column) {node.key}</h4>
113149
{children}
114150
</>
115151
);
116152
}
117153

118-
function Column({ children, node }: StructureContainerProps) {
154+
export function Row2({ children, node }: StructureContainerProps) {
119155
return (
120156
<>
121-
<h4>This is column {node.key}</h4>
157+
<h3>This is row (Row2) {node.key}</h3>
158+
{children}
159+
</>
160+
);
161+
}
162+
163+
export function Column2({ children, node }: StructureContainerProps) {
164+
return (
165+
<>
166+
<h4>This is column (Column2) {node.key}</h4>
167+
{children}
168+
</>
169+
);
170+
}
171+
172+
export function RowA({ children, node }: StructureContainerProps) {
173+
return (
174+
<>
175+
<h3>This is row (RowA) {node.key}</h3>
176+
{children}
177+
</>
178+
);
179+
}
180+
181+
export function ColumnA({ children, node }: StructureContainerProps) {
182+
return (
183+
<>
184+
<h4>This is column (ColumnA) {node.key}</h4>
122185
{children}
123186
</>
124187
);
@@ -127,8 +190,17 @@ function Column({ children, node }: StructureContainerProps) {
127190
export function BlankSection({ opti }: BlankSectionProps) {
128191
return (
129192
<>
130-
<h2>This is section {opti.key}</h2>
131-
<OptimizelyGridSection nodes={opti.nodes} row={Row} column={Column} />
193+
<h2>This is BlankSection {opti.key}</h2>
194+
<OptimizelyGridSection nodes={opti.nodes} />
195+
</>
196+
);
197+
}
198+
199+
export function BlankSection2({ opti }: BlankSectionProps) {
200+
return (
201+
<>
202+
<h2>This is BlankSection2 {opti.key}</h2>
203+
<OptimizelyGridSection nodes={opti.nodes} row={Row2} column={Column2} />
132204
</>
133205
);
134206
}

packages/optimizely-cms-sdk/src/react/server.tsx

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ type OptimizelyComponentProps = {
7979
/** Display template tag (if any) */
8080
__tag?: string;
8181

82+
displayTemplateKey?: string | null;
83+
8284
/** Preview context */
8385
__context?: { edit: boolean; preview_token: string };
8486

@@ -96,10 +98,9 @@ export async function OptimizelyComponent({
9698
if (!componentRegistry) {
9799
throw new Error('You should call `initReactComponentRegistry` first');
98100
}
99-
101+
const dtKey = opti.composition?.displayTemplateKey ?? opti.displayTemplateKey;
100102
const Component = await componentRegistry.getComponent(opti.__typename, {
101-
tag:
102-
opti.__tag ?? getDisplayTemplateTag(opti.composition?.displayTemplateKey),
103+
tag: opti.__tag ?? getDisplayTemplateTag(dtKey),
103104
});
104105

105106
if (!Component) {
@@ -230,46 +231,60 @@ function FallbackComponent({ children }: { children: ReactNode }) {
230231
}
231232

232233
type OptimizelyGridSectionProps = {
233-
nodes?: ExperienceNode[];
234+
nodes: ExperienceNode[];
234235
row?: StructureContainer;
235236
column?: StructureContainer;
236237
displaySettings?: DisplaySettingsType[];
237238
};
238239

240+
const fallbacks: Record<string, StructureContainer> = {
241+
row: FallbackRow,
242+
column: FallbackColumn,
243+
};
244+
239245
export function OptimizelyGridSection({
240246
nodes,
241-
row = FallbackRow,
242-
column = FallbackColumn,
247+
row,
248+
column,
243249
}: OptimizelyGridSectionProps) {
244-
if (!nodes) {
245-
// TODO: Handle beter
246-
throw new Error('Nodes must be an array');
247-
}
250+
const locallyDefined: Record<string, StructureContainer | undefined> = {
251+
row,
252+
column,
253+
};
254+
248255
return nodes.map((node, i) => {
249-
// get component key(tag) from the display template
250-
const key = getDisplayTemplateTag(node.displayTemplateKey);
251-
// get the parsed display settings (stlyes, classes etc.)
256+
const tag = getDisplayTemplateTag(node.displayTemplateKey);
252257
const parsedDisplaySettings = parseDisplaySettings(node.displaySettings);
253258

254259
if (isComponentNode(node)) {
255260
return (
256261
<OptimizelyComponent
257262
opti={{
258263
...node.component,
259-
__tag: key,
264+
__tag: tag,
260265
}}
261266
key={node.key}
262267
displaySettings={parsedDisplaySettings}
263268
/>
264269
);
265270
}
266271

267-
const { nodes, nodeType } = node;
268-
269-
const mapper: Record<string, StructureContainer> = { row, column };
270-
271-
// TODO: default component
272-
const Component = mapper[nodeType] ?? React.Fragment;
272+
const { nodeType } = node;
273+
const globalNames: Record<string, string> = {
274+
row: '_Row',
275+
column: '_Column',
276+
};
277+
278+
// Pick the component in the following order:
279+
// 1. Explicitly defined in this component
280+
// 2. Globally defined (in the registry)
281+
// 3. Fallback
282+
// 4. React.Fragment
283+
const Component =
284+
locallyDefined[nodeType] ??
285+
componentRegistry.getComponent(globalNames[nodeType], { tag }) ??
286+
fallbacks[nodeType] ??
287+
React.Fragment;
273288

274289
return (
275290
<Component
@@ -278,7 +293,11 @@ export function OptimizelyGridSection({
278293
key={node.key}
279294
displaySettings={parsedDisplaySettings}
280295
>
281-
<OptimizelyGridSection row={row} column={column} nodes={nodes} />
296+
<OptimizelyGridSection
297+
row={row}
298+
column={column}
299+
nodes={node.nodes ?? []}
300+
/>
282301
</Component>
283302
);
284303
});

0 commit comments

Comments
 (0)