0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

Merge pull request #4066 from halfdan/3939-psm3-meta

Meta data screen
This commit is contained in:
Hannah Wolfe 2014-09-21 17:53:12 +01:00
commit f991ab44b8
8 changed files with 115 additions and 22 deletions

View file

@ -87,6 +87,9 @@
max-height: 250px; max-height: 250px;
} }
.word-count {
font-weight: bold;
}
} }

View file

@ -0,0 +1,5 @@
import TextInputMixin from 'ghost/mixins/text-input';
var Input = Ember.TextField.extend(TextInputMixin);
export default Input;

View file

@ -0,0 +1,5 @@
import TextInputMixin from 'ghost/mixins/text-input';
var TextArea = Ember.TextArea.extend(TextInputMixin);
export default TextArea;

View file

@ -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 // observe titleScratch, keeping the post's slug in sync
// with it until saved for the first time. // 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) { setCoverImage: function (image) {
var self = this; var self = this;

View 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;

View file

@ -1,4 +1,4 @@
var BlurInput = Ember.TextField.extend({ var BlurField = Ember.Mixin.create({
selectOnClick: false, selectOnClick: false,
stopEnterKeyDownPropagation: false, stopEnterKeyDownPropagation: false,
click: function (event) { click: function (event) {
@ -6,9 +6,6 @@ var BlurInput = Ember.TextField.extend({
event.currentTarget.select(); event.currentTarget.select();
} }
}, },
focusOut: function () {
this.sendAction('action', this.get('value'));
},
keyDown: function (event) { keyDown: function (event) {
// stop event propagation when pressing "enter" // stop event propagation when pressing "enter"
// most useful in the case when undesired (global) keyboard shortcuts are getting triggered while interacting // 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;

View file

@ -1,5 +1,5 @@
<div class="editor-cover" {{action "closeRightOutlet"}}></div> <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 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 {{bind-attr class="isViewingSubview:outlet-pane-out-left:outlet-pane-in :post-settings-menu :outlet-pane"}}>
<div class="post-settings-header"> <div class="post-settings-header">
@ -12,14 +12,14 @@
<div class="form-group"> <div class="form-group">
<label for="blog-title">Post URL</label> <label for="blog-title">Post URL</label>
<span class="input-icon icon-link"> <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> </span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="blog-title">Publish Date</label> <label for="blog-title">Publish Date</label>
<span class="input-icon icon-calendar"> <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> </span>
</div> </div>
@ -45,13 +45,13 @@
</label> </label>
</div> </div>
<ul class="nav-list nav-list-block"> <ul class="nav-list nav-list-block">
{{!--
{{#gh-tab tagName="li" classNames="nav-list-item"}} {{#gh-tab tagName="li" classNames="nav-list-item"}}
<a href="#"> <a href="#">
<b>Meta Data</b> <b>Meta Data</b>
<span>Extra content for SEO and social media.</span> <span>Extra content for SEO and social media.</span>
</a> </a>
{{/gh-tab}} {{/gh-tab}}
{{!--
{{#gh-tab tagName="li" classNames="nav-list-item"}} {{#gh-tab tagName="li" classNames="nav-list-item"}}
<a href="#"> <a href="#">
<b>Advanced Settings</b> <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> <button type="button" class="btn btn-red icon-trash delete" {{action "openModal" "delete-post" this}}>Delete This Post</button>
</form> </form>
</div><!-- .post-settings-content --> </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"}}> <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"> <div class="post-settings-header subview">
<button {{action "closeSubview"}} class="back icon-chevron-left post-settings-header-action"><span class="hidden">Back</span></button> <button {{action "closeSubview"}} class="back icon-chevron-left post-settings-header-action"><span class="hidden">Back</span></button>
<h4>Meta Data</h4> <h4>Meta Data</h4>
@ -87,26 +87,26 @@
<div class="post-settings-content"> <div class="post-settings-content">
<div class="form-group"> <div class="form-group">
<label for="blog-title">Meta Title</label> <label for="blog-title">Meta Title</label>
<input type="text" value="My Post is Super SEO Friendly" /> {{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. Youve used <b class="green">43</b></p> <p>Recommended: <b>70</b> characters. Youve used {{gh-count-down-characters metaTitleValue 70}}</p>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="blog-title">Meta Description</label> <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. Dont miss my stunning insights!</textarea> {{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. Youve used <b class="green">133</b></p> <p>Recommended: <b>156</b> characters. Youve used {{gh-count-down-characters metaDescriptionValue 156}}</p>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Search Engine Result Preview</label> <label>Search Engine Result Preview</label>
<div class="seo-preview"> <div class="seo-preview">
<div class="seo-preview-title">My Post is Super SEO Friendly</div> <div class="seo-preview-title">{{seoTitle}}</div>
<div class="seo-preview-link">myblog.com/this-is-my-post/</div> <div class="seo-preview-link">{{gh-blog-url}}/{{seoSlug}}{{#if seoSlug}}/{{/if}}</div>
<div class="seo-preview-description">In this fascinating posts I explore the value of SEO meta descriptions and their impact on blogging. Dont miss my stunning insights!</div> <div class="seo-preview-description">{{seoDescription}}</div>
</div> </div>
</div> </div>
</div> </div>
{{!---{{/gh-tab-pane}}----}} {{/gh-tab-pane}}
</div>--> </div>
</div> </div>
{{!---{{/gh-tabs-manager}} ---}} {{/gh-tabs-manager}}

View file

@ -49,7 +49,7 @@
<div class="form-group"> <div class="form-group">
<label for="user-slug">Slug</label> <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> <p>{{gh-blog-url}}/author/{{slugValue}}</p>
</div> </div>