0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Made lexical rendering async (#17438)

-moved lexical rendering to async
-includes rendering for front end and email
-necessary to pull dynamic data into render method, e.g. collections
This commit is contained in:
Steve Larson 2023-07-20 17:48:48 -05:00 committed by GitHub
parent 78a06aead3
commit 22441fe730
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 42 additions and 38 deletions

View file

@ -241,11 +241,14 @@ export default class KoenigLexicalEditor extends Component {
};
const fetchCollectionPosts = async (collectionSlug) => {
const collectionPostsEndpoint = this.ghostPaths.url.api('collections', collectionSlug,'posts');
const {collection_posts: collectionPosts} = await this.ajax.request(collectionPostsEndpoint, {
data: {limit: 12}
const collectionPostsEndpoint = this.ghostPaths.url.api('posts');
const {posts} = await this.ajax.request(collectionPostsEndpoint, {
data: {
collection: collectionSlug,
limit: 12
}
});
return collectionPosts;
return posts;
};
const fetchAutocompleteLinks = async () => {

View file

@ -26,7 +26,7 @@ module.exports = {
return lexicalHtmlRenderer;
},
render(lexical, userOptions = {}) {
async render(lexical, userOptions = {}) {
const options = Object.assign({
siteUrl: config.get('url'),
imageOptimization: config.get('imageOptimization'),
@ -45,7 +45,7 @@ module.exports = {
}
}, userOptions);
return this.lexicalHtmlRenderer.render(lexical, options);
return await this.lexicalHtmlRenderer.render(lexical, options);
},
get nodes() {

View file

@ -688,7 +688,7 @@ Post = ghostBookshelf.Model.extend({
)
) {
try {
this.set('html', lexicalLib.render(this.get('lexical')));
this.set('html', await lexicalLib.render(this.get('lexical')));
} catch (err) {
throw new errors.ValidationError({
message: tpl(messages.invalidLexicalStructure),

View file

@ -102,8 +102,8 @@
"@tryghost/kg-card-factory": "4.0.8",
"@tryghost/kg-default-atoms": "4.0.1",
"@tryghost/kg-default-cards": "9.1.0",
"@tryghost/kg-default-nodes": "0.1.9",
"@tryghost/kg-lexical-html-renderer": "0.3.5",
"@tryghost/kg-default-nodes": "0.1.10",
"@tryghost/kg-lexical-html-renderer": "0.3.6",
"@tryghost/kg-mobiledoc-html-renderer": "6.0.8",
"@tryghost/limit-service": "1.2.6",
"@tryghost/link-redirects": "0.0.0",

View file

@ -3,14 +3,14 @@ const lexicalLib = require('../../../../core/server/lib/lexical');
describe('lib/lexical', function () {
describe('render()', function () {
it('renders', function () {
it('renders', async function () {
const lexical = `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lexical is ","type":"text","version":1},{"detail":0,"format":3,"mode":"normal","style":"","text":"rendering.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`;
lexicalLib.render(lexical)
.should.eql('<p>Lexical is <strong><em>rendering.</em></strong></p>');
const renderedHtml = await lexicalLib.render(lexical);
renderedHtml.should.eql('<p>Lexical is <strong><em>rendering.</em></strong></p>');
});
it('renders all default cards', function () {
it('renders all default cards', async function () {
const lexicalState = JSON.stringify({
root: {
children: [
@ -39,7 +39,7 @@ describe('lib/lexical', function () {
}
});
const rendered = lexicalLib.render(lexicalState);
const rendered = await lexicalLib.render(lexicalState);
rendered.should.containEql('<figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption">');
rendered.should.containEql('<div class="kg-card kg-audio-card">');

View file

@ -31,7 +31,7 @@ async function createPublishedPostEmail(agent, settings = {}, email_recipient_fi
const res = await agent.post('posts/')
.body({posts: [post]})
.expectStatus(201);
const id = res.body.posts[0].id;
// Make sure all posts are published in the samre order, with minimum 1s difference (to have consistent ordering when including latests posts)

View file

@ -227,7 +227,7 @@ class BatchSendingService {
async createBatches({email, post, newsletter}) {
logging.info(`Creating batches for email ${email.id}`);
const segments = this.#emailRenderer.getSegments(post);
const segments = await this.#emailRenderer.getSegments(post);
const batches = [];
const BATCH_SIZE = this.#sendingService.getMaximumRecipients();
let totalCount = 0;

View file

@ -205,11 +205,11 @@ class EmailRenderer {
Returns all the segments that we need to render the email for because they have different content.
WARNING: The sum of all the returned segments should always include all the members. Those members are later limited if needed based on the recipient filter of the email.
@param {Post} post
@returns {Segment[]}
@returns {Promise<Segment[]>}
*/
getSegments(post) {
async getSegments(post) {
const allowedSegments = ['status:free', 'status:-free'];
const html = this.renderPostBaseHtml(post);
const html = await this.renderPostBaseHtml(post);
/**
* Always add free and paid segments if email has paywall card
@ -235,11 +235,12 @@ class EmailRenderer {
return allowedSegments;
}
renderPostBaseHtml(post) {
async renderPostBaseHtml(post) {
const postUrl = this.#getPostUrl(post);
let html;
if (post.get('lexical')) {
html = this.#renderers.lexical.render(
// only lexical's renderer is async
html = await this.#renderers.lexical.render(
post.get('lexical'), {target: 'email', postUrl}
);
} else {
@ -259,7 +260,7 @@ class EmailRenderer {
* @returns {Promise<EmailBody>}
*/
async renderBody(post, newsletter, segment, options) {
let html = this.renderPostBaseHtml(post);
let html = await this.renderPostBaseHtml(post);
// We don't allow the usage of the %%{uuid}%% replacement in the email body (only in links and special cases)
// So we need to filter them before we introduce the real %%{uuid}%%

View file

@ -775,7 +775,7 @@ describe('Email renderer', function () {
}
});
it('returns correct empty segment for post', function () {
it('returns correct empty segment for post', async function () {
let post = {
get: (key) => {
if (key === 'lexical') {
@ -783,7 +783,7 @@ describe('Email renderer', function () {
}
}
};
let response = emailRenderer.getSegments(post);
let response = await emailRenderer.getSegments(post);
response.should.eql([null]);
post = {
@ -793,11 +793,11 @@ describe('Email renderer', function () {
}
}
};
response = emailRenderer.getSegments(post);
response = await emailRenderer.getSegments(post);
response.should.eql([null]);
});
it('returns correct segments for post with members only card', function () {
it('returns correct segments for post with members only card', async function () {
emailRenderer = new EmailRenderer({
renderers: {
lexical: {
@ -821,11 +821,11 @@ describe('Email renderer', function () {
}
}
};
let response = emailRenderer.getSegments(post);
let response = await emailRenderer.getSegments(post);
response.should.eql(['status:free', 'status:-free']);
});
it('returns correct segments for post with email card', function () {
it('returns correct segments for post with email card', async function () {
emailRenderer = new EmailRenderer({
renderers: {
lexical: {
@ -849,7 +849,7 @@ describe('Email renderer', function () {
}
}
};
let response = emailRenderer.getSegments(post);
let response = await emailRenderer.getSegments(post);
response.should.eql(['status:free', 'status:-free']);
});
});

View file

@ -6762,10 +6762,10 @@
lodash "^4.17.21"
luxon "^3.0.0"
"@tryghost/kg-default-nodes@0.1.9", "@tryghost/kg-default-nodes@^0.1.9":
version "0.1.9"
resolved "https://registry.yarnpkg.com/@tryghost/kg-default-nodes/-/kg-default-nodes-0.1.9.tgz#ada6686fa45762cc942f84650cf91628efd7bd4c"
integrity sha512-IW1t4V2o1c82SeSA/eHq09jUWo0xQWELrd8YboXwwYQ03+yZ7HpRxvIBJoKL4En/PeVAbO7JhSqL9eTt8fmKqg==
"@tryghost/kg-default-nodes@0.1.10", "@tryghost/kg-default-nodes@^0.1.10":
version "0.1.10"
resolved "https://registry.yarnpkg.com/@tryghost/kg-default-nodes/-/kg-default-nodes-0.1.10.tgz#d7cdf76238a54368ad3ba7d0ad991de9e9006e08"
integrity sha512-d7GkuoLV99EWjaVwrZRjT9Y8eKVeAJSG4FSLOn8rGGul7z59qFIIzd1Ufkw0uqJKPtiHvuyCTFdmknspV6r5UA==
dependencies:
"@tryghost/kg-clean-basic-html" "^3.0.21"
"@tryghost/kg-markdown-html-renderer" "^6.0.8"
@ -6775,10 +6775,10 @@
lodash "^4.17.21"
luxon "^3.3.0"
"@tryghost/kg-lexical-html-renderer@0.3.5":
version "0.3.5"
resolved "https://registry.yarnpkg.com/@tryghost/kg-lexical-html-renderer/-/kg-lexical-html-renderer-0.3.5.tgz#bd3796b1039032deb5ac469704e6e6d5ee0d24d4"
integrity sha512-/lf0BV2k+D3r6oaJQhw0q+PKHgOa5k7pRLWzk7wgKMF50dHUWgnHUh2FSZXSxdEg0rUDMdYStofOjEtMhCsS3Q==
"@tryghost/kg-lexical-html-renderer@0.3.6":
version "0.3.6"
resolved "https://registry.yarnpkg.com/@tryghost/kg-lexical-html-renderer/-/kg-lexical-html-renderer-0.3.6.tgz#a262f6e363420d2f0291bc283fc9122ceb033bbd"
integrity sha512-H1F1uBUJgAnG5sbNemvNELzZrriAXDokbit44O9nTGF8W5ys5F0ibwZns6DV8h8ZPToG57GxjggmA25Qw/ghwg==
dependencies:
"@lexical/clipboard" "^0.11.0"
"@lexical/code" "^0.11.0"
@ -6786,7 +6786,7 @@
"@lexical/link" "^0.11.0"
"@lexical/list" "^0.11.0"
"@lexical/rich-text" "^0.11.0"
"@tryghost/kg-default-nodes" "^0.1.9"
"@tryghost/kg-default-nodes" "^0.1.10"
jsdom "^22.1.0"
lexical "^0.11.0"
prettier "^2.7.1"