mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-24 03:14:03 +03:00
🐛 Fixed __GHOST_URL__ appearing in generated excerpts
refs https://github.com/TryGhost/Team/issues/467
refs a6f5eb71be
- When a generated excerpt is calculated for posts/page resources it uses raw model! to get the data. Model contains untranformed __GHOST_URL__ markup which has to be additionally processed before extracint an excerpt or use the transformed `plaintext` from available attributes (chose the latter to decrease complexity)
- Removed model dependency as `attrs` at this point of serialization should always contain the `plaintext` field. It's ugly and has an unsolved bug report here - https://github.com/TryGhost/Ghost/issues/10396. The reliance should be solved at some point, but definitely not a part of this issue
This commit is contained in:
parent
958775b068
commit
6b07d4b2a0
@ -6,7 +6,7 @@ module.exports.forPost = (frame, model, attrs) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(frame.options, 'columns') ||
|
||||
(frame.options.columns.includes('excerpt') && frame.options.formats && frame.options.formats.includes('plaintext'))) {
|
||||
if (_.isEmpty(attrs.custom_excerpt)) {
|
||||
const plaintext = model.get('plaintext');
|
||||
const plaintext = attrs.plaintext;
|
||||
|
||||
if (plaintext) {
|
||||
attrs.excerpt = plaintext.substring(0, 500);
|
||||
|
@ -4,7 +4,7 @@ module.exports.forPost = (frame, model, attrs) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(frame.options, 'columns') ||
|
||||
(frame.options.columns.includes('excerpt') && frame.options.formats && frame.options.formats.includes('plaintext'))) {
|
||||
if (_.isEmpty(attrs.custom_excerpt)) {
|
||||
const plaintext = model.get('plaintext');
|
||||
const plaintext = attrs.plaintext;
|
||||
|
||||
if (plaintext) {
|
||||
attrs.excerpt = plaintext.substring(0, 500);
|
||||
|
@ -6,7 +6,7 @@ module.exports.forPost = (frame, model, attrs) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(frame.options, 'columns') ||
|
||||
(frame.options.columns.includes('excerpt') && frame.options.formats && frame.options.formats.includes('plaintext'))) {
|
||||
if (_.isEmpty(attrs.custom_excerpt)) {
|
||||
const plaintext = model.get('plaintext');
|
||||
const plaintext = attrs.plaintext;
|
||||
|
||||
if (plaintext) {
|
||||
attrs.excerpt = plaintext.substring(0, 500);
|
||||
|
@ -242,14 +242,19 @@ describe('api/canary/content/posts', function () {
|
||||
});
|
||||
|
||||
it('can read post with fields', function () {
|
||||
const complexPostId = testUtils.DataGenerator.Content.posts.find(p => p.slug === 'not-so-short-bit-complex').id;
|
||||
|
||||
return request
|
||||
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[0].id}/?key=${validKey}&fields=title,slug`))
|
||||
.get(localUtils.API.getApiQuery(`posts/${complexPostId}/?key=${validKey}&fields=title,slug,excerpt&formats=plaintext`))
|
||||
.set('Origin', testUtils.API.getURL())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
localUtils.API.checkResponse(res.body.posts[0], 'post', null, null, ['id', 'title', 'slug']);
|
||||
localUtils.API.checkResponse(res.body.posts[0], 'post', null, null, ['id', 'title', 'slug', 'excerpt', 'plaintext']);
|
||||
|
||||
// excerpt should transform links to absolute URLs
|
||||
res.body.posts[0].excerpt.should.match(/\* Aliquam \[http:\/\/127.0.0.1:2369\/about#nowhere\]/);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -183,14 +183,19 @@ describe('api/v2/content/posts', function () {
|
||||
});
|
||||
|
||||
it('can read post with fields', function () {
|
||||
const complexPostId = testUtils.DataGenerator.Content.posts.find(p => p.slug === 'not-so-short-bit-complex').id;
|
||||
|
||||
return request
|
||||
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[0].id}/?key=${validKey}&fields=title,slug`))
|
||||
.get(localUtils.API.getApiQuery(`posts/${complexPostId}/?key=${validKey}&fields=title,slug,excerpt&formats=plaintext`))
|
||||
.set('Origin', testUtils.API.getURL())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
localUtils.API.checkResponse(res.body.posts[0], 'post', null, null, ['id', 'title', 'slug']);
|
||||
localUtils.API.checkResponse(res.body.posts[0], 'post', null, null, ['id', 'title', 'slug', 'excerpt', 'plaintext']);
|
||||
|
||||
// excerpt should transform links to absolute URLs
|
||||
res.body.posts[0].excerpt.should.match(/\* Aliquam \[http:\/\/127.0.0.1:2369\/about#nowhere\]/);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -242,14 +242,19 @@ describe('api/v3/content/posts', function () {
|
||||
});
|
||||
|
||||
it('can read post with fields', function () {
|
||||
const complexPostId = testUtils.DataGenerator.Content.posts.find(p => p.slug === 'not-so-short-bit-complex').id;
|
||||
|
||||
return request
|
||||
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[0].id}/?key=${validKey}&fields=title,slug`))
|
||||
.get(localUtils.API.getApiQuery(`posts/${complexPostId}/?key=${validKey}&fields=title,slug,excerpt&formats=plaintext`))
|
||||
.set('Origin', testUtils.API.getURL())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
localUtils.API.checkResponse(res.body.posts[0], 'post', null, null, ['id', 'title', 'slug']);
|
||||
localUtils.API.checkResponse(res.body.posts[0], 'post', null, null, ['id', 'title', 'slug', 'excerpt', 'plaintext']);
|
||||
|
||||
// excerpt should transform links to absolute URLs
|
||||
res.body.posts[0].excerpt.should.match(/\* Aliquam \[http:\/\/127.0.0.1:2369\/about#nowhere\]/);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
const should = require('should');
|
||||
const sinon = require('sinon');
|
||||
const extraAttrsUtil = require('../../../../../../../../core/server/api/canary/utils/serializers/output/utils/extra-attrs');
|
||||
|
||||
describe('Unit: canary/utils/serializers/output/utils/extra-attrs', function () {
|
||||
@ -9,38 +8,34 @@ describe('Unit: canary/utils/serializers/output/utils/extra-attrs', function ()
|
||||
|
||||
let model;
|
||||
|
||||
beforeEach(function () {
|
||||
model = sinon.stub();
|
||||
model.get = sinon.stub();
|
||||
model.get.withArgs('plaintext').returns(new Array(5000).join('A'));
|
||||
});
|
||||
|
||||
describe('for post', function () {
|
||||
it('respects custom excerpt', function () {
|
||||
const attrs = {custom_excerpt: 'custom excerpt'};
|
||||
const attrs = {
|
||||
custom_excerpt: 'custom excerpt',
|
||||
plaintext: new Array(5000).join('A')
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.false();
|
||||
|
||||
attrs.excerpt.should.eql(attrs.custom_excerpt);
|
||||
});
|
||||
|
||||
it('no custom excerpt', function () {
|
||||
const attrs = {};
|
||||
const attrs = {
|
||||
plaintext: new Array(5000).join('A')
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.true();
|
||||
|
||||
attrs.excerpt.should.eql(new Array(501).join('A'));
|
||||
});
|
||||
|
||||
it('has excerpt when plaintext is null', function () {
|
||||
model.get.withArgs('plaintext').returns(null);
|
||||
|
||||
const attrs = {};
|
||||
const attrs = {
|
||||
plaintext: null
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.true();
|
||||
|
||||
attrs.should.have.property('excerpt');
|
||||
(attrs.excerpt === null).should.be.true();
|
||||
|
@ -9,38 +9,34 @@ describe('Unit: v2/utils/serializers/output/utils/extra-attrs', function () {
|
||||
|
||||
let model;
|
||||
|
||||
beforeEach(function () {
|
||||
model = sinon.stub();
|
||||
model.get = sinon.stub();
|
||||
model.get.withArgs('plaintext').returns(new Array(5000).join('A'));
|
||||
});
|
||||
|
||||
describe('for post', function () {
|
||||
it('respects custom excerpt', function () {
|
||||
const attrs = {custom_excerpt: 'custom excerpt'};
|
||||
const attrs = {
|
||||
custom_excerpt: 'custom excerpt',
|
||||
plaintext: new Array(5000).join('A')
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.false();
|
||||
|
||||
attrs.excerpt.should.eql(attrs.custom_excerpt);
|
||||
});
|
||||
|
||||
it('no custom excerpt', function () {
|
||||
const attrs = {};
|
||||
const attrs = {
|
||||
plaintext: new Array(5000).join('A')
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.true();
|
||||
|
||||
attrs.excerpt.should.eql(new Array(501).join('A'));
|
||||
});
|
||||
|
||||
it('has excerpt when plaintext is null', function () {
|
||||
model.get.withArgs('plaintext').returns(null);
|
||||
|
||||
const attrs = {};
|
||||
const attrs = {
|
||||
plaintext: null
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.true();
|
||||
|
||||
attrs.should.have.property('excerpt');
|
||||
(attrs.excerpt === null).should.be.true();
|
||||
|
@ -1,5 +1,4 @@
|
||||
const should = require('should');
|
||||
const sinon = require('sinon');
|
||||
const extraAttrsUtil = require('../../../../../../../../core/server/api/v3/utils/serializers/output/utils/extra-attrs');
|
||||
|
||||
describe('Unit: v3/utils/serializers/output/utils/extra-attrs', function () {
|
||||
@ -9,38 +8,34 @@ describe('Unit: v3/utils/serializers/output/utils/extra-attrs', function () {
|
||||
|
||||
let model;
|
||||
|
||||
beforeEach(function () {
|
||||
model = sinon.stub();
|
||||
model.get = sinon.stub();
|
||||
model.get.withArgs('plaintext').returns(new Array(5000).join('A'));
|
||||
});
|
||||
|
||||
describe('for post', function () {
|
||||
it('respects custom excerpt', function () {
|
||||
const attrs = {custom_excerpt: 'custom excerpt'};
|
||||
const attrs = {
|
||||
custom_excerpt: 'custom excerpt',
|
||||
plaintext: new Array(5000).join('A')
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.false();
|
||||
|
||||
attrs.excerpt.should.eql(attrs.custom_excerpt);
|
||||
});
|
||||
|
||||
it('no custom excerpt', function () {
|
||||
const attrs = {};
|
||||
const attrs = {
|
||||
plaintext: new Array(5000).join('A')
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.true();
|
||||
|
||||
attrs.excerpt.should.eql(new Array(501).join('A'));
|
||||
});
|
||||
|
||||
it('has excerpt when plaintext is null', function () {
|
||||
model.get.withArgs('plaintext').returns(null);
|
||||
|
||||
const attrs = {};
|
||||
const attrs = {
|
||||
plaintext: null
|
||||
};
|
||||
|
||||
extraAttrsUtil.forPost(frame, model, attrs);
|
||||
model.get.called.should.be.true();
|
||||
|
||||
attrs.should.have.property('excerpt');
|
||||
(attrs.excerpt === null).should.be.true();
|
||||
|
Loading…
Reference in New Issue
Block a user