working on post URL slugs

This commit is contained in:
Sacha Greif 2015-06-18 13:04:38 +09:00
parent 3741552713
commit 7e48d49366
16 changed files with 81 additions and 47 deletions

View file

@ -85,6 +85,7 @@ oauth@1.1.4
oauth1@1.1.4
oauth2@1.1.3
observe-sequence@1.0.6
ongoworks:speakingurl@5.0.1
ordered-dict@1.0.3
package-version-parser@3.0.3
percolatestudio:synced-cron@1.1.0

View file

@ -1,7 +1,7 @@
<template name="post_thumbnail">
{{#if thumbnailUrl}}
<div class="post-thumbnail" aria-hidden="true">
<a class="post-thumbnail-link {{playVideoClass}}" href="{{postLink}}" target="_blank">
<a class="post-thumbnail-link {{playVideoClass}}" href="{{postLink}}" target="{{target}}">
<img class="post-thumbnail-image" src="{{thumbnailUrl}}" onerror="this.style.display='none';" aria-hidden="true"/>
</a>
</div>

View file

@ -1,6 +1,9 @@
Template.post_thumbnail.helpers({
postLink: function () {
return !!this.url ? Posts.getOutgoingUrl(this.url) : "/posts/"+this._id;
return Posts.getLink(this);
},
target: function () {
return !!this.url? "_blank" : "";
},
playVideoClass: function () {
return !!this.media ? 'post-thumbnail-has-video': '';

View file

@ -140,13 +140,10 @@ Telescope.utils.getPostCommentUrl = function(postId, commentId) {
});
};
Telescope.utils.slugify = function(text) {
if(text){
text = text.replace(/[^-_a-zA-Z0-9,&\s]+/ig, '');
text = text.replace(/\s/gi, "-");
text = text.toLowerCase();
}
return text;
Telescope.utils.slugify = function (s) {
return getSlug(s, {
truncate: 60
});
};
Telescope.utils.getShortUrl = function(post) {

View file

@ -50,7 +50,8 @@ Package.onUse(function (api) {
'jparker:gravatar@0.3.1',
'sanjo:meteor-files-helpers@1.1.0_4',
'cmather:handlebars-server@0.2.0',
'chuangbo:cookie@1.1.0'
'chuangbo:cookie@1.1.0',
'ongoworks:speakingurl@5.0.1'
];
api.use(packages);

View file

@ -683,6 +683,17 @@ var migrationsList = {
});
return i;
},
addSlugsToPosts: function () {
var i = 0;
Posts.find({slug: {$exists : false}}).forEach(function (post) {
i++;
var slug = Telescope.utils.slugify(post.title);
console.log("Post: "+post._id + " | "+slug);
Posts.update(post._id, { $set: { 'slug': slug}});
console.log("---------------------");
});
return i;
}
};

View file

@ -1,6 +1,6 @@
<template name="post_comments_link">
<div class="post-meta-item">
<a class="comments-link" href="/posts/{{_id}}">
<a class="comments-link" href="{{pathFor 'post_page'}}">
<span class="comments-count">{{commentCount}}</span>
<span class="comments-action">{{_ 'comments_'}}</span>
</a>

View file

@ -1,18 +0,0 @@
Template.post_content.helpers({
sourceLink: function(){
return !!this.url ? this.url : "/posts/"+this._id;
},
current_domain: function(){
return "http://"+document.domain;
},
timestamp: function(){
var time = this.status === Posts.config.STATUS_APPROVED ? this.postedAt : this.createdAt;
return moment(time).format("MMMM Do, h:mm:ss a");
},
inactiveClass: function(){
return (Users.is.admin(Meteor.user()) && this.inactive) ? i18n.t('inactive') : "";
},
commentsDisplayText: function(){
return this.comments === 1 ? i18n.t('comment') : i18n.t('comments');
}
});

View file

@ -1,5 +1,5 @@
<template name="post_discuss">
<a class="discuss-link go-to-comments action" href="/posts/{{_id}}" title="{{_ 'discuss'}}">
<a class="discuss-link go-to-comments action" href="{{pathFor 'post_page'}}" title="{{_ 'discuss'}}">
{{{icon "comment"}}}
<span class="action-count">{{commentCount}}</span>
<span class="sr-only"> {{_ "comments"}}</span>

View file

@ -1,6 +1,6 @@
Template.post_title.helpers({
postLink: function(){
return !!this.url ? Posts.getOutgoingUrl(this.url) : "/posts/"+this._id;
return Posts.getLink(this);
},
postTarget: function() {
return !!this.url ? '_blank' : '';

View file

@ -33,7 +33,7 @@ AutoForm.hooks({
onSuccess: function(operation, post) {
this.template.$('button[type=submit]').removeClass('loading');
Events.track("new post", {'postId': post._id});
Router.go('post_page', {_id: post._id});
Router.go('post_page', post);
},
onError: function(operation, error) {
@ -43,7 +43,7 @@ AutoForm.hooks({
// $(e.target).removeClass('disabled');
if (error.error === 603) {
var dupePostId = error.reason.split('|')[1];
Router.go('post_page', {_id: dupePostId});
Router.go('post_page', {slug: '_', _id: dupePostId});
}
}

View file

@ -41,28 +41,28 @@ Posts.getDefaultStatus = function (user) {
}
};
/**
* Return a post's link if it has one, else return its post page URL
* @param {Object} post
*/
Posts.getLink = function (post) {
return !!post.url ? Posts.getOutgoingUrl(post.url) : this.getPageUrl(post);
};
/**
* Get URL of a post page.
* @param {Object} post
*/
Posts.getPageUrl = function(post){
return Telescope.utils.getSiteUrl()+'posts/'+post._id;
return Router.path("post_page", post);
};
/**
* Get post edit page URL.
* @param {String} id
*/
Posts.getEditUrl = function(id){
return Telescope.utils.getSiteUrl()+'posts/'+id+'/edit';
};
/**
* Return a post's link if it has one, else return its post page URL
* @param {Object} post
*/
Posts.getLink = function (post) {
return !!post.url ? Posts.getOutgoingUrl(post.url) : this.getPageUrl(post);
Posts.getEditUrl = function(post){
return Router.path("post_edit", post);
};
/**

View file

@ -52,6 +52,9 @@ Posts.submit = function (post) {
// clean up post title
post.title = Telescope.utils.cleanUp(post.title);
// generate slug
post.slug = Telescope.utils.slugify(post.title);
// ------------------------------ Callbacks ------------------------------ //
// run all post submit server callbacks on post object successively
@ -80,7 +83,6 @@ Posts.edit = function (postId, modifier, post) {
post = Posts.findOne(postId);
}
// ------------------------------ Callbacks ------------------------------ //
// run all post edit server callbacks on modifier successively

View file

@ -48,6 +48,13 @@ Posts.schema = new SimpleSchema({
optional: false,
editableBy: ["member", "admin"]
},
/**
Slug
*/
slug: {
type: String,
optional: true
},
/**
Post body (markdown)
*/
@ -249,3 +256,13 @@ Posts.before.update(function (userId, doc, fieldNames, modifier) {
modifier.$set.htmlBody = Telescope.utils.sanitize(marked(modifier.$set.body));
}
});
/**
* Generate slug when post title is updated
*/
Posts.before.update(function (userId, doc, fieldNames, modifier) {
// if title is being modified, update slug too
if (Meteor.isServer && modifier.$set && modifier.$set.title) {
modifier.$set.slug = Telescope.utils.slugify(marked(modifier.$set.title));
}
});

View file

@ -130,7 +130,7 @@ Posts.controllers.page = RouteController.extend({
return this.post().title;
},
onBeforeAction: function() {
onBeforeAction: function () {
if (! this.post()) {
if (this.postSubscription.ready()) {
this.render('not_found');
@ -151,6 +151,14 @@ Posts.controllers.page = RouteController.extend({
data: function() {
return this.post();
},
onAfterAction: function () {
var post = this.post();
if (post && post.slug !== this.params.slug) {
Router.go("post_page", post);
}
},
fastRender: true
});
@ -196,7 +204,19 @@ Meteor.startup(function () {
// Post Page
// legacy route
Router.route('/posts/:_id', {
name: 'post_page_id',
onBeforeAction: function () {
var post = {
slug: '_',
_id: this.params._id
};
Router.go("post_page", post);
}
});
Router.route('/p/:slug/:_id', {
name: 'post_page',
controller: Posts.controllers.page
});

View file

@ -1,7 +1,7 @@
Meteor.startup(function () {
Template.post_share.helpers({
sourceLink: function(){
return !!this.url ? this.url : Telescope.utils.getSiteUrl() + "posts/"+this._id;
return !!this.url ? this.url : Posts.getPageUrl(this);
},
viaTwitter: function () {
return !!Settings.get('twitterAccount') ? 'via='+Settings.get('twitterAccount') : '';