mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-05 18:34:39 +03:00
Meta data screen
closes #3939 - Add Seo Tab component to PSM - Add new gh-blur-textarea component - Refactor blur-input to use new text-input mixin
This commit is contained in:
parent
67c4452787
commit
30f56280e0
@ -87,6 +87,9 @@
|
||||
max-height: 250px;
|
||||
}
|
||||
|
||||
.word-count {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
5
core/client/components/gh-input.js
Normal file
5
core/client/components/gh-input.js
Normal file
@ -0,0 +1,5 @@
|
||||
import TextInputMixin from 'ghost/mixins/text-input';
|
||||
|
||||
var Input = Ember.TextField.extend(TextInputMixin);
|
||||
|
||||
export default Input;
|
5
core/client/components/gh-textarea.js
Normal file
5
core/client/components/gh-textarea.js
Normal file
@ -0,0 +1,5 @@
|
||||
import TextInputMixin from 'ghost/mixins/text-input';
|
||||
|
||||
var TextArea = Ember.TextArea.extend(TextInputMixin);
|
||||
|
||||
export default TextArea;
|
@ -97,6 +97,38 @@ var PostSettingsMenuController = Ember.ObjectController.extend({
|
||||
});
|
||||
},
|
||||
|
||||
metaTitleValue: boundOneWay('meta_title'),
|
||||
|
||||
metaDescriptionValue: boundOneWay('meta_description'),
|
||||
metaDescriptionPlaceholder: Ember.computed('scratch', function () {
|
||||
var html = this.get('scratch'),
|
||||
placeholder;
|
||||
|
||||
// Strip HTML
|
||||
placeholder = $('<div />', { html: html }).text();
|
||||
// Replace new lines and trim
|
||||
placeholder = placeholder.replace(/\n+/g, ' ').trim();
|
||||
// Limit to 156 characters
|
||||
placeholder = placeholder.substring(0,156);
|
||||
|
||||
return placeholder;
|
||||
}),
|
||||
|
||||
seoTitle: Ember.computed('titleScratch', 'metaTitleValue', function () {
|
||||
var metaTitle = this.get('metaTitleValue') || '';
|
||||
|
||||
return metaTitle.length > 0 ? metaTitle : this.get('titleScratch');
|
||||
}),
|
||||
|
||||
seoDescription: Ember.computed('scratch', 'metaDescriptionValue', function () {
|
||||
var metaDescription = this.get('metaDescriptionValue') || '';
|
||||
|
||||
return metaDescription.length > 0 ? metaDescription : this.get('metaDescriptionPlaceholder');
|
||||
}),
|
||||
|
||||
seoSlug: Ember.computed('slug', 'slugPlaceholder', function () {
|
||||
return this.get('slug') ? this.get('slug') : this.get('slugPlaceholder');
|
||||
}),
|
||||
|
||||
// observe titleScratch, keeping the post's slug in sync
|
||||
// with it until saved for the first time.
|
||||
@ -274,6 +306,40 @@ var PostSettingsMenuController = Ember.ObjectController.extend({
|
||||
});
|
||||
},
|
||||
|
||||
setMetaTitle: function (metaTitle) {
|
||||
var self = this;
|
||||
|
||||
this.set('meta_title', metaTitle);
|
||||
|
||||
// If this is a new post. Don't save the model. Defer the save
|
||||
// to the user pressing the save button
|
||||
if (this.get('isNew')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.get('model').save(this.get('saveOptions')).catch(function (errors) {
|
||||
self.showErrors(errors);
|
||||
self.get('model').rollback();
|
||||
});
|
||||
},
|
||||
|
||||
setMetaDescription: function (metaDescription) {
|
||||
var self = this;
|
||||
|
||||
this.set('meta_description', metaDescription);
|
||||
|
||||
// If this is a new post. Don't save the model. Defer the save
|
||||
// to the user pressing the save button
|
||||
if (this.get('isNew')) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.get('model').save(this.get('saveOptions')).catch(function (errors) {
|
||||
self.showErrors(errors);
|
||||
self.get('model').rollback();
|
||||
});
|
||||
},
|
||||
|
||||
setCoverImage: function (image) {
|
||||
var self = this;
|
||||
|
||||
|
17
core/client/helpers/gh-count-down-characters.js
Normal file
17
core/client/helpers/gh-count-down-characters.js
Normal file
@ -0,0 +1,17 @@
|
||||
var countDownCharacters = Ember.Handlebars.makeBoundHelper(function (content, maxCharacters) {
|
||||
var el = document.createElement('span'),
|
||||
length = content ? content.length : 0;
|
||||
|
||||
el.className = 'word-count';
|
||||
if (length > maxCharacters) {
|
||||
el.style.color = '#E25440';
|
||||
} else {
|
||||
el.style.color = '#9E9D95';
|
||||
}
|
||||
|
||||
el.innerHTML = length;
|
||||
|
||||
return new Ember.Handlebars.SafeString(el.outerHTML);
|
||||
});
|
||||
|
||||
export default countDownCharacters;
|
@ -1,4 +1,4 @@
|
||||
var BlurInput = Ember.TextField.extend({
|
||||
var BlurField = Ember.Mixin.create({
|
||||
selectOnClick: false,
|
||||
stopEnterKeyDownPropagation: false,
|
||||
click: function (event) {
|
||||
@ -6,9 +6,6 @@ var BlurInput = Ember.TextField.extend({
|
||||
event.currentTarget.select();
|
||||
}
|
||||
},
|
||||
focusOut: function () {
|
||||
this.sendAction('action', this.get('value'));
|
||||
},
|
||||
keyDown: function (event) {
|
||||
// stop event propagation when pressing "enter"
|
||||
// most useful in the case when undesired (global) keyboard shortcuts are getting triggered while interacting
|
||||
@ -20,4 +17,4 @@ var BlurInput = Ember.TextField.extend({
|
||||
}
|
||||
});
|
||||
|
||||
export default BlurInput;
|
||||
export default BlurField;
|
@ -1,5 +1,5 @@
|
||||
<div class="editor-cover" {{action "closeRightOutlet"}}></div>
|
||||
{{!----for halfdan:{{#gh-tabs-manager selected="showSubview" id="entry-controls" classNameBindings="isNew:unsaved :right-outlet"}}----}}
|
||||
{{#gh-tabs-manager selected="showSubview" id="entry-controls" classNameBindings="isNew:unsaved :right-outlet"}}
|
||||
<div id="entry-controls" {{bind-attr class="isNew:unsaved :right-outlet"}}>
|
||||
<div {{bind-attr class="isViewingSubview:outlet-pane-out-left:outlet-pane-in :post-settings-menu :outlet-pane"}}>
|
||||
<div class="post-settings-header">
|
||||
@ -12,14 +12,14 @@
|
||||
<div class="form-group">
|
||||
<label for="blog-title">Post URL</label>
|
||||
<span class="input-icon icon-link">
|
||||
{{gh-blur-input class="post-setting-slug" id="url" value=slugValue name="post-setting-slug" action="updateSlug" placeholder=slugPlaceholder selectOnClick="true" stopEnterKeyDownPropagation="true"}}
|
||||
{{gh-input class="post-setting-slug" id="url" value=slugValue name="post-setting-slug" focus-out="updateSlug" placeholder=slugPlaceholder selectOnClick="true" stopEnterKeyDownPropagation="true"}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="blog-title">Publish Date</label>
|
||||
<span class="input-icon icon-calendar">
|
||||
{{gh-blur-input class="post-setting-date" value=publishedAtValue name="post-setting-date" action="setPublishedAt" placeholder=publishedAtPlaceholder stopEnterKeyDownPropagation="true"}}
|
||||
{{gh-input class="post-setting-date" value=publishedAtValue name="post-setting-date" focus-out="setPublishedAt" placeholder=publishedAtPlaceholder stopEnterKeyDownPropagation="true"}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@ -45,13 +45,13 @@
|
||||
</label>
|
||||
</div>
|
||||
<ul class="nav-list nav-list-block">
|
||||
{{!--
|
||||
{{#gh-tab tagName="li" classNames="nav-list-item"}}
|
||||
<a href="#">
|
||||
<b>Meta Data</b>
|
||||
<span>Extra content for SEO and social media.</span>
|
||||
</a>
|
||||
{{/gh-tab}}
|
||||
{{!--
|
||||
{{#gh-tab tagName="li" classNames="nav-list-item"}}
|
||||
<a href="#">
|
||||
<b>Advanced Settings</b>
|
||||
@ -75,9 +75,9 @@
|
||||
<button type="button" class="btn btn-red icon-trash delete" {{action "openModal" "delete-post" this}}>Delete This Post</button>
|
||||
</form>
|
||||
</div><!-- .post-settings-content -->
|
||||
</div><!-- .post-settings-menu --
|
||||
</div><!-- .post-settings-menu -->
|
||||
<div {{bind-attr class="isViewingSubview:outlet-pane-in:outlet-pane-out-right :post-settings-menu :outlet-pane"}}>
|
||||
{{!-----{{#gh-tab-pane}}-----}}
|
||||
{{#gh-tab-pane}}
|
||||
<div class="post-settings-header subview">
|
||||
<button {{action "closeSubview"}} class="back icon-chevron-left post-settings-header-action"><span class="hidden">Back</span></button>
|
||||
<h4>Meta Data</h4>
|
||||
@ -87,26 +87,26 @@
|
||||
<div class="post-settings-content">
|
||||
<div class="form-group">
|
||||
<label for="blog-title">Meta Title</label>
|
||||
<input type="text" value="My Post is Super SEO Friendly" />
|
||||
<p>Recommended: <b>70</b> characters. You’ve used <b class="green">43</b></p>
|
||||
{{gh-input class="post-setting-meta-title" value=metaTitleValue name="post-setting-meta-title" focus-out="setMetaTitle" placeholder=titleScratch stopEnterKeyDownPropagation="true"}}
|
||||
<p>Recommended: <b>70</b> characters. You’ve used {{gh-count-down-characters metaTitleValue 70}}</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="blog-title">Meta Description</label>
|
||||
<textarea>In this fascinating posts I explore the value of SEO meta descriptions and their impact on blogging. Don’t miss my stunning insights!</textarea>
|
||||
<p>Recommended: <b>156</b> characters. You’ve used <b class="green">133</b></p>
|
||||
{{gh-textarea class="post-setting-meta-description" value=metaDescriptionValue name="post-setting-meta-description" focus-out="setMetaDescription" placeholder=metaDescriptionPlaceholder stopEnterKeyDownPropagation="true"}}
|
||||
<p>Recommended: <b>156</b> characters. You’ve used {{gh-count-down-characters metaDescriptionValue 156}}</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Search Engine Result Preview</label>
|
||||
<div class="seo-preview">
|
||||
<div class="seo-preview-title">My Post is Super SEO Friendly</div>
|
||||
<div class="seo-preview-link">myblog.com/this-is-my-post/</div>
|
||||
<div class="seo-preview-description">In this fascinating posts I explore the value of SEO meta descriptions and their impact on blogging. Don’t miss my stunning insights!</div>
|
||||
<div class="seo-preview-title">{{seoTitle}}</div>
|
||||
<div class="seo-preview-link">{{gh-blog-url}}/{{seoSlug}}{{#if seoSlug}}/{{/if}}</div>
|
||||
<div class="seo-preview-description">{{seoDescription}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{!---{{/gh-tab-pane}}----}}
|
||||
</div>-->
|
||||
{{/gh-tab-pane}}
|
||||
</div>
|
||||
</div>
|
||||
{{!---{{/gh-tabs-manager}} ---}}
|
||||
{{/gh-tabs-manager}}
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label for="user-slug">Slug</label>
|
||||
{{gh-blur-input class="user-name" id="user-slug" value=slugValue name="user" action="updateSlug" placeholder="Slug" selectOnClick="true" autocorrect="off"}}
|
||||
{{gh-input class="user-name" id="user-slug" value=slugValue name="user" focus-out="updateSlug" placeholder="Slug" selectOnClick="true" autocorrect="off"}}
|
||||
<p>{{gh-blog-url}}/author/{{slugValue}}</p>
|
||||
</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user