Can edit category descriptions, they show up in a `title` attribute
This commit is contained in:
parent
2d9942ceef
commit
532b1f5450
|
@ -40,16 +40,22 @@
|
|||
*/
|
||||
|
||||
categoryLink: function(category) {
|
||||
var color, name;
|
||||
if (!category) {
|
||||
return "";
|
||||
}
|
||||
var color, name, description, result;
|
||||
if (!category) return "";
|
||||
|
||||
color = Em.get(category, 'color');
|
||||
name = Em.get(category, 'name');
|
||||
return "<a href=\"/category/" +
|
||||
(this.categoryUrlId(category)) +
|
||||
"\" class=\"badge-category excerptable\" data-excerpt-size=\"medium\" style=\"background-color: #" + color + "\">" +
|
||||
name + "</a>";
|
||||
description = Em.get(category, 'description');
|
||||
|
||||
// Build the HTML link
|
||||
result = "<a href=\"/category/" +
|
||||
this.categoryUrlId(category) +
|
||||
"\" class=\"badge-category excerptable\" data-excerpt-size=\"medium\" ";
|
||||
|
||||
// Add description if we have it
|
||||
if (description) result += "title=\"" + description + "\" ";
|
||||
|
||||
return result + "style=\"background-color: #" + color + "\">" + name + "</a>";
|
||||
},
|
||||
avatarUrl: function(username, size, template) {
|
||||
var rawSize;
|
||||
|
|
|
@ -312,6 +312,7 @@
|
|||
post.set('cooked', jQuery('#wmd-preview').html());
|
||||
this.set('composeState', CLOSED);
|
||||
post.save(function(savedPost) {
|
||||
|
||||
var idx, postNumber, posts;
|
||||
posts = _this.get('topic.posts');
|
||||
/* perhaps our post came from elsewhere eg. draft
|
||||
|
|
|
@ -144,22 +144,25 @@
|
|||
url: "/posts/" + (this.get('id')),
|
||||
type: 'PUT',
|
||||
data: {
|
||||
post: {
|
||||
raw: this.get('raw')
|
||||
},
|
||||
post: { raw: this.get('raw') },
|
||||
image_sizes: this.get('imageSizes')
|
||||
},
|
||||
success: function(result) {
|
||||
return typeof complete === "function" ? complete(Discourse.Post.create(result)) : void 0;
|
||||
|
||||
console.log(result)
|
||||
|
||||
// If we received a category update, update it
|
||||
if (result.category) Discourse.get('site').updateCategory(result.category);
|
||||
|
||||
return typeof complete === "function" ? complete(Discourse.Post.create(result.post)) : void 0;
|
||||
},
|
||||
error: function(result) {
|
||||
return typeof error === "function" ? error(result) : void 0;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
/* We're saving a post
|
||||
*/
|
||||
|
||||
// We're saving a post
|
||||
data = {
|
||||
post: this.getProperties('raw', 'topic_id', 'reply_to_post_number', 'category'),
|
||||
archetype: this.get('archetype'),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(function() {
|
||||
|
||||
window.Discourse.Site = Discourse.Model.extend({
|
||||
|
||||
notificationLookup: (function() {
|
||||
var result;
|
||||
result = [];
|
||||
|
@ -9,6 +10,7 @@
|
|||
});
|
||||
return result;
|
||||
}).property('notification_types'),
|
||||
|
||||
flagTypes: (function() {
|
||||
var postActionTypes;
|
||||
postActionTypes = this.get('post_action_types');
|
||||
|
@ -17,8 +19,14 @@
|
|||
}
|
||||
return postActionTypes.filterProperty('is_flag', true);
|
||||
}).property('post_action_types.@each'),
|
||||
|
||||
postActionTypeById: function(id) {
|
||||
return this.get("postActionByIdLookup.action" + id);
|
||||
},
|
||||
|
||||
updateCategory: function(newCategory) {
|
||||
var existingCategory = this.get('categories').findProperty('id', Em.get(newCategory, 'id'));
|
||||
if (existingCategory) existingCategory.mergeAttributes(newCategory);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -3,10 +3,17 @@
|
|||
<label>{{i18n category.name}}</label>
|
||||
{{view Discourse.TextField valueBinding="view.category.name" placeholderKey="category.name_placeholder"}}
|
||||
|
||||
{{#if view.category.excerpt}}
|
||||
<div class='description-controls' style="margin-bottom: 20px">
|
||||
<label>{{i18n category.description}}</label>
|
||||
<p>{{view.category.excerpt}} <a href="{{unbound view.category.topic_url}}">{{i18n category.topic}}</a></p>
|
||||
{{/if}}
|
||||
|
||||
{{#if view.category.description}}
|
||||
{{view.category.description}}
|
||||
<a href="#" {{action showCategoryTopic target="view"}}>{{i18n category.change_in_category_topic}}</a>
|
||||
{{else}}
|
||||
{{i18n category.no_description}} <a {{action showCategoryTopic target="view"}} href="#">{{i18n category.change_in_category_topic}}</a>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
|
||||
<label>{{i18n category.color}}</label>
|
||||
|
||||
|
|
|
@ -1,64 +1,72 @@
|
|||
(function() {
|
||||
|
||||
window.Discourse.EditCategoryView = window.Discourse.ModalBodyView.extend({
|
||||
/**
|
||||
A modal view for editing the basic aspects of a category
|
||||
|
||||
@class EditCategoryView
|
||||
@extends Discourse.ModalBodyView
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
|
||||
templateName: 'modal/edit_category',
|
||||
appControllerBinding: 'Discourse.appController',
|
||||
|
||||
disabled: (function() {
|
||||
if (this.get('saving')) {
|
||||
return true;
|
||||
}
|
||||
if (!this.get('category.name')) {
|
||||
return true;
|
||||
}
|
||||
if (!this.get('category.color')) {
|
||||
return true;
|
||||
}
|
||||
if (this.get('saving')) return true;
|
||||
if (!this.get('category.name')) return true;
|
||||
if (!this.get('category.color')) return true;
|
||||
return false;
|
||||
}).property('category.name', 'category.color'),
|
||||
|
||||
colorStyle: (function() {
|
||||
return "background-color: #" + (this.get('category.color')) + ";";
|
||||
}).property('category.color'),
|
||||
|
||||
title: (function() {
|
||||
if (this.get('category.id')) {
|
||||
return "Edit Category";
|
||||
} else {
|
||||
return "Create Category";
|
||||
}
|
||||
if (this.get('category.id')) return Em.String.i18n("category.edit_long");
|
||||
return "Create Category";
|
||||
}).property('category.id'),
|
||||
|
||||
buttonTitle: (function() {
|
||||
if (this.get('saving')) {
|
||||
return "Saving...";
|
||||
} else {
|
||||
return this.get('title');
|
||||
}
|
||||
if (this.get('saving')) return Em.String.i18n("saving");
|
||||
return this.get('title');
|
||||
}).property('title', 'saving'),
|
||||
|
||||
didInsertElement: function() {
|
||||
this._super();
|
||||
if (this.get('category')) {
|
||||
return this.set('id', this.get('category.slug'));
|
||||
this.set('id', this.get('category.slug'));
|
||||
} else {
|
||||
return this.set('category', Discourse.Category.create({
|
||||
color: 'AB9364'
|
||||
}));
|
||||
this.set('category', Discourse.Category.create({ color: 'AB9364' }));
|
||||
}
|
||||
},
|
||||
|
||||
showCategoryTopic: function() {
|
||||
jQuery('#discourse-modal').modal('hide');
|
||||
Discourse.routeTo(this.get('category.topic_url'));
|
||||
return false;
|
||||
},
|
||||
|
||||
saveSuccess: function(result) {
|
||||
jQuery('#discourse-modal').modal('hide');
|
||||
window.location = "/category/" + (Discourse.Utilities.categoryUrlId(result.category));
|
||||
},
|
||||
|
||||
saveCategory: function() {
|
||||
var _this = this;
|
||||
this.set('saving', true);
|
||||
return this.get('category').save({
|
||||
success: function(result) {
|
||||
return _this.saveSuccess(result);
|
||||
_this.saveSuccess(result);
|
||||
},
|
||||
error: function(errors) {
|
||||
_this.displayErrors(errors);
|
||||
return _this.set('saving', false);
|
||||
_this.set('saving', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
|
|
@ -35,23 +35,32 @@ class PostsController < ApplicationController
|
|||
def update
|
||||
requires_parameter(:post)
|
||||
|
||||
@post = Post.where(id: params[:id]).first
|
||||
@post.image_sizes = params[:image_sizes] if params[:image_sizes].present?
|
||||
guardian.ensure_can_edit!(@post)
|
||||
if @post.revise(current_user, params[:post][:raw])
|
||||
TopicLink.extract_from(@post)
|
||||
post = Post.where(id: params[:id]).first
|
||||
post.image_sizes = params[:image_sizes] if params[:image_sizes].present?
|
||||
guardian.ensure_can_edit!(post)
|
||||
|
||||
revisor = PostRevisor.new(post)
|
||||
if revisor.revise!(current_user, params[:post][:raw])
|
||||
TopicLink.extract_from(post)
|
||||
end
|
||||
|
||||
if @post.errors.present?
|
||||
render_json_error(@post)
|
||||
if post.errors.present?
|
||||
render_json_error(post)
|
||||
return
|
||||
end
|
||||
|
||||
post_serializer = PostSerializer.new(@post, scope: guardian, root: false)
|
||||
post_serializer.draft_sequence = DraftSequence.current(current_user, @post.topic.draft_key)
|
||||
link_counts = TopicLinkClick.counts_for(@post.topic, [@post])
|
||||
post_serializer.single_post_link_counts = link_counts[@post.id] if link_counts.present?
|
||||
render_json_dump(post_serializer)
|
||||
post_serializer = PostSerializer.new(post, scope: guardian, root: false)
|
||||
post_serializer.draft_sequence = DraftSequence.current(current_user, post.topic.draft_key)
|
||||
link_counts = TopicLinkClick.counts_for(post.topic, [post])
|
||||
post_serializer.single_post_link_counts = link_counts[post.id] if link_counts.present?
|
||||
|
||||
|
||||
result = {post: post_serializer.as_json}
|
||||
if revisor.category_changed.present?
|
||||
result[:category] = CategorySerializer.new(revisor.category_changed, scope: guardian, root: false).as_json
|
||||
end
|
||||
|
||||
render_json_dump(result)
|
||||
end
|
||||
|
||||
def by_number
|
||||
|
|
|
@ -44,19 +44,6 @@ class Category < ActiveRecord::Base
|
|||
topics_week = (#{topics_week})")
|
||||
end
|
||||
|
||||
# Use the first paragraph of the topic's first post as the excerpt
|
||||
def excerpt
|
||||
if topic.present?
|
||||
first_post = topic.posts.order(:post_number).first
|
||||
body = first_post.cooked
|
||||
matches = body.scan(/\<p\>(.*)\<\/p\>/)
|
||||
if matches and matches[0] and matches[0][0]
|
||||
return matches[0][0]
|
||||
end
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def topic_url
|
||||
topic.try(:relative_url)
|
||||
end
|
||||
|
@ -67,11 +54,17 @@ class Category < ActiveRecord::Base
|
|||
|
||||
after_create do
|
||||
topic = Topic.create!(title: I18n.t("category.topic_prefix", category: name), user: user, visible: false)
|
||||
topic.posts.create!(raw: SiteSetting.category_post_template, user: user)
|
||||
|
||||
post_contents = I18n.t("category.post_template", replace_paragraph: I18n.t("category.replace_paragraph"))
|
||||
topic.posts.create!(raw: post_contents, user: user)
|
||||
update_column(:topic_id, topic.id)
|
||||
topic.update_column(:category_id, self.id)
|
||||
end
|
||||
|
||||
def self.post_template
|
||||
I18n.t("category.post_template", replace_paragraph: I18n.t("category.replace_paragraph"))
|
||||
end
|
||||
|
||||
# We cache the categories in the site json, so we need to invalidate it when they change
|
||||
def invalidate_site_cache
|
||||
Site.invalidate_cache
|
||||
|
|
|
@ -100,8 +100,6 @@ class SiteSetting < ActiveRecord::Base
|
|||
setting(:best_of_score_threshold, 15)
|
||||
setting(:best_of_posts_required, 50)
|
||||
setting(:best_of_likes_required, 1)
|
||||
setting(:category_post_template,
|
||||
"[Replace this first paragraph with a short description of your new category. Try to keep it below 200 characters.]\n\nUse this space below for a longer description, as well as to establish any rules or discussion!")
|
||||
|
||||
# we need to think of a way to force users to enter certain settings, this is a minimal config thing
|
||||
setting(:notification_email, 'info@discourse.org')
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
class CategorySerializer < ApplicationSerializer
|
||||
attributes :id, :name, :color, :slug, :topic_count
|
||||
|
||||
attributes :id,
|
||||
:name,
|
||||
:color,
|
||||
:slug,
|
||||
:topic_count,
|
||||
:description,
|
||||
:topic_url
|
||||
|
||||
end
|
||||
|
|
|
@ -519,6 +519,7 @@ en:
|
|||
category:
|
||||
none: '(no category)'
|
||||
edit: 'edit'
|
||||
edit_long: "Edit Category"
|
||||
view: 'View Topics in Category'
|
||||
delete: 'Delete Category'
|
||||
create: 'Create Category'
|
||||
|
@ -531,6 +532,8 @@ en:
|
|||
color_placeholder: "Any web color"
|
||||
delete_confirm: "Are you sure you want to delete that category?"
|
||||
list: "List Categories"
|
||||
no_description: "There is no description for this category."
|
||||
change_in_category_topic: "visit category topic to edit the description"
|
||||
|
||||
flagging:
|
||||
title: 'Why are you flagging this post?'
|
||||
|
|
|
@ -228,7 +228,6 @@ nl:
|
|||
exclude_rel_nofollow_domains: "Een commagescheiden lijst van domeinen waar 'nofollow' niet is toegevoegd. (voorbeelddomein.com zal automatisch sub.voorbeelddomein.com toestaan)"
|
||||
post_excerpt_maxlength: "Maximale lengte in karakters van een post-uittreksel."
|
||||
post_onebox_maxlength: "Maximale lengte van een 'oneboxed' discourse post."
|
||||
category_post_template: "De post-template die verschijnt wanneer je een categorie aanmaakt"
|
||||
new_topics_rollup: "Hoeveel topics er aan een topic-lijst kunnen worden toegevoegd voordat de lijst oprolt."
|
||||
onebox_max_chars: "Het maximaal aantal karakters dat een 'onebox' zal importeren in een lap text."
|
||||
logo_url: "Het logo van je site bijv: http://xyz.com/x.png"
|
||||
|
|
|
@ -62,6 +62,8 @@ en:
|
|||
|
||||
category:
|
||||
topic_prefix: "Category definition for %{category}"
|
||||
replace_paragraph: "[Replace this first paragraph with a short description of your new category. Try to keep it below 200 characters.]"
|
||||
post_template: "%{replace_paragraph}\n\nUse this space below for a longer description, as well as to establish any rules or discussion!"
|
||||
|
||||
trust_levels:
|
||||
new:
|
||||
|
@ -254,7 +256,6 @@ en:
|
|||
exclude_rel_nofollow_domains: "A comma delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"
|
||||
post_excerpt_maxlength: "Maximum length in chars of a post's excerpt."
|
||||
post_onebox_maxlength: "Maximum length of a oneboxed discourse post."
|
||||
category_post_template: "The post template that appears once you create a category"
|
||||
new_topics_rollup: "How many topics can be inserted on the topic list before rolling up."
|
||||
onebox_max_chars: "The maximum amount of characters a onebox will import in a text blob."
|
||||
logo_url: "The logo for your site eg: http://xyz.com/x.png"
|
||||
|
|
|
@ -261,7 +261,6 @@ fr:
|
|||
exclude_rel_nofollow_domains: "Une liste séparée par des virgules contenant les noms de domaines de premier niveau pour lesquels il faut ajouter un attribut nofollow (exemple.com va automatiquement fonctionner aussi avec sous.domaine.exemple.com)"
|
||||
post_excerpt_maxlength: "Longueur maximale d'un extrait de message."
|
||||
post_onebox_maxlength: "Longueur maximale d'un message emboîté."
|
||||
category_post_template: "Le modèle de message qui va apparaitre quand vous créez une catégorie"
|
||||
new_topics_rollup: "Combien de discussions peuvent être insérées dans la liste des discussions avant de remonter."
|
||||
onebox_max_chars: "Nombre maximal de caractères qu'une boîte peut importer en blob de texte."
|
||||
logo_url: "Le logo de votre site, par exemple: http://xyz.com/x.png"
|
||||
|
|
|
@ -255,7 +255,6 @@ nl:
|
|||
exclude_rel_nofollow_domains: "Een commagescheiden lijst van domeinen waar 'nofollow' niet is toegevoegd. (voorbeelddomein.com zal automatisch sub.voorbeelddomein.com toestaan)"
|
||||
post_excerpt_maxlength: "Maximale lengte in karakters van een post-uittreksel."
|
||||
post_onebox_maxlength: "Maximale lengte van een 'oneboxed' discourse post."
|
||||
category_post_template: "De post-template die verschijnt wanneer je een categorie aanmaakt"
|
||||
new_topics_rollup: "Hoeveel topics er aan een topic-lijst kunnen worden toegevoegd voordat de lijst oprolt."
|
||||
onebox_max_chars: "Het maximaal aantal karakters dat een 'onebox' zal importeren in een lap tekst."
|
||||
logo_url: "Het logo van je site bijv: http://xyz.com/x.png"
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
class AddDescriptionToCategories < ActiveRecord::Migration
|
||||
def up
|
||||
add_column :categories, :description, :text, null: true
|
||||
|
||||
# While we're at it, remove unused columns
|
||||
remove_column :categories, :top1_topic_id
|
||||
remove_column :categories, :top2_topic_id
|
||||
remove_column :categories, :top1_user_id
|
||||
remove_column :categories, :top2_user_id
|
||||
|
||||
# Migrate excerpts over
|
||||
Category.all.each do |c|
|
||||
excerpt = c.excerpt
|
||||
unless excerpt == I18n.t("category.replace_paragraph")
|
||||
c.update_column(:description, c.excerpt)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :categories, :description
|
||||
end
|
||||
|
||||
end
|
|
@ -1222,10 +1222,6 @@ CREATE TABLE categories (
|
|||
name character varying(50) NOT NULL,
|
||||
color character varying(6) DEFAULT 'AB9364'::character varying NOT NULL,
|
||||
topic_id integer,
|
||||
top1_topic_id integer,
|
||||
top2_topic_id integer,
|
||||
top1_user_id integer,
|
||||
top2_user_id integer,
|
||||
topic_count integer DEFAULT 0 NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
|
@ -1233,7 +1229,8 @@ CREATE TABLE categories (
|
|||
topics_year integer,
|
||||
topics_month integer,
|
||||
topics_week integer,
|
||||
slug character varying(255) NOT NULL
|
||||
slug character varying(255) NOT NULL,
|
||||
description text
|
||||
);
|
||||
|
||||
|
||||
|
@ -1242,7 +1239,7 @@ CREATE TABLE categories (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE categories_id_seq
|
||||
START WITH 5
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1327,7 +1324,7 @@ CREATE TABLE draft_sequences (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE draft_sequences_id_seq
|
||||
START WITH 20
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1361,7 +1358,7 @@ CREATE TABLE drafts (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE drafts_id_seq
|
||||
START WITH 2
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1394,7 +1391,7 @@ CREATE TABLE email_logs (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE email_logs_id_seq
|
||||
START WITH 3
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1429,7 +1426,7 @@ CREATE TABLE email_tokens (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE email_tokens_id_seq
|
||||
START WITH 3
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1642,7 +1639,7 @@ CREATE TABLE onebox_renders (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE onebox_renders_id_seq
|
||||
START WITH 2
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1676,7 +1673,7 @@ CREATE TABLE post_action_types (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE post_action_types_id_seq
|
||||
START WITH 6
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1807,7 +1804,7 @@ CREATE TABLE posts (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE posts_id_seq
|
||||
START WITH 16
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1898,7 +1895,7 @@ CREATE TABLE site_settings (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE site_settings_id_seq
|
||||
START WITH 4
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -1930,7 +1927,7 @@ CREATE TABLE topic_allowed_users (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE topic_allowed_users_id_seq
|
||||
START WITH 3
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -2122,7 +2119,7 @@ CREATE TABLE topics (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE topics_id_seq
|
||||
START WITH 16
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -2228,7 +2225,7 @@ CREATE TABLE user_actions (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE user_actions_id_seq
|
||||
START WITH 40
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -2292,7 +2289,7 @@ CREATE TABLE user_visits (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE user_visits_id_seq
|
||||
START WITH 4
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -2359,7 +2356,7 @@ CREATE TABLE users (
|
|||
--
|
||||
|
||||
CREATE SEQUENCE users_id_seq
|
||||
START WITH 3
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
|
@ -4578,4 +4575,6 @@ INSERT INTO schema_migrations (version) VALUES ('20130208220635');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20130213021450');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20130213203300');
|
||||
INSERT INTO schema_migrations (version) VALUES ('20130213203300');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20130221215017');
|
|
@ -1,5 +1,8 @@
|
|||
require 'edit_rate_limiter'
|
||||
class PostRevisor
|
||||
|
||||
attr_reader :category_changed
|
||||
|
||||
def initialize(post)
|
||||
@post = post
|
||||
end
|
||||
|
@ -8,6 +11,7 @@ class PostRevisor
|
|||
@user, @new_raw, @opts = user, new_raw, opts
|
||||
return false if not should_revise?
|
||||
revise_post
|
||||
update_category_description
|
||||
post_process_post
|
||||
true
|
||||
end
|
||||
|
@ -76,6 +80,25 @@ class PostRevisor
|
|||
@post.save
|
||||
end
|
||||
|
||||
def update_category_description
|
||||
# If we're revising the first post, we might have to update the category description
|
||||
return unless @post.post_number == 1
|
||||
|
||||
# Is there a category with our topic id?
|
||||
category = Category.where(topic_id: @post.topic_id).first
|
||||
return unless category.present?
|
||||
|
||||
# If found, update its description
|
||||
body = @post.cooked
|
||||
matches = body.scan(/\<p\>(.*)\<\/p\>/)
|
||||
if matches and matches[0] and matches[0][0]
|
||||
new_description = matches[0][0]
|
||||
new_description = nil if new_description == I18n.t("category.replace_paragraph")
|
||||
category.update_column(:description, new_description)
|
||||
@category_changed = category
|
||||
end
|
||||
end
|
||||
|
||||
def post_process_post
|
||||
@post.invalidate_oneboxes = true
|
||||
@post.trigger_post_process
|
||||
|
|
|
@ -43,6 +43,11 @@ describe PostRevisor do
|
|||
it "doesn't change the last_version_at" do
|
||||
post.last_version_at.should == first_version_at
|
||||
end
|
||||
|
||||
it "doesn't update a category" do
|
||||
subject.category_changed.should be_blank
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'revision much later' do
|
||||
|
@ -55,6 +60,10 @@ describe PostRevisor do
|
|||
post.reload
|
||||
end
|
||||
|
||||
it "doesn't update a category" do
|
||||
subject.category_changed.should be_blank
|
||||
end
|
||||
|
||||
it 'updates the cached_version' do
|
||||
post.cached_version.should == 2
|
||||
end
|
||||
|
@ -82,6 +91,10 @@ describe PostRevisor do
|
|||
post.last_version_at.to_i.should == revised_at.to_i
|
||||
end
|
||||
|
||||
it "doesn't update a category" do
|
||||
subject.category_changed.should be_blank
|
||||
end
|
||||
|
||||
context "after second window" do
|
||||
|
||||
let!(:new_revised_at) {revised_at + 2.minutes}
|
||||
|
@ -102,6 +115,68 @@ describe PostRevisor do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'category topic' do
|
||||
|
||||
let!(:category) do
|
||||
category = Fabricate(:category)
|
||||
category.update_column(:topic_id, topic.id)
|
||||
category
|
||||
end
|
||||
|
||||
let(:new_description) { "this is my new description." }
|
||||
|
||||
it "should have to description by default" do
|
||||
category.description.should be_blank
|
||||
end
|
||||
|
||||
context "one paragraph description" do
|
||||
before do
|
||||
subject.revise!(post.user, new_description)
|
||||
category.reload
|
||||
end
|
||||
|
||||
it "returns true for category_changed" do
|
||||
subject.category_changed.should be_true
|
||||
end
|
||||
|
||||
it "updates the description of the category" do
|
||||
category.description.should == new_description
|
||||
end
|
||||
end
|
||||
|
||||
context "multiple paragraph description" do
|
||||
before do
|
||||
subject.revise!(post.user, "#{new_description}\n\nOther content goes here.")
|
||||
category.reload
|
||||
end
|
||||
|
||||
it "returns the changed category info" do
|
||||
subject.category_changed.should == category
|
||||
end
|
||||
|
||||
it "updates the description of the category" do
|
||||
category.description.should == new_description
|
||||
end
|
||||
end
|
||||
|
||||
context 'when updating back to the original paragraph' do
|
||||
before do
|
||||
category.update_column(:description, 'this is my description')
|
||||
subject.revise!(post.user, Category.post_template)
|
||||
category.reload
|
||||
end
|
||||
|
||||
it "puts the description back to nothing" do
|
||||
category.description.should be_blank
|
||||
end
|
||||
|
||||
it "returns true for category_changed" do
|
||||
subject.category_changed.should == category
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'rate limiter' do
|
||||
let(:changed_by) { Fabricate(:coding_horror) }
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ describe PostsController do
|
|||
end
|
||||
|
||||
it "calls revise with valid parameters" do
|
||||
Post.any_instance.expects(:revise).with(post.user, 'edited body')
|
||||
PostRevisor.any_instance.expects(:revise!).with(post.user, 'edited body')
|
||||
xhr :put, :update, update_params
|
||||
end
|
||||
|
||||
|
|
|
@ -83,6 +83,10 @@ describe Category do
|
|||
@category.slug.should == 'amazing-category'
|
||||
end
|
||||
|
||||
it 'has a default description' do
|
||||
@category.description.should be_blank
|
||||
end
|
||||
|
||||
it 'has one topic' do
|
||||
Topic.where(category_id: @category).count.should == 1
|
||||
end
|
||||
|
@ -107,14 +111,12 @@ describe Category do
|
|||
@topic.posts.count.should == 1
|
||||
end
|
||||
|
||||
it 'should have an excerpt' do
|
||||
@category.excerpt.should be_present
|
||||
end
|
||||
|
||||
it 'should have a topic url' do
|
||||
@category.topic_url.should be_present
|
||||
end
|
||||
|
||||
|
||||
|
||||
describe "trying to change the category topic's category" do
|
||||
|
||||
before do
|
||||
|
@ -166,8 +168,7 @@ describe Category do
|
|||
context 'with regular topics' do
|
||||
|
||||
before do
|
||||
@category.topics << Fabricate(:topic,
|
||||
user: @category.user)
|
||||
@category.topics << Fabricate(:topic, user: @category.user)
|
||||
Category.update_stats
|
||||
@category.reload
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue