diff --git a/CHANGELOG.md b/CHANGELOG.md index a672d4503..9bdbf5e1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ #### For plugin authors * New `expressPreSession` server-side hook. +* New `padDefaultContent` server-side hook. * New APIs for processing attributes: `ep_etherpad-lite/static/js/attributes` (low-level API) and `ep_etherpad-lite/static/js/AttributeMap` (high-level API). diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index a5b153f56..4ee35f920 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -216,6 +216,31 @@ Context properties: * `authorId`: The ID of the author who created the pad. * `author` (**deprecated**): Synonym of `authorId`. +## `padDefaultContent` + +Called from `src/node/db/Pad.js` + +Called to obtain a pad's initial content, unless the pad is being created with +specific content. The return value is ignored; to change the content, modify the +`content` context property. + +This hook is run asynchronously. All registered hook functions are run +concurrently (via `Promise.all()`), so be careful to avoid race conditions when +reading and modifying the context properties. + +Context properties: + +* `pad`: The newly created Pad object. +* `authorId`: The author ID of the user that is creating the pad. +* `type`: String identifying the content type. Currently this is `'text'` and + must not be changed. Future versions of Etherpad may add support for HTML, + jsdom objects, or other formats, so plugins must assert that this matches a + supported content type before reading `content`. +* `content`: The pad's initial content. Change this property to change the pad's + initial content. If the content type is changed, the `type` property must also + be updated to match. Plugins must check the value of the `type` property + before reading this value. + ## `padLoad` Called from: `src/node/db/PadManager.js` diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index 218bf5c5e..c68e6e271 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -372,11 +372,6 @@ Pad.prototype.getChatMessages = async function (start, end) { }; Pad.prototype.init = async function (text, authorId = '') { - // replace text with default text if text isn't set - if (text == null) { - text = settings.defaultPadText; - } - // try to load the pad const value = await this._db.get(`pad:${this.id}`); @@ -391,9 +386,18 @@ Pad.prototype.init = async function (text, authorId = '') { } } } else { - // this pad doesn't exist, so create it - const firstChangeset = Changeset.makeSplice('\n', 0, 0, exports.cleanText(text)); - + if (text == null) { + const context = { + pad: this, + authorId, + type: 'text', + content: exports.cleanText(settings.defaultPadText), + }; + await hooks.aCallAll('padDefaultContent', context); + if (context.type !== 'text') throw new Error(`unsupported content type: ${context.type}`); + text = context.content; + } + const firstChangeset = Changeset.makeSplice('\n', 0, 0, text); await this.appendRevision(firstChangeset, authorId); } };