Added posts html regeneration migration (#12660)

refs https://github.com/TryGhost/Team/issues/467
refs https://github.com/TryGhost/Team/issues/221

- we've introduced backwards-compatible changes to rendering in 3.0 such as srcset and sizes which will only have taken effect on posts created or edited since the changes were made
- 4.0 brings additional changes such as image card width/height
- re-generating the `html` field of all posts from the `mobiledoc` brings all content up to latest rendering output
This commit is contained in:
Kevin Ansfield 2021-02-23 17:32:07 +00:00 committed by GitHub
parent 26c49b4f57
commit 722825055f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,72 @@
const logging = require('../../../../../shared/logging');
const {createIrreversibleMigration} = require('../../utils');
const mobiledocLib = require('../../../../lib/mobiledoc');
const htmlToText = require('html-to-text');
module.exports = createIrreversibleMigration(async (knex) => {
logging.info('Starting re-generation of posts html.');
await knex.transaction(async (trx) => {
// get list of posts ids, use .forUpdate to lock rows until the transaction is finished
const postIdRows = await knex('posts')
.transacting(trx)
.forUpdate()
.select('id');
// transform each post individually to avoid dumping all posts into memory and
// pushing all queries into the query builder buffer in parallel
// https://stackoverflow.com/questions/54105280/how-to-loop-through-multi-line-sql-query-and-use-them-in-knex-transactions
for (const postIdRow of postIdRows) {
const {id} = postIdRow;
const [post] = await knex('posts')
.transacting(trx)
.where({id})
.select('mobiledoc', 'html', 'plaintext');
let mobiledoc;
try {
mobiledoc = JSON.parse(post.mobiledoc || null);
if (!mobiledoc) {
return logging.warn(`No mobiledoc for ${id}. Skipping.`);
}
} catch (err) {
return logging.warn(`Invalid JSON structure for ${id}. Skipping`);
}
const html = mobiledocLib.mobiledocHtmlRenderer.render(mobiledoc);
const updatedAttrs = {
html: html
};
// NOTE: block comes straight from the Post model
// https://github.com/TryGhost/Ghost/blob/4.0.0-alpha.2/core/server/models/post.js#L484
if (html !== post.html || !post.plaintext) {
const plaintext = htmlToText.fromString(html, {
wordwrap: 80,
ignoreImage: true,
hideLinkHrefIfSameAsText: true,
preserveNewlines: true,
returnDomByDefault: true,
uppercaseHeadings: false
});
if (plaintext !== post.plaintext) {
updatedAttrs.plaintext = plaintext;
}
}
await knex('posts')
.transacting(trx)
.where({id})
.update(updatedAttrs);
}
return 'transaction complete';
});
logging.info('Finished re-generation of posts html.');
});