diff --git a/app/assets/javascripts/discourse/components/utilities.coffee b/app/assets/javascripts/discourse/components/utilities.coffee
index e1d26506448..ea98a224898 100644
--- a/app/assets/javascripts/discourse/components/utilities.coffee
+++ b/app/assets/javascripts/discourse/components/utilities.coffee
@@ -11,15 +11,21 @@ Discourse.Utilities =
when 'large' then size=45
return size
+ categoryUrlId: (category) ->
+ return "" unless category
+ id = Em.get(category, 'id')
+ slug = Em.get(category, 'slug')
+ return "#{id}-category" if (!slug) or slug.isBlank()
+ slug
+
# Create a badge like category link
categoryLink: (category) ->
return "" unless category
- slug = Em.get(category, 'slug')
color = Em.get(category, 'color')
name = Em.get(category, 'name')
- "#{name}"
+ "#{name}"
avatarUrl: (username, size, template)->
return "" unless username
diff --git a/app/assets/javascripts/discourse/routes/list_category_route.js.coffee b/app/assets/javascripts/discourse/routes/list_category_route.js.coffee
index 5e38ad1acd2..ddb3a435af4 100644
--- a/app/assets/javascripts/discourse/routes/list_category_route.js.coffee
+++ b/app/assets/javascripts/discourse/routes/list_category_route.js.coffee
@@ -3,11 +3,14 @@ window.Discourse.ListCategoryRoute = Discourse.FilteredListRoute.extend
slug = Em.get(model, 'slug')
category = Discourse.get('site.categories').findProperty('slug', slug)
+ category ||= Discourse.get('site.categories').findProperty('id', parseInt(slug))
category ||= Discourse.Category.create(name: slug, slug: slug)
listController = @controllerFor('list')
- listController.set('filterMode', "category/#{category.get('slug')}")
- listController.load("category/#{category.get('slug')}").then (topicList) =>
+
+ urlId = Discourse.Utilities.categoryUrlId(category)
+ listController.set('filterMode', "category/#{urlId}")
+ listController.load("category/#{urlId}").then (topicList) =>
listController.set('canCreateTopic', topicList.get('can_create_topic'))
listController.set('category',category)
@controllerFor('listTopics').set('content', topicList)
diff --git a/app/assets/javascripts/discourse/views/modal/edit_category_view.js.coffee b/app/assets/javascripts/discourse/views/modal/edit_category_view.js.coffee
index dd364cc7e48..593e6a51c78 100644
--- a/app/assets/javascripts/discourse/views/modal/edit_category_view.js.coffee
+++ b/app/assets/javascripts/discourse/views/modal/edit_category_view.js.coffee
@@ -32,7 +32,7 @@ window.Discourse.EditCategoryView = window.Discourse.ModalBodyView.extend
saveSuccess: (result) ->
$('#discourse-modal').modal('hide')
- window.location = "/category/#{result.category.slug}"
+ window.location = "/category/#{Discourse.Utilities.categoryUrlId(result.category)}"
saveCategory: ->
diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb
index ef2092d7f62..4289426174e 100644
--- a/app/controllers/list_controller.rb
+++ b/app/controllers/list_controller.rb
@@ -38,7 +38,7 @@ class ListController < ApplicationController
if params[:category] == Slug.for(SiteSetting.uncategorized_name) or params[:category] == SiteSetting.uncategorized_name
list = query.list_uncategorized
else
- category = Category.where(slug: params[:category]).includes(:featured_users).first
+ category = Category.where("slug = ? or id = ?", params[:category], params[:category].to_i).includes(:featured_users).first
guardian.ensure_can_see!(category)
list = query.list_category(category)
end
diff --git a/spec/controllers/list_controller_spec.rb b/spec/controllers/list_controller_spec.rb
index a0581b4e12d..6605e738b6b 100644
--- a/spec/controllers/list_controller_spec.rb
+++ b/spec/controllers/list_controller_spec.rb
@@ -34,6 +34,15 @@ describe ListController do
it { should respond_with(:success) }
end
+
+ context 'with a link that includes an id' do
+ before do
+ xhr :get, :category, category: "#{category.slug}-#{category.id}"
+ end
+
+ it { should respond_with(:success) }
+ end
+
end
context 'uncategorized' do
diff --git a/spec/fabricators/category_fabricator.rb b/spec/fabricators/category_fabricator.rb
index f99f8c374fc..fb2fff55208 100644
--- a/spec/fabricators/category_fabricator.rb
+++ b/spec/fabricators/category_fabricator.rb
@@ -2,3 +2,4 @@ Fabricator(:category) do
name 'Amazing Category'
user
end
+
diff --git a/spec/javascripts/utilities_spec.js.coffee b/spec/javascripts/utilities_spec.js.coffee
index cffca63157d..b821d388e9c 100644
--- a/spec/javascripts/utilities_spec.js.coffee
+++ b/spec/javascripts/utilities_spec.js.coffee
@@ -1,6 +1,17 @@
describe "Discourse.Utilities", ->
+ describe "categoryUrlId", ->
+
+ it "returns the slug when it exists", ->
+ expect(Discourse.Utilities.categoryUrlId(slug: 'hello')).toBe("hello")
+
+ it "returns id-category when slug is an empty string", ->
+ expect(Discourse.Utilities.categoryUrlId(id: 123, slug: '')).toBe("123-category")
+
+ it "returns id-category without a slug", ->
+ expect(Discourse.Utilities.categoryUrlId(id: 456)).toBe("456-category")
+
describe "Cooking", ->
cook = (contents, opts) ->
diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb
index de8606f1b8c..96bf849e427 100644
--- a/spec/models/category_spec.rb
+++ b/spec/models/category_spec.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
require 'spec_helper'
describe Category do
@@ -59,6 +61,16 @@ describe Category do
end
end
+ describe 'non-english characters' do
+
+ let(:category) { Fabricate(:category, name: "電車男") }
+
+ it "creates a blank slug, this is OK." do
+ category.slug.should be_blank
+ end
+
+ end
+
describe 'after create' do
before do