Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
internal tags feature
Browse files Browse the repository at this point in the history
refs TryGhost/Ghost#6165
- change behavior to use 'visibility' property
- add tests
  • Loading branch information
acburdine committed Jun 13, 2016
1 parent e704d5f commit 7d693c1
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 9 deletions.
5 changes: 3 additions & 2 deletions app/components/gh-tag-settings-form.js
Expand Up @@ -25,6 +25,7 @@ export default Component.extend({

isViewingSubview: false,

feature: service(),
config: service(),
mediaQueries: service(),

Expand Down Expand Up @@ -114,11 +115,11 @@ export default Component.extend({
},

setCoverImage(image) {
invokeAction(this, 'setProperty', 'image', image);
this.send('setProperty', 'image', image);
},

clearCoverImage() {
invokeAction(this, 'setProperty', 'image', '');
this.send('setProperty', 'image', '');
},

openMeta() {
Expand Down
7 changes: 6 additions & 1 deletion app/components/gh-tag.js
@@ -1,9 +1,14 @@
import Ember from 'ember';
import {invokeAction} from 'ember-invoke-action';

const {Component} = Ember;
const {
inject: {service},
Component
} = Ember;

export default Component.extend({
feature: service(),

willDestroyElement() {
this._super(...arguments);

Expand Down
8 changes: 7 additions & 1 deletion app/controllers/posts.js
@@ -1,6 +1,11 @@
import Ember from 'ember';

const {Controller, compare, computed} = Ember;
const {
Controller,
compare,
computed,
inject: {service}
} = Ember;
const {equal} = computed;

// a custom sort function is needed in order to sort the posts list the same way the server would:
Expand Down Expand Up @@ -67,6 +72,7 @@ function publishedAtCompare(item1, item2) {
}

export default Controller.extend({
feature: service(),

showDeletePostModal: false,

Expand Down
2 changes: 1 addition & 1 deletion app/mirage/factories/tag.js
Expand Up @@ -5,7 +5,7 @@ export default Mirage.Factory.extend({
created_at() { return '2015-09-11T09:44:29.871Z'; },
created_by() { return 1; },
description(i) { return `Description for tag ${i}.`; },
hidden() { return false; },
visibility() { return 'public'; },
image(i) { return `/content/images/2015/10/tag-${i}.jpg`; },
meta_description(i) { return `Meta description for tag ${i}.`; },
meta_title(i) { return `Meta Title for tag ${i}`; },
Expand Down
2 changes: 1 addition & 1 deletion app/mirage/fixtures/settings.js
Expand Up @@ -125,7 +125,7 @@ export default [
id: 12,
uuid: 'd806f358-7996-4c74-b153-8876959c4b70',
key: 'labs',
value: '{"codeInjectionUI":true,"subscribers":true}',
value: '{"subscribers":true,"internalTags":true}',
type: 'blog',
created_at: '2015-01-12T18:29:01.000Z',
created_by: 1,
Expand Down
3 changes: 2 additions & 1 deletion app/models/post.js
Expand Up @@ -9,7 +9,7 @@ const {
computed,
inject: {service}
} = Ember;
const {equal} = computed;
const {equal, filterBy} = computed;

export default Model.extend(ValidationEngine, {
validationType: 'post',
Expand Down Expand Up @@ -68,6 +68,7 @@ export default Model.extend(ValidationEngine, {

isPublished: equal('status', 'published'),
isDraft: equal('status', 'draft'),
internalTags: filterBy('tags', 'isInternal', true),

// remove client-generated tags, which have `id: null`.
// Ember Data won't recognize/update them automatically
Expand Down
37 changes: 35 additions & 2 deletions app/models/tag.js
@@ -1,8 +1,17 @@
/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
import Ember from 'ember';
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import ValidationEngine from 'ghost-admin/mixins/validation-engine';

const {
computed,
observer,
inject: {service}
} = Ember;

const {equal} = computed;

export default Model.extend(ValidationEngine, {
validationType: 'tag',

Expand All @@ -14,10 +23,34 @@ export default Model.extend(ValidationEngine, {
metaTitle: attr('string'),
metaDescription: attr('string'),
image: attr('string'),
hidden: attr('boolean'),
visibility: attr('string', {defaultValue: 'public'}),
createdAt: attr('moment-utc'),
updatedAt: attr('moment-utc'),
createdBy: attr(),
updatedBy: attr(),
count: attr('raw')
count: attr('raw'),

isInternal: equal('visibility', 'internal'),
isPublic: equal('visibility', 'public'),

feature: service(),

setVisibility() {
let internalRegex = /^#.?/;

this.set('visibility', internalRegex.test(this.get('name')) ? 'internal' : 'public');
},

save() {
if (this.get('feature.internalTags') && this.get('changedAttributes.name') && !this.get('isDeleted')) {
this.setVisibility();
}
return this._super(...arguments);
},

setVisibilityOnNew: observer('feature.internalTags', 'isNew', 'isSaving', 'name', function () {
if (this.get('isNew') && !this.get('isSaving') && this.get('feature.internalTags')) {
this.setVisibility();
}
})
});
1 change: 1 addition & 0 deletions app/services/feature.js
Expand Up @@ -31,6 +31,7 @@ export default Service.extend({

publicAPI: feature('publicAPI'),
subscribers: feature('subscribers'),
internalTags: feature('internalTags'),

_settings: null,

Expand Down
7 changes: 7 additions & 0 deletions app/templates/components/gh-tag.hbs
Expand Up @@ -2,6 +2,13 @@
{{#link-to 'settings.tags.tag' tag class="tag-edit-button"}}
<span class="tag-title">{{tag.name}}</span>
<span class="label label-default">/{{tag.slug}}</span>

{{#if feature.internalTags}}
{{#if tag.isInternal}}
<span class="label label-blue">internal</span>
{{/if}}
{{/if}}

<p class="tag-description">{{tag.description}}</p>
<span class="tags-count">{{tag.count.posts}}</span>
{{/link-to}}
Expand Down
5 changes: 5 additions & 0 deletions app/templates/posts.hbs
Expand Up @@ -32,6 +32,11 @@
<span class="draft">Draft</span>
{{/if}}
</span>
{{#if feature.internalTags}}
{{#each post.internalTags as |tag|}}
<span class="label label-default">{{tag.name}}</span>
{{/each}}
{{/if}}
</section>
{{/link-to}}
{{/gh-posts-list-item}}
Expand Down
3 changes: 3 additions & 0 deletions app/templates/settings/labs.hbs
Expand Up @@ -53,6 +53,9 @@
{{#gh-feature-flag "subscribers"}}
Subscribers - Collect email addresses from your readers, more info in <a href="http://support.ghost.org/subscribers-beta/">the docs</a>
{{/gh-feature-flag}}
{{#gh-feature-flag "internalTags"}}
Internal Tags - tags which don't show up in your theme. more info in <a href="http://support.ghost.org/internal-tags-beta/">the docs</a>.
{{/gh-feature-flag}}
</div>
</fieldset>
</form>
Expand Down
19 changes: 19 additions & 0 deletions tests/acceptance/settings/tags-test.js
Expand Up @@ -285,6 +285,25 @@ describe('Acceptance: Settings - Tags', function () {
});
});

it('shows the internal tag label', function () {
server.create('tag', {name: '#internal-tag', slug: 'hash-internal-tag', visibility: 'internal'});

visit('settings/tags/');

andThen(() => {
expect(currentURL()).to.equal('/settings/tags/hash-internal-tag');

expect(find('.settings-tags .settings-tag').length, 'tag list count')
.to.equal(1);

expect(find('.settings-tags .settings-tag:first .label.label-blue').length, 'internal tag label')
.to.equal(1);

expect(find('.settings-tags .settings-tag:first .label.label-blue').text().trim(), 'internal tag label text')
.to.equal('internal');
});
});

it('redirects to 404 when tag does not exist', function () {
server.get('/tags/slug/unknown/', function () {
return new Mirage.Response(404, {'Content-Type': 'application/json'}, {errors: [{message: 'Tag not found.', errorType: 'NotFoundError'}]});
Expand Down

0 comments on commit 7d693c1

Please sign in to comment.