@progress/sitefinity-nextjs-sdk
Version:
Provides OOB widgets developed using the Next.js framework, which includes an abstraction layer for Sitefinity communication. Additionally, it offers an expanded API, typings, and tools for further development and integration.
148 lines (147 loc) • 7.51 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { RenderPageClient } from './render-page-client';
import { pageLayout } from './utils';
import { RenderWidgetService } from '../services/render-widget-service';
import { RenderLazyWidgetsClient } from './render-lazy-widgets.client';
import { RenderPageScripts } from './render-page-scripts';
import { ServiceMetadata } from '../rest-sdk/service-metadata';
import { headers } from 'next/headers';
import { ErrorCodeException } from '../rest-sdk/errors/error-code.exception';
import { notFound, permanentRedirect, redirect } from 'next/navigation';
import { PageScriptLocation } from '../rest-sdk/dto/scripts';
import { PageFrontEndUtilLoader } from './page-frontend-util-loader';
import { Tracer } from '@progress/sitefinity-nextjs-sdk/diagnostics/empty';
import { getPageNumber } from '../widgets/pager/pager-view-model';
import { ContentListsCommonRestService } from '../widgets/content-lists-common/content-lists-rest.setvice';
import { initServerSideRestSdk } from '../rest-sdk/init';
import { setHostServerContext } from '../services/server-context';
import { initRegistry } from '../editor/widget-framework/widget-registry';
import { widgetRegistry } from '@widgetregistry';
export async function RenderPage({ params, searchParams, relatedFields, templates }) {
const host = headers().get('host') || '';
setHostServerContext(host);
if (!RenderWidgetService.widgetRegistry) {
RenderWidgetService.widgetRegistry = initRegistry(widgetRegistry);
}
let layoutResponse = null;
if (params && params.slug && params.slug.length > 0) {
if (params.slug.some(x => x === '_next') || params.slug[params.slug.length - 1].indexOf('.') !== -1) {
notFound();
}
}
if (searchParams && searchParams['sf-auth']) {
searchParams['sf-auth'] = encodeURIComponent(searchParams['sf-auth']);
}
const { span, ctx } = Tracer.startSpan(`RenderPage ${params.slug.join('/')}`, true);
try {
layoutResponse = await pageLayout({ params, searchParams, relatedFields, traceContext: ctx });
}
catch (error) {
if (error instanceof ErrorCodeException && (error.code === 'NotFound' || error.code === 'Forbidden' || error.code === 'Unauthorized')) {
notFound();
}
}
if (!layoutResponse) {
throw layoutResponse;
}
// nasty hack
if (layoutResponse.isRedirect) {
const redirectResponse = layoutResponse.redirect;
if (redirectResponse.Permenant) {
return permanentRedirect(redirectResponse.Location);
}
else {
return redirect(redirectResponse.Location);
}
}
if (!layoutResponse.layout) {
return notFound();
}
const isEdit = searchParams['sfaction'] === 'edit';
const isPreview = searchParams['sfaction'] === 'preview';
const isLive = !(isEdit || isPreview);
const layout = layoutResponse.layout;
await initServerSideRestSdk({
metadataHash: layout.MetadataHash,
queryParams: {
sf_culture: layout.Culture,
sf_site: isEdit || layout.Site.IsSubFolder ? layout.SiteId : ''
}
});
const appState = {
requestContext: {
layout: layout,
searchParams: searchParams,
detailItem: layout.DetailItem,
culture: layout.Culture,
isEdit,
isPreview,
isLive,
url: params.slug.join('/'),
pageNode: layout.Fields
},
widgets: layout.ComponentContext.Components
};
// get all list widgets
const allWidgets = flattenWidgets(layout.ComponentContext.Components || []);
allWidgets.filter(x => x.Name === 'SitefinityContentList' || x.Name === 'SitefinityDocumentList').forEach(x => {
// try to resolve pagers
const entity = x.Properties;
getPageNumber(entity.PagerMode, appState.requestContext, entity.PagerQueryTemplate, entity.PagerTemplate);
// try to resolve classifications
ContentListsCommonRestService.getClassificationSegment(appState.requestContext);
});
// if not resolved urls => 404
if (layout.UrlParameters && layout.UrlParameters.length > 0 && !layout.DetailItem) {
notFound();
}
const liveUrl = '/' + params.slug.join('/') + '?' + new URLSearchParams(searchParams).toString();
let pageTemplate;
if (layout.TemplateName && templates && templates[layout.TemplateName]) {
let template = templates[layout.TemplateName];
if (template && template.templateFunction) {
const sortedWidgets = {};
appState.widgets.forEach(widget => {
const placeholder = widget.PlaceHolder;
if (!sortedWidgets[placeholder]) {
sortedWidgets[placeholder] = [];
}
sortedWidgets[placeholder].push(RenderWidgetService.createComponent(widget, appState.requestContext, ctx));
});
pageTemplate = template.templateFunction({ widgets: sortedWidgets, requestContext: appState.requestContext });
}
}
if (!pageTemplate) {
pageTemplate = appState.widgets.map((child) => {
return RenderWidgetService.createComponent(child, appState.requestContext, ctx);
});
}
const registryForFrontent = {
widgets: Object.fromEntries(Object.entries(RenderWidgetService.widgetRegistry.widgets).filter(([key, registration]) => {
return !registration.ssr;
}))
};
const registryForEdit = {
widgets: Object.fromEntries(Object.entries(RenderWidgetService.widgetRegistry.widgets).map(([key, registration]) => {
if (!registration.ssr) {
return [key, registration];
}
const reg = {
designerMetadata: registration.designerMetadata,
editorMetadata: registration.editorMetadata,
ssr: registration.ssr,
componentType: null
};
return [key, reg];
}))
};
return (_jsxs(_Fragment, { children: [_jsx(PageFrontEndUtilLoader, { metadata: ServiceMetadata.serviceMetadataCache, taxonomies: ServiceMetadata.taxonomies, additionalQueryParams: { sf_culture: layout.Culture, sf_site: isEdit || layout.Site.IsSubFolder ? layout.SiteId : '' }, registry: registryForFrontent }), _jsx(RenderPageScripts, { layout: layout, scriptLocation: PageScriptLocation.Head }), _jsx(RenderPageScripts, { layout: layout, scriptLocation: PageScriptLocation.BodyTop }), isEdit && _jsx(RenderPageClient, { layout: layout, metadata: ServiceMetadata.serviceMetadataCache, taxonomies: ServiceMetadata.taxonomies, context: appState.requestContext, registry: registryForEdit }), !isEdit && appState.requestContext.layout?.ComponentContext.HasLazyComponents && _jsx(RenderLazyWidgetsClient, { metadata: ServiceMetadata.serviceMetadataCache, taxonomies: ServiceMetadata.taxonomies, url: liveUrl, registry: registryForFrontent }), pageTemplate, _jsx(RenderPageScripts, { layout: layout, scriptLocation: PageScriptLocation.BodyBottom }), Tracer.endSpan(span)] }));
}
function flattenWidgets(widgets) {
return widgets.reduce((acc, widget) => {
if (Array.isArray(widget?.Children) && widget.Children.length) {
return acc.concat(flattenWidgets(widget.Children));
}
return acc.concat([widget]);
}, []);
}