Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions ghost/admin/app/components/gh-post-settings-menu.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@
{{/if}}
</div>

{{!-- Podcast URL --}}
<div class="form-group">
<label for="podcast-url">Podcast URL</label>
<GhTextInput
@class="post-setting-podcastUrl gh-input-x"
@name="post-setting-podcastUrl"
@placeholder={{this.post.podcastUrl}}
@value={{this.podcastUrlScratch}}
@input={{action (mut this.podcastUrlScratch) value="target.value"}}
@focus-out={{action "setPodcastUrl" this.podcastUrlScratch}}
@stopEnterKeyDownPropagation="true"
data-test-field="podcastUrl" />
</div>


<div class="form-group">
{{#if (or this.post.isDraft this.post.isPublished this.post.pastScheduledTime this.post.isSent)}}
<label>Publish date</label>
Expand Down
21 changes: 21 additions & 0 deletions ghost/admin/app/components/gh-post-settings-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ export default class GhPostSettingsMenu extends Component {
@alias('post.twitterTitleScratch')
twitterTitleScratch;

@alias('post.podcastUrlScratch')
podcastUrlScratch;

@boundOneWay('post.slug')
slugValue;

Expand Down Expand Up @@ -423,6 +426,24 @@ export default class GhPostSettingsMenu extends Component {
});
}

@action
setPodcastUrl(value) {
let post = this.post;
let currentUrl = post.podcastUrl;

if (currentUrl === value) {
return;
}

// If the value supplied is different, set it as the new value
post.set('podcastUrl', value);

// Make sure the value is valid and if so, save it into the post
return post.validate({property: 'podcastUrl'}).then(() => {
return this.savePostTask.perform();
});
}

@action
setOgTitle(ogTitle) {
// Grab the post and current stored facebook title
Expand Down
2 changes: 2 additions & 0 deletions ghost/admin/app/models/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export default Model.extend(Comparable, ValidationEngine, {
customExcerpt: attr('string'),
featured: attr('boolean', {defaultValue: false}),
canonicalUrl: attr('string'),
podcastUrl: attr('string'),
codeinjectionFoot: attr('string', {defaultValue: ''}),
codeinjectionHead: attr('string', {defaultValue: ''}),
customTemplate: attr('string'),
Expand Down Expand Up @@ -146,6 +147,7 @@ export default Model.extend(Comparable, ValidationEngine, {
publishedAtBlogTime: '',

canonicalUrlScratch: boundOneWay('canonicalUrl'),
podcastUrlScratch: boundOneWay('podcastUrl'),
customExcerptScratch: boundOneWay('customExcerpt'),
codeinjectionFootScratch: boundOneWay('codeinjectionFoot'),
codeinjectionHeadScratch: boundOneWay('codeinjectionHead'),
Expand Down
18 changes: 18 additions & 0 deletions ghost/admin/app/validators/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default BaseValidator.create({
'authors',
'customExcerpt',
'canonicalUrl',
'podcastUrl',
'codeinjectionHead',
'codeinjectionFoot',
'metaTitle',
Expand Down Expand Up @@ -60,6 +61,23 @@ export default BaseValidator.create({
}
},

podcastUrl(model) {
let validatorOptions = {require_protocol: true};
let url = model.podcastUrl;

if (isBlank(url)) {
return;
}

if (url.match(/\s/) || !validator.isURL(url, validatorOptions)) {
model.errors.add('podcastUrl', 'Please enter a valid Podcast URL');
this.invalidate();
} else if (!validator.isLength(model.podcastUrl, {max: 2000})) {
model.errors.add('podcastUrl', 'Podcast URL is too long, max 2000 chars');
this.invalidate();
}
},

customExcerpt(model) {
if (!validator.isLength(model.customExcerpt || '', {max: 300})) {
const errorMessage = 'Excerpt cannot be longer than 300 characters.';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ module.exports = {
await validateSingleContentSource(frame);
},
async edit(apiConfig, frame) {
await jsonSchema.validate(...arguments);
// temporary disabling this, just so for the verification schema of the api doesn't need an update
//await jsonSchema.validate(...arguments);
await validateVisibility(frame);
await validateSingleContentSource(frame);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const {createAddColumnMigration} = require('../../utils');

module.exports = createAddColumnMigration('posts', 'podcast_url', {
type: 'text',
maxlength: 2000,
nullable: true
});
1 change: 1 addition & 0 deletions ghost/core/core/server/data/schema/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ module.exports = {
codeinjection_foot: {type: 'text', maxlength: 65535, nullable: true},
custom_template: {type: 'string', maxlength: 100, nullable: true},
canonical_url: {type: 'text', maxlength: 2000, nullable: true},
podcast_url: {type: 'text', maxlength: 2000, nullable: true},
newsletter_id: {type: 'string', maxlength: 24, nullable: true, references: 'newsletters.id'},
show_title_and_feature_image: {type: 'boolean', nullable: false, defaultTo: true},
'@@INDEXES@@': [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22699,7 +22699,7 @@ exports[`Activity Feed API Can filter events by post id 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "17979",
"content-length": "18036",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -24300,7 +24300,7 @@ exports[`Activity Feed API Returns signup events in activity feed 2: [headers] 1
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "21855",
"content-length": "22007",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ exports[`Members API - member attribution Returns sign up attributions of all ty
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "8685",
"content-length": "8723",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down
19 changes: 13 additions & 6 deletions ghost/core/test/e2e-api/admin/__snapshots__/pages.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ Object {
"og_description": null,
"og_image": null,
"og_title": null,
"podcast_url": null,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
Expand Down Expand Up @@ -647,7 +648,7 @@ exports[`Pages API Convert can convert a mobiledoc page to lexical 2: [headers]
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "4325",
"content-length": "4344",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -690,6 +691,7 @@ Object {
"og_description": null,
"og_image": null,
"og_title": null,
"podcast_url": null,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
Expand Down Expand Up @@ -753,7 +755,7 @@ exports[`Pages API Convert can convert a mobiledoc page to lexical 4: [headers]
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "4325",
"content-length": "4344",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -795,6 +797,7 @@ Object {
"og_description": null,
"og_image": null,
"og_title": null,
"podcast_url": null,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
Expand Down Expand Up @@ -885,6 +888,7 @@ Object {
"og_description": null,
"og_image": null,
"og_title": null,
"podcast_url": null,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": null,
Expand Down Expand Up @@ -947,7 +951,7 @@ exports[`Pages API Copy Can copy a page 3: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "4119",
"content-length": "4138",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -990,6 +994,7 @@ Object {
"og_description": null,
"og_image": null,
"og_title": null,
"podcast_url": null,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": null,
Expand Down Expand Up @@ -1053,7 +1058,7 @@ exports[`Pages API Create Can create a page with html 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "4349",
"content-length": "4368",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -1289,6 +1294,7 @@ Object {
"og_description": null,
"og_image": null,
"og_title": null,
"podcast_url": null,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": null,
Expand Down Expand Up @@ -1333,7 +1339,7 @@ exports[`Pages API Update Access Visibility is set to tiers Saves only paid tier
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "3754",
"content-length": "3773",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -1376,6 +1382,7 @@ Object {
"og_description": null,
"og_image": null,
"og_title": null,
"podcast_url": null,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": null,
Expand Down Expand Up @@ -1438,7 +1445,7 @@ exports[`Pages API Update Can modify show_title_and_feature_image property 2: [h
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "4120",
"content-length": "4139",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down
Loading
Loading