mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-11 18:35:22 +03:00
Added posts_meta.feature_image_{alt,caption}
columns (#13030)
refs https://github.com/TryGhost/Team/issues/770 We want post feature image functionality to better match what's available inside the editor, to do that we'll need somewhere to store alt and caption meta data. `posts_meta` chosen because even though we want to make this generic for other tables in the future those tables also have a `feature_image` (or closely related) field. - updated schema with new columns - added migration to create columns - cleaned new columns from API output - not output on v2/v3 - conditionally output on v4/canary output based on labs flag - bumped `@tryghost/admin-api-schema` to allow new columns through in canary API requests - silently clean properties from input when labs flag is disabled - updated acceptance tests so they fail if `admin-api-schema` is not letting the new fields through
This commit is contained in:
parent
b53de12e12
commit
1bc57b584a
@ -6,6 +6,7 @@ const url = require('./utils/url');
|
||||
const slugFilterOrder = require('./utils/slug-filter-order');
|
||||
const localUtils = require('../../index');
|
||||
const postsMetaSchema = require('../../../../../data/schema').tables.posts_meta;
|
||||
const labs = require('../../../../../services/labs');
|
||||
|
||||
const replacePageWithType = mapNQLKeyValues({
|
||||
key: {
|
||||
@ -102,6 +103,13 @@ const forceStatusFilter = (frame) => {
|
||||
}
|
||||
};
|
||||
|
||||
const cleanLabsProperties = (frame) => {
|
||||
if (!labs.isSet('featureImageMeta') && frame.data.pages[0]) {
|
||||
delete frame.data.pages[0].feature_image_alt;
|
||||
delete frame.data.pages[0].feature_image_caption;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
browse(apiConfig, frame) {
|
||||
debug('browse');
|
||||
@ -180,6 +188,7 @@ module.exports = {
|
||||
});
|
||||
}
|
||||
|
||||
cleanLabsProperties(frame);
|
||||
handlePostsMeta(frame);
|
||||
defaultFormat(frame);
|
||||
defaultRelations(frame);
|
||||
@ -189,7 +198,6 @@ module.exports = {
|
||||
debug('edit');
|
||||
this.add(...arguments, {add: false});
|
||||
|
||||
handlePostsMeta(frame);
|
||||
forceStatusFilter(frame);
|
||||
forcePageFilter(frame);
|
||||
},
|
||||
|
@ -6,6 +6,7 @@ const slugFilterOrder = require('./utils/slug-filter-order');
|
||||
const localUtils = require('../../index');
|
||||
const mobiledoc = require('../../../../../lib/mobiledoc');
|
||||
const postsMetaSchema = require('../../../../../data/schema').tables.posts_meta;
|
||||
const labs = require('../../../../../services/labs');
|
||||
|
||||
const replacePageWithType = mapNQLKeyValues({
|
||||
key: {
|
||||
@ -111,6 +112,13 @@ const transformLegacyEmailRecipientFilters = (frame) => {
|
||||
}
|
||||
};
|
||||
|
||||
const cleanLabsProperties = (frame) => {
|
||||
if (!labs.isSet('featureImageMeta') && frame.data.posts[0]) {
|
||||
delete frame.data.posts[0].feature_image_alt;
|
||||
delete frame.data.posts[0].feature_image_caption;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
browse(apiConfig, frame) {
|
||||
debug('browse');
|
||||
@ -205,6 +213,7 @@ module.exports = {
|
||||
});
|
||||
}
|
||||
|
||||
cleanLabsProperties(frame);
|
||||
transformLegacyEmailRecipientFilters(frame);
|
||||
handlePostsMeta(frame);
|
||||
defaultFormat(frame);
|
||||
@ -215,8 +224,6 @@ module.exports = {
|
||||
debug('edit');
|
||||
this.add(apiConfig, frame, {add: false});
|
||||
|
||||
transformLegacyEmailRecipientFilters(frame);
|
||||
handlePostsMeta(frame);
|
||||
forceStatusFilter(frame);
|
||||
forcePageFilter(frame);
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
const _ = require('lodash');
|
||||
const localUtils = require('../../../index');
|
||||
const labs = require('../../../../../../services/labs');
|
||||
|
||||
const tag = (attrs, frame) => {
|
||||
if (localUtils.isContentAPI(frame)) {
|
||||
@ -124,6 +125,11 @@ const post = (attrs, frame) => {
|
||||
delete attrs.author;
|
||||
delete attrs.type;
|
||||
|
||||
if (!labs.isSet('featureImageMeta')) {
|
||||
delete attrs.feature_image_alt;
|
||||
delete attrs.feature_image_caption;
|
||||
}
|
||||
|
||||
return attrs;
|
||||
};
|
||||
|
||||
|
@ -136,6 +136,8 @@ const post = (attrs, frame) => {
|
||||
delete attrs.send_email_when_published;
|
||||
delete attrs.email_recipient_filter;
|
||||
delete attrs.email_subject;
|
||||
delete attrs.feature_image_alt;
|
||||
delete attrs.feature_image_caption;
|
||||
|
||||
return attrs;
|
||||
};
|
||||
|
@ -123,6 +123,8 @@ const post = (attrs, frame) => {
|
||||
delete attrs.locale;
|
||||
delete attrs.author;
|
||||
delete attrs.type;
|
||||
delete attrs.feature_image_alt;
|
||||
delete attrs.feature_image_caption;
|
||||
|
||||
return attrs;
|
||||
};
|
||||
|
@ -0,0 +1,7 @@
|
||||
const {createAddColumnMigration} = require('../../utils');
|
||||
|
||||
module.exports = createAddColumnMigration('posts_meta', 'feature_image_alt', {
|
||||
type: 'string',
|
||||
maxlength: 191,
|
||||
nullable: true
|
||||
});
|
@ -0,0 +1,7 @@
|
||||
const {createAddColumnMigration} = require('../../utils');
|
||||
|
||||
module.exports = createAddColumnMigration('posts_meta', 'feature_image_caption', {
|
||||
type: 'text',
|
||||
maxlength: 65535,
|
||||
nullable: true
|
||||
});
|
@ -72,7 +72,9 @@ module.exports = {
|
||||
meta_title: {type: 'string', maxlength: 2000, nullable: true, validations: {isLength: {max: 300}}},
|
||||
meta_description: {type: 'string', maxlength: 2000, nullable: true, validations: {isLength: {max: 500}}},
|
||||
email_subject: {type: 'string', maxlength: 300, nullable: true},
|
||||
frontmatter: {type: 'text', maxlength: 65535, nullable: true}
|
||||
frontmatter: {type: 'text', maxlength: 65535, nullable: true},
|
||||
feature_image_alt: {type: 'string', maxlength: 191, nullable: true, validations: {isLength: {max: 125}}},
|
||||
feature_image_caption: {type: 'text', maxlength: 65535, nullable: true}
|
||||
},
|
||||
users: {
|
||||
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
|
||||
|
@ -15,7 +15,8 @@ const BETA_FEATURES = [
|
||||
];
|
||||
|
||||
const ALPHA_FEATURES = [
|
||||
'multipleProducts'
|
||||
'multipleProducts',
|
||||
'featureImageMeta'
|
||||
];
|
||||
|
||||
module.exports.WRITABLE_KEYS_ALLOWLIST = [...BETA_FEATURES, ...ALPHA_FEATURES];
|
||||
|
@ -43,7 +43,7 @@
|
||||
"@nexes/nql": "0.5.2",
|
||||
"@sentry/node": "6.6.0",
|
||||
"@tryghost/adapter-manager": "0.2.12",
|
||||
"@tryghost/admin-api-schema": "2.2.2",
|
||||
"@tryghost/admin-api-schema": "2.3.0",
|
||||
"@tryghost/bootstrap-socket": "0.2.8",
|
||||
"@tryghost/constants": "0.1.7",
|
||||
"@tryghost/email-analytics-provider-mailgun": "1.0.0",
|
||||
|
@ -41,7 +41,9 @@ describe('Pages API', function () {
|
||||
const page = {
|
||||
title: 'My Page',
|
||||
page: false,
|
||||
status: 'published'
|
||||
status: 'published',
|
||||
feature_image_alt: 'Testing feature image alt',
|
||||
feature_image_caption: 'Testing <b>feature image caption</b>'
|
||||
};
|
||||
|
||||
const res = await request.post(localUtils.API.getApiQuery('pages/'))
|
||||
@ -63,9 +65,14 @@ describe('Pages API', function () {
|
||||
id: res.body.pages[0].id
|
||||
}, testUtils.context.internal);
|
||||
|
||||
model.get('title').should.eql(page.title);
|
||||
model.get('status').should.eql(page.status);
|
||||
model.get('type').should.eql('page');
|
||||
const modelJson = model.toJSON();
|
||||
|
||||
modelJson.title.should.eql(page.title);
|
||||
modelJson.status.should.eql(page.status);
|
||||
modelJson.type.should.eql('page');
|
||||
|
||||
modelJson.posts_meta.feature_image_alt.should.eql(page.feature_image_alt);
|
||||
modelJson.posts_meta.feature_image_caption.should.eql(page.feature_image_caption);
|
||||
});
|
||||
|
||||
it('Can update a page', async function () {
|
||||
|
@ -204,6 +204,8 @@ describe('Posts API', function () {
|
||||
const post = {
|
||||
title: 'My post',
|
||||
status: 'draft',
|
||||
feature_image_alt: 'Testing feature image alt',
|
||||
feature_image_caption: 'Testing <b>feature image caption</b>',
|
||||
published_at: '2016-05-30T07:00:00.000Z',
|
||||
mobiledoc: testUtils.DataGenerator.markdownToMobiledoc('my post'),
|
||||
created_at: moment().subtract(2, 'days').toDate(),
|
||||
@ -232,13 +234,18 @@ describe('Posts API', function () {
|
||||
status: 'draft'
|
||||
}, testUtils.context.internal);
|
||||
|
||||
model.get('title').should.eql(post.title);
|
||||
model.get('status').should.eql(post.status);
|
||||
model.get('published_at').toISOString().should.eql('2016-05-30T07:00:00.000Z');
|
||||
model.get('created_at').toISOString().should.not.eql(post.created_at.toISOString());
|
||||
model.get('updated_at').toISOString().should.not.eql(post.updated_at.toISOString());
|
||||
model.get('updated_by').should.not.eql(post.updated_by);
|
||||
model.get('created_by').should.not.eql(post.created_by);
|
||||
const modelJson = model.toJSON();
|
||||
|
||||
modelJson.title.should.eql(post.title);
|
||||
modelJson.status.should.eql(post.status);
|
||||
modelJson.published_at.toISOString().should.eql('2016-05-30T07:00:00.000Z');
|
||||
modelJson.created_at.toISOString().should.not.eql(post.created_at.toISOString());
|
||||
modelJson.updated_at.toISOString().should.not.eql(post.updated_at.toISOString());
|
||||
modelJson.updated_by.should.not.eql(post.updated_by);
|
||||
modelJson.created_by.should.not.eql(post.created_by);
|
||||
|
||||
modelJson.posts_meta.feature_image_alt.should.eql(post.feature_image_alt);
|
||||
modelJson.posts_meta.feature_image_caption.should.eql(post.feature_image_caption);
|
||||
});
|
||||
|
||||
it('Can update draft', async function () {
|
||||
|
@ -39,6 +39,8 @@ const expectedProperties = {
|
||||
'mobiledoc',
|
||||
'comment_id',
|
||||
'feature_image',
|
||||
'feature_image_alt',
|
||||
'feature_image_caption',
|
||||
'featured',
|
||||
'status',
|
||||
'visibility',
|
||||
@ -78,6 +80,8 @@ const expectedProperties = {
|
||||
'mobiledoc',
|
||||
'comment_id',
|
||||
'feature_image',
|
||||
'feature_image_alt',
|
||||
'feature_image_caption',
|
||||
'featured',
|
||||
'status',
|
||||
'visibility',
|
||||
|
@ -19,6 +19,8 @@ const expectedProperties = {
|
||||
'html',
|
||||
'comment_id',
|
||||
'feature_image',
|
||||
'feature_image_alt',
|
||||
'feature_image_caption',
|
||||
'featured',
|
||||
'visibility',
|
||||
'email_recipient_filter',
|
||||
|
@ -34,6 +34,8 @@ const expectedProperties = {
|
||||
'mobiledoc',
|
||||
'comment_id',
|
||||
'feature_image',
|
||||
'feature_image_alt',
|
||||
'feature_image_caption',
|
||||
'featured',
|
||||
'status',
|
||||
'visibility',
|
||||
|
@ -264,11 +264,6 @@ describe('api/canary/content/posts', function () {
|
||||
let paidPost;
|
||||
let membersPostWithPaywallCard;
|
||||
|
||||
before(function () {
|
||||
// NOTE: ideally this would be set through Admin API request not a stub
|
||||
sinon.stub(labs, 'isSet').withArgs('members').returns(true);
|
||||
});
|
||||
|
||||
before (function () {
|
||||
publicPost = testUtils.DataGenerator.forKnex.createPost({
|
||||
slug: 'free-to-see',
|
||||
|
@ -19,6 +19,8 @@ const expectedProperties = {
|
||||
'html',
|
||||
'comment_id',
|
||||
'feature_image',
|
||||
'feature_image_alt',
|
||||
'feature_image_caption',
|
||||
'featured',
|
||||
'visibility',
|
||||
'email_recipient_filter',
|
||||
|
@ -32,7 +32,7 @@ const defaultSettings = require('../../../../core/server/data/schema/default-set
|
||||
*/
|
||||
describe('DB version integrity', function () {
|
||||
// Only these variables should need updating
|
||||
const currentSchemaHash = '2099a4ba6b9462c5a0aa36a434139e8b';
|
||||
const currentSchemaHash = 'ef13a18aee78222086ca864c16bde696';
|
||||
const currentFixturesHash = '8671672598d2a62e53418c4b91aa79a3';
|
||||
const currentSettingsHash = 'fec0d2f71557a9bd2ff5ff8b423e11be';
|
||||
const currentRoutesHash = '3d180d52c663d173a6be791ef411ed01';
|
||||
|
@ -586,10 +586,10 @@
|
||||
dependencies:
|
||||
"@tryghost/errors" "^0.2.11"
|
||||
|
||||
"@tryghost/admin-api-schema@2.2.2":
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/admin-api-schema/-/admin-api-schema-2.2.2.tgz#d02c811f10bee5c3f62d3349ed220afd318f43cc"
|
||||
integrity sha512-H2L8DkGloUT+1i8/0qdNYEeZNCrocFIqa8kE89EfjcyxTPkMsI6whpdI1CFQNHxuz9TazbC2M2TeTzCgALrQLg==
|
||||
"@tryghost/admin-api-schema@2.3.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/admin-api-schema/-/admin-api-schema-2.3.0.tgz#3ec7dd98576e26166ff4c8082e6cd7542c3322d0"
|
||||
integrity sha512-f69N5TE4Wzff0xr13Pa+HyfqCVktiIg+5L3we2TWYUO8XSrZcLKo5ionj/ybMHUY1M3DMVL2yVFjOfRWnV2TpA==
|
||||
dependencies:
|
||||
"@tryghost/errors" "^0.2.10"
|
||||
bluebird "^3.5.3"
|
||||
|
Loading…
Reference in New Issue
Block a user