diff --git a/public/language/en-GB/admin/manage/categories.json b/public/language/en-GB/admin/manage/categories.json index 8a9ff471b0..124396eb88 100644 --- a/public/language/en-GB/admin/manage/categories.json +++ b/public/language/en-GB/admin/manage/categories.json @@ -7,6 +7,8 @@ "privileges": "Privileges", "back-to-categories": "Back to categories", "name": "Category Name", + "handle": "Category Handle", + "handle.help": "Your category handle is used as a representation of this category across other networks, similar to a username. A category handle must not match an existing username or user group.", "description": "Category Description", "bg-color": "Background Colour", "text-color": "Text Colour", diff --git a/public/language/en-GB/error.json b/public/language/en-GB/error.json index 78945d68a7..fba2f0eaef 100644 --- a/public/language/en-GB/error.json +++ b/public/language/en-GB/error.json @@ -264,6 +264,7 @@ "topic-event-unrecognized": "Topic event '%1' unrecognized", + "category.handle-taken": "Category handle is already taken, please choose another.", "cant-set-child-as-parent": "Can't set child as parent category", "cant-set-self-as-parent": "Can't set self as parent category", diff --git a/src/categories/update.js b/src/categories/update.js index d4be83edb8..517cbeb499 100644 --- a/src/categories/update.js +++ b/src/categories/update.js @@ -49,6 +49,8 @@ module.exports = function (Categories) { return await updateTagWhitelist(cid, value); } else if (key === 'name') { return await updateName(cid, value); + } else if (key === 'handle') { + return await updateHandle(cid, value); } else if (key === 'order') { return await updateOrder(cid, value); } @@ -142,4 +144,22 @@ module.exports = function (Categories) { await db.sortedSetAdd('categories:name', 0, `${newName.slice(0, 200).toLowerCase()}:${cid}`); await db.setObjectField(`category:${cid}`, 'name', newName); } + + async function updateHandle(cid, handle) { + const existing = await Categories.getCategoryField(cid, 'handle'); + if (existing === handle) { + return; + } + + const taken = await meta.slugTaken(handle); + if (taken) { + throw new Error('[[error:category.handle-taken]]'); + } + + await Promise.all([ + db.setObjectField(`category:${cid}`, 'handle', handle), + db.sortedSetRemove('categoryhandle:cid', existing), + db.sortedSetAdd('categoryhandle:cid', cid, handle), + ]); + } }; diff --git a/src/views/admin/manage/category.tpl b/src/views/admin/manage/category.tpl index fb2afcedec..5d35b69c5a 100644 --- a/src/views/admin/manage/category.tpl +++ b/src/views/admin/manage/category.tpl @@ -19,6 +19,16 @@ +
+ + +

+ [[admin/manage/categories:handle.help]] +

+
+