Plugin: server side field preprocessing
QA
There is no new feature, we just need to ensure there is no regression:
-
In the BO of Singapore, edit a page, change the content in Quill, insert a new image, save the document -
In the public site, it should be displayed
Implementation
A new backend TS project inside the Quill-editor plugin
- Move the file
quill-delta.tsin a new directoryplugins/quill-editor/backend-src/. - Create a new file
plugins/quill-editor/tsconfig.backend.jsonwith the following content:
{
"compilerOptions": {
"strict": true,
"target": "ES2022",
"module": "CommonJS",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"outDir": "./dist-backend",
},
"include": ["backend-src/**/*.ts"],
}
- In
plugins/quill-editor/package.json, add a script and edit thebuild:
"build": "tsc && vite build && npm run build:backend",
"build:backend": "tsc --project tsconfig.backend.json",
Augment the package: packages/plugin-lib
In quill-delta.ts, we'll have to replace these imports:
import { applyRatioToImageSize, isImageSize } from "@paroicms/server-image-cache-engine";
import { escapeHtml } from "../../../common/mail/html-helpers";
import { platformLog } from "../../../context";
import type { RenderingContext } from "../../../liquidjs-tools/liquidjs-rendering/rendering-context";
import { makeImageAvailable } from "../../../public-payload/make-image-available";
import type { SiteContext } from "../../../site-context/site-context.types";
But the only package we want to import is plugin-lib. Here is what to do:
- Move the file
packages/server-image-cache-engine/src/public-helpers.tsinplugin-lib(export it, then update the imports everywhere it is used) - Move the file
html-helpers.tsinplugin-libtoo - Create a
PluginSiteContextinplugin-lib, with a sub-part ofSiteContext(site-context.types.ts) by copy/paste. It can contain:- fqdn
- siteUrl
- siteSchema
- themeConf
- multilingual
- siteLog (move the interface
AppLoginplugin-lib)
We don't need platformLog, we will use siteContext.siteLog instead.
Do not move the code of makeImageAvailable function: we will use a useImage passed as a parameter instead.
Augment the plugin API
In packages/plugin-lib/types/backend-plugin-types.d.ts, the PluginApi interface, add:
registerFieldProcessor(
dataType: string,
preprocessor: FieldPreprocessor
);
With:
export interface FieldPreprocessorOptions {
absoluteUrls?: boolean;
outputType?: "plainText"
}
export type FieldPreprocessor = (
ctx: FieldPreprocessorContext,
value: unknown,
options?: FieldPreprocessorOptions
) => unknown | Promise<unknown>
export interface FieldPreprocessorContext {
siteContext: PluginSiteContext
useImage(
options: { imageUid: string; size: ImageSize }
): Promise<PublicImage>;
}
Now, implement (in the server) this new API registerFieldProcessor. It should simply keep the field processor in a new map of field processors, in the site context. Add this declaration in SiteContext (site-context.types.ts):
/** The key is the `dataType` */
fieldPreprocessors: Map<string, FieldPreprocessor[]>
In render-delta-fields.ts:
- rename the file to
preprocess-fields.ts - rename
renderQuillDeltaFieldstopreprocessFields - Replace the implementation by:
- create a
FieldPreprocessorContext, with a new callbackuseImagewhich just callsmakeImageAvailable - call the field preprocessors
- create a
- create another function named
preprocessField(singular) for preprocessing a single field
In the plugin, use the new API
Notice: You can look into plugins/video/plugin.cjs, there is an example of code that uses the server API for plugins.
Now, in plugins/quill-editor/plugin.cjs: create a preprocessor function with this implementation:
- if
outputType === "plainText", then callconvertQuillDeltaToPlainTextfromplugins/quill-editor/dist-backend/quill-delta.js(indist-backend/, because it is the compiled version here) - Otherwise, call
convertQuillDeltaToHtml
… and register this new preprocessor function using api.registerFieldProcessor.