From e16e04cf0bbb0756a472902ab11ae9b851d795af Mon Sep 17 00:00:00 2001
From: "David M. Johnson"
Date: Wed, 11 Nov 2026 17:40:25 -0500
Subject: [PATCH 1/4] Redesign the categories page
- Categories are one list in display order. Drag a category by its handle,
or use the arrow keys on the handle, to reorder them; the order is saved
through a new categories!reorder action and is the order themes show.
- Each category shows how many entries it has (any status), linked to the
entries page filtered by that category. The counts come from one grouped
query, which also decides whether a delete must move entries.
- Add and edit share one dialog with field-level validation and an image
preview; the Save button is disabled while a field is invalid.
- Deleting a category that has entries, or that blogging clients post to,
asks where to move them; the delete button stays disabled until a target
is chosen.
- Add replaces the sidebar link with a button in the page; the page is laid
out for phones, and a toast confirms each change after the reload.
- Removes the unused categories!move action, CategoriesSidebar.jsp and the
strings only they used, and escapes every message the page puts in an
HTML attribute.
---
CHANGES.md | 8 +
.../business/WeblogEntryManager.java | 9 +
.../jpa/JPAWeblogEntryManagerImpl.java | 20 +
.../ui/struts2/editor/Categories.java | 142 ++++--
.../resources/ApplicationResources.properties | 42 +-
.../ApplicationResources_de.properties | 7 -
.../ApplicationResources_es.properties | 6 -
.../ApplicationResources_fr.properties | 9 -
.../ApplicationResources_ja.properties | 9 -
.../ApplicationResources_ko.properties | 8 -
.../ApplicationResources_ru.properties | 8 -
.../ApplicationResources_zh_CN.properties | 8 -
app/src/main/resources/struts.xml | 2 +-
.../webapp/WEB-INF/jsps/editor/Categories.jsp | 450 +++++++-----------
.../WEB-INF/jsps/editor/CategoriesSidebar.jsp | 55 ---
app/src/main/webapp/WEB-INF/tiles.xml | 3 +-
.../webapp/roller-ui/scripts/categories.js | 331 +++++++++++++
.../main/webapp/roller-ui/styles/roller.css | 146 ++++++
.../business/WeblogCategoryCRUDTest.java | 25 +
.../ui/struts2/editor/CategoriesTest.java | 150 ++++++
.../util/StrutsParameterAnnotationTest.java | 3 +-
.../org/apache/roller/playwright/BaseIT.java | 12 +-
22 files changed, 992 insertions(+), 461 deletions(-)
delete mode 100644 app/src/main/webapp/WEB-INF/jsps/editor/CategoriesSidebar.jsp
create mode 100644 app/src/main/webapp/roller-ui/scripts/categories.js
create mode 100644 app/src/test/java/org/apache/roller/weblogger/ui/struts2/editor/CategoriesTest.java
diff --git a/CHANGES.md b/CHANGES.md
index fa53dc8836..9a1a9b502d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,14 @@
- A details page for each file, with a preview, its facts, a copy-URL
button and the edit form. The description is used as the image's alt text.
+- **Redesigned categories page.** Categories are one list you can reorder.
+ - Drag a category by its handle, or use the arrow keys on the handle, to
+ change the order themes show categories in.
+ - Each category shows how many entries it has, linked to those entries.
+ - Add and edit in one dialog with field-level checks and an image preview.
+ Deleting a category that has entries asks where to move them.
+ - The page works on phones, and a short message confirms each change.
+
- **AtomPub can manage templates and categories.** New collections
in each weblog's workspace, documented in the user guide:
- Templates (standard and mobile versions) for weblog administrators,
diff --git a/app/src/main/java/org/apache/roller/weblogger/business/WeblogEntryManager.java b/app/src/main/java/org/apache/roller/weblogger/business/WeblogEntryManager.java
index f841193e72..4f4ee69662 100644
--- a/app/src/main/java/org/apache/roller/weblogger/business/WeblogEntryManager.java
+++ b/app/src/main/java/org/apache/roller/weblogger/business/WeblogEntryManager.java
@@ -281,6 +281,15 @@ boolean isDuplicateWeblogCategoryName(WeblogCategory data)
*/
boolean isWeblogCategoryInUse(WeblogCategory data)
throws WebloggerException;
+
+ /**
+ * Count the entries in each of a weblog's categories, in any status.
+ *
+ * @return entry counts keyed by category id; categories with no entries
+ * are not in the map
+ */
+ Map getWeblogCategoryEntryCounts(Weblog weblog)
+ throws WebloggerException;
/**
diff --git a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogEntryManagerImpl.java b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogEntryManagerImpl.java
index 93a478a9ed..d13c8e1acf 100644
--- a/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogEntryManagerImpl.java
+++ b/app/src/main/java/org/apache/roller/weblogger/business/jpa/JPAWeblogEntryManagerImpl.java
@@ -652,6 +652,26 @@ public boolean isWeblogCategoryInUse(WeblogCategory cat)
int entryCount = q.getResultList().size();
return entryCount > 0;
}
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public Map getWeblogCategoryEntryCounts(Weblog weblog)
+ throws WebloggerException {
+ if (weblog == null) {
+ throw new WebloggerException("weblog is null");
+ }
+ TypedQuery
-categoryDeleteOK.moveToWhere=Move the contents to another category:
-categoryDeleteOK.noEntriesInCat=There are no weblog entries in this category, \
-OK to delete.
-categoryDeleteOK.areYouSure=Are you sure you want to delete this weblog category?
+categoryDeleteOK.heading=Delete category "{0}"?
+categoryDeleteOK.delete=Delete category
+categoryDeleteOK.chooseCategory=Choose a category
+categoryDeleteOK.entriesInCategory={0,choice,1#1 entry is|1<{0,number,integer} entries are} in this category. \
+Choose a category to move them to.
+categoryDeleteOK.warningCatInUse=Blogging clients use this category as their default. \
+Choose a category to use instead.
+categoryDeleteOK.moveToWhere=Move to
+categoryDeleteOK.noEntriesInCat=No entries are in this category.
# ----------------------------------------------------------------- comments.jsp
diff --git a/app/src/main/resources/ApplicationResources_de.properties b/app/src/main/resources/ApplicationResources_de.properties
index 35d9ca6734..90d3eab502 100644
--- a/app/src/main/resources/ApplicationResources_de.properties
+++ b/app/src/main/resources/ApplicationResources_de.properties
@@ -145,21 +145,14 @@ calendar.prev=Voriger
calendar.summary=Blog Archiv Kalender
calendar.today=Heute
categoriesForm.addCategory=Kategorie hinzuf\u00FCgen
-categoriesForm.move=Verschieben
-categoriesForm.move.confirm=Ausgew\u00E4hlte Kategorien verschieben?
# ---------------------------------------------------------- CategoriesForm.jsp
-categoriesForm.remove=L\u00F6schen
-categoriesForm.root=root
categoriesForm.rootPrompt=Dies sind Ihre Kategorien auf der obersten Ebene. Sie k\u00F6nnen diese Kategorien verwenden um Ihre Weblogeintr\u00E4ge zu organisieren und Ihre Leser k\u00F6nnen zwischen unterschiedlichen Newsfeeds f\u00FCr Ihre Kategorien w\u00E4hlen.
categoriesForm.rootTitle=Kategorien
categoriesForm.subtitle=Kategorien in Weblog {0} verwalten
-categoryDeleteOK.areYouSure=Sind Sie sicher, dass Sie diese Kategorie l\u00F6schen wollen?
categoryDeleteOK.moveToWhere=Verschiebe die Inhalte in eine andere Kategorie:
categoryDeleteOK.noEntriesInCat=Es gibt keine Weblogeintr\u00E4ge in dieser Kategorie. Klicken Sie auf 'Ok' um die Kategorie zu l\u00F6schen
# ------------------------------------------------------- CategoryDeleteOK.jsp
-categoryDeleteOK.removeCategory=L\u00F6sche Kategorie
categoryDeleteOK.warningCatInUse=WARNUNG: Diese Kategorie wird benutzt!
-categoryDeleteOK.youMustMoveEntries=Sie m\u00FCssen die Eintr\u00E4ge in der Kategorie in eine andere Kategorie verschieben, w\u00E4hlen Sie dazu in der Auswahlliste die Zielkategorie, welche die Eintr\u00E4ge erhalten soll.
categoryForm.add.title=Kategorie hinzuf\u00FCgen
categoryForm.edit.subtitle=Kategorie bearbeiten
# ------------------------------------------------------------- CategoryForm.jsp
diff --git a/app/src/main/resources/ApplicationResources_es.properties b/app/src/main/resources/ApplicationResources_es.properties
index e8e795526a..604cb34585 100644
--- a/app/src/main/resources/ApplicationResources_es.properties
+++ b/app/src/main/resources/ApplicationResources_es.properties
@@ -64,18 +64,12 @@ categoryForm.add.title=A\u00F1adir categor\u00EDa
categoryForm.add.subtitle=A\u00F1adiendo categor\u00EDa
categoryForm.image=imagen
categoriesForm.subtitle=Administrar categor\u00EDas en weblog {0}
-categoriesForm.root=ra\u00EDz
categoriesForm.rootTitle=Categor\u00EDas
categoriesForm.rootPrompt=Estas son sus categor\u00EDas weblog de nivel superior. Puede usar categor\u00EDas para organizar sus entradas de weblog y sus lectores pueden elegir suscribirse cada una de sus categor\u00EDas.
categoriesForm.addCategory=A\u00F1adir categor\u00EDa
-categoriesForm.move=Mover
-categoriesForm.remove=Eliminar
-categoryDeleteOK.removeCategory=Eliminar categor\u00EDa del weblog
categoryDeleteOK.warningCatInUse=ALERTA\: \u00A1La categor\u00EDa est\u00E1 en uso\!
-categoryDeleteOK.youMustMoveEntries=Debe mover las entradas del weblog de una categor\u00EDa a otra, use el combo-box para seleccionar qu\u00E9 categor\u00EDa debe recibir las entradas.
categoryDeleteOK.moveToWhere=Mover los contenidos a otra categor\u00EDa\:
categoryDeleteOK.noEntriesInCat=No hay entradas del weblog en esta categor\u00EDa, OK para eliminar.
-categoryDeleteOK.areYouSure=\u00BFEst\u00E1 seguro de que desea eliminar esta categor\u00EDa del weblog?
comments.title=Comentario
comments.header=Enviar un comentario
comments.email=Correo electr\u00F3nico\:
diff --git a/app/src/main/resources/ApplicationResources_fr.properties b/app/src/main/resources/ApplicationResources_fr.properties
index 8c7f4c3624..380c522e8d 100644
--- a/app/src/main/resources/ApplicationResources_fr.properties
+++ b/app/src/main/resources/ApplicationResources_fr.properties
@@ -109,7 +109,6 @@ categoryForm.error.duplicateName=Il existe déjà une catégorie nommée '{0}'.
# ----------------------------------------------------------- CategoriesForm.jsp
categoriesForm.subtitle=Gérer les catégories du blog {0}
-categoriesForm.root=Racine
categoriesForm.rootTitle=Catégories
categoriesForm.rootPrompt=\
Vous trouverez ci-dessous la liste de vos catégories de plus haut niveau. \
@@ -119,20 +118,12 @@ Vous pouvez aussi définir des sous-catégories, cependant la plupart des macros
affichent seulement les catégories de plus haut niveau. Il vous faudra modifier votre modèle \
si vous désirer afficher les sous-catégories.
categoriesForm.addCategory=Ajouter une catégorie
-categoriesForm.move=Déplacer
-categoriesForm.move.confirm=Déplacer les catégories sélectionnées ?
-categoriesForm.remove=Effacer
# --------------------------------------------------------- catégorieDeleteOK.jsp
-categoryDeleteOK.removeCategory=Effacer une catégorie
categoryDeleteOK.warningCatInUse=ATTENTION: Cette catégorie est en cours d'utilisation !
-categoryDeleteOK.youMustMoveEntries=Vous devez déplacer les entrées de votre blog appartenant à \
-cette catégorie dans une autre catégorie. Sélectionnez quelle catégorie recevra ces entrées dans la \
-boite de sélection.
categoryDeleteOK.moveToWhere=Déplacer le contenu dans une autre catégorie :
categoryDeleteOK.noEntriesInCat=Il n'y a pas d'entrée dans cette catégorie.
-categoryDeleteOK.areYouSure=Etes vous certain de vouloir effacer cette catégorie ?
# ----------------------------------------------------------------- comments.jsp
diff --git a/app/src/main/resources/ApplicationResources_ja.properties b/app/src/main/resources/ApplicationResources_ja.properties
index f6ca6b5561..dae9f68d7c 100644
--- a/app/src/main/resources/ApplicationResources_ja.properties
+++ b/app/src/main/resources/ApplicationResources_ja.properties
@@ -96,23 +96,15 @@ categoryForm.image=\u753B\u50CF
# ----------------------------------------------------------- CategoriesForm.jsp
categoriesForm.subtitle={0}\u306E\u30AB\u30C6\u30B4\u30EA\u3092\u7BA1\u7406\u3057\u307E\u3059
-categoriesForm.root=\u30EB\u30FC\u30C8
categoriesForm.rootTitle=\u30AB\u30C6\u30B4\u30EA
categoriesForm.rootPrompt=\u30AB\u30C6\u30B4\u30EA\u306E\u6700\u4E0A\u4F4D\u3067\u3059\u3002\u6700\u4F4E\u3067\u3082\u4E00\u3064\u306E\u30AB\u30C6\u30B4\u30EA\u304C\u5FC5\u8981\u3067\u3059\u3002\u30AB\u30C6\u30B4\u30EA\u306F\u30D6\u30ED\u30B0\u30A8\u30F3\u30C8\u30EA\u3092\u5206\u985E\u3059\u308B\u305F\u3081\u306B\u4F7F\u308F\u308C\u3001\u30D6\u30ED\u30B0\u306E\u8AAD\u8005\u306F\u30AB\u30C6\u30B4\u30EA\u6BCE\u306B\u5206\u304B\u308C\u305F\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9\u306E\u4E2D\u304B\u3089\u597D\u304D\u306A\u3082\u306E\u3092\u8CFC\u8AAD\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002
categoriesForm.addCategory=\u30AB\u30C6\u30B4\u30EA\u306E\u8FFD\u52A0
-categoriesForm.move=\u79FB\u52D5
-categoriesForm.move.confirm=\u9078\u629E\u3057\u305F\u30AB\u30C6\u30B4\u30EA\u3092\u79FB\u52D5\u3057\u307E\u3059\u304B\uFF1F
-categoriesForm.remove=\u524A\u9664
# --------------------------------------------------------- CategoryDeleteOK.jsp
-categoryDeleteOK.removeCategory=\u30AB\u30C6\u30B4\u30EA\u3092\u524A\u9664\u3057\u307E\u3059
categoryDeleteOK.warningCatInUse=\u8B66\u544A\uFF1A\u3053\u306E\u30AB\u30C6\u30B4\u30EA\u306F\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059\u3002
-categoryDeleteOK.youMustMoveEntries=\u3053\u306E\u30AB\u30C6\u30B4\u30EA\u3092\u524A\u9664\u3059\u308B\u306B\u3042\u305F\u308A\u3001\
-\u5C5E\u3059\u308B\u30A8\u30F3\u30C8\u30EA\u5168\u3066\u3092\u4EE5\u4E0B\u3067\u6307\u5B9A\u3059\u308B\u4ED6\u306E\u30AB\u30C6\u30B4\u30EA\u3078\u79FB\u52D5\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
categoryDeleteOK.moveToWhere=\u79FB\u52D5\u5148\u30AB\u30C6\u30B4\u30EA
categoryDeleteOK.noEntriesInCat=\u3053\u306E\u30AB\u30C6\u30B4\u30EA\u306B\u6240\u5C5E\u3059\u308B\u30A8\u30F3\u30C8\u30EA\u306F\u3042\u308A\u307E\u305B\u3093\u3002
-categoryDeleteOK.areYouSure=\u3053\u306E\u30AB\u30C6\u30B4\u30EA\u3092\u524A\u9664\u3057\u307E\u3059\u304B\uFF1F
# ----------------------------------------------------------------- comments.jsp
@@ -1309,7 +1301,6 @@ commonPingTargets.error.disabling=Ping\u30BF\u30FC\u30B2\u30C3\u30C8\u306E\u7121
stylesheetEdit.revert=\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u3092\u5FA9\u5143
weblogEdit.submitForReview=\u30EC\u30D3\u30E5\u30FC\u4F9D\u983C\u3092\u9001\u4FE1
mediaFileView.filesOfType=\u30BF\u30A4\u30D7\u304C {0} \u306E\u30D5\u30A1\u30A4\u30EB
-categoriesForm.imageUrl=\u753B\u50CF\u306EURL
userAdmin.tip.openIdUrl=Open ID\u8B58\u5225\u5B50(URL\u5F62\u5F0F)\u3002
macro.weblog.searchalert=\u691C\u7D22\u30EF\u30FC\u30C9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
tabbedmenu.weblog.mediaFiles=\u30E1\u30C7\u30A3\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB
diff --git a/app/src/main/resources/ApplicationResources_ko.properties b/app/src/main/resources/ApplicationResources_ko.properties
index 3adb9a1a46..adf8b1338c 100644
--- a/app/src/main/resources/ApplicationResources_ko.properties
+++ b/app/src/main/resources/ApplicationResources_ko.properties
@@ -127,7 +127,6 @@ Category.error.imageBad=\uc785\ub825\ud558\uc2e0 \uc774\ubbf8\uc9c0 URL\uc740 \u
# ----------------------------------------------------------- CategoriesForm.jsp
categoriesForm.subtitle=\uc6f9\ub85c\uadf8 {0} \ub0b4\uc758 \uce74\ud14c\uace0\ub9ac \uad00\ub9ac
-categoriesForm.root=\ub8e8\ud2b8
categoriesForm.rootTitle=\uce74\ud14c\uace0\ub9ac
categoriesForm.rootPrompt=\
\ucd5c\uc0c1\uc704 \uc218\uc900\uc758 \uc6f9\ub85c\uadf8 \uce74\ud14c\uace0\ub9ac\ub4e4\uc785\ub2c8\ub2e4. \
@@ -136,20 +135,13 @@ categoriesForm.rootPrompt=\
\ub610\ud55c \ud558\uc704-\uce74\ud14c\uace0\ub9ac\ub97c \uc815\uc758\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ud558\uc9c0\ub9cc, \ub9ce\uc740 \uc2dc\uc2a4\ud15c \ub9e4\ud06c\ub85c\ub4e4\uc740 \
\uc624\uc9c1 \ucd5c\uc0c1\uc704 \uc218\uc900\uc758 \uce74\ud14c\uace0\ub9ac\ub4e4\ub9cc\uc744 \ud45c\uc2dc\ud569\ub2c8\ub2e4.
categoriesForm.addCategory=\uce74\ud14c\uace0\ub9ac \ucd94\uac00
-categoriesForm.move=\uc774\ub3d9
-categoriesForm.move.confirm=\uc120\ud0dd\ub41c \uce74\ud14c\uace0\ub9ac\ub4e4\uc744 \uc774\ub3d9\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
-categoriesForm.remove=\uc0ad\uc81c
# --------------------------------------------------------- CategoryDeleteOK.jsp
-categoryDeleteOK.removeCategory=\uc6f9\ub85c\uadf8 \uce74\ud14c\uace0\ub9ac \uc0ad\uc81c
categoryDeleteOK.warningCatInUse=\uacbd\uace0: \uc774 \uce74\ud14c\uace0\ub9ac\ub294 \uc0ac\uc6a9 \uc911\uc778 \uce74\ud14c\uace0\ub9ac\uc785\ub2c8\ub2e4!
-categoryDeleteOK.youMustMoveEntries=\uc6f9\ub85c\uadf8 \uae30\uc0ac\ub4e4\uc744 \ub2e4\ub978 \uce74\ud14c\uace0\ub9ac\ub85c \uc774\ub3d9\ud574\uc57c \ud569\ub2c8\ub2e4. \
-\ucf64\ubcf4\ubc15\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uae30\uc0ac\ub4e4\uc744 \uc774\ub3d9\ud560 \uce74\ud14c\uace0\ub9ac\ub97c \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624.
categoryDeleteOK.moveToWhere=\ucee8\ud150\ud2b8\ub4e4\uc744 \ub2e4\ub978 \uce74\ud14c\uace0\ub9ac\ub85c \uc774\ub3d9\ud558\uc2ed\uc2dc\uc624.:
categoryDeleteOK.noEntriesInCat=\uc774 \uce74\ud14c\uace0\ub9ac\uc5d0 \uc6f9\ub85c\uadf8 \uae30\uc0ac\ub4e4\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. \
\uc0ad\uc81c\ud558\uc2dc\ub824\uba74 OK\ub97c \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624.
-categoryDeleteOK.areYouSure=\uc774 \uc6f9\ub85c\uadf8 \uce74\ud14c\uace0\ub9ac\ub97c \uc815\ub9d0 \uc0ad\uc81c\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
# ----------------------------------------------------------------- comments.jsp
diff --git a/app/src/main/resources/ApplicationResources_ru.properties b/app/src/main/resources/ApplicationResources_ru.properties
index 78aa084ca6..26fe4e3341 100644
--- a/app/src/main/resources/ApplicationResources_ru.properties
+++ b/app/src/main/resources/ApplicationResources_ru.properties
@@ -99,26 +99,18 @@ categoryForm.image=\u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0430
# ----------------------------------------------------------- CategoriesForm.jsp
categoriesForm.subtitle=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F\u043C\u0438 \u0432 \u0434\u043D\u0435\u0432\u043D\u0438\u043A\u0435 {0}
-categoriesForm.root=root
categoriesForm.rootTitle=\u041A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438
categoriesForm.rootPrompt=\u042D\u0442\u043E \u0433\u043B\u0430\u0432\u043D\u0430\u044F \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F \u0434\u043D\u0435\u0432\u043D\u0438\u043A\u0430. \
\u0412\u044B \u043C\u043E\u0436\u0435\u0442\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438 \u0447\u0442\u043E\u0431\u044B \u0443\u043F\u043E\u0440\u044F\u0434\u043E\u0447\u0438\u0442\u044C \u0437\u0430\u043F\u0438\u0441\u0438, \u0438 \u0412\u0430\u0448\u0438 \u0447\u0438\u0442\u0430\u0442\u0435\u043B\u0438 \u043C\u043E\u0433\u0443\u0442 \
\u043F\u043E\u0434\u043F\u0438\u0441\u0430\u0442\u044C\u0441\u044F \u043D\u0430 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u0443\u044E \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044E \u0412\u0430\u0448\u0435\u0433\u043E \u0434\u043D\u0435\u0432\u043D\u0438\u043A\u0430.
categoriesForm.addCategory=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044E
-categoriesForm.move=\u041F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C
-categoriesForm.remove=\u0423\u0434\u0430\u043B\u0438\u0442\u044C
# --------------------------------------------------------- CategoryDeleteOK.jsp
-categoryDeleteOK.removeCategory=\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438
categoryDeleteOK.warningCatInUse=\u0412\u041D\u0418\u041C\u0410\u041D\u0418\u0415: \u041A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0441\u044F!
-categoryDeleteOK.youMustMoveEntries=\u0412\u044B \u0434\u043E\u043B\u0436\u043D\u044B \u043F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \u0437\u0430\u043F\u0438\u0441\u0438 \u0432 \u0434\u0440\u0443\u0433\u0443\u044E \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044E \
-, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 combo-box \u0434\u043B\u044F \u0432\u044B\u0431\u043E\u0440\u0430 \
-\u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438, \u0432 \u043A\u043E\u0442\u043E\u0440\u0443\u044E \u043F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \u0437\u0430\u043F\u0438\u0441\u0438.
categoryDeleteOK.moveToWhere=\u041F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \u0432 \u0434\u0440\u0443\u0433\u0443\u044E \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044E:
categoryDeleteOK.noEntriesInCat=\u0412 \u044D\u0442\u043E\u0439 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438 \u043D\u0435\u0442 \u0437\u0430\u043F\u0438\u0441\u0435\u0439, \
\u041C\u043E\u0436\u043D\u043E \u0443\u0434\u0430\u043B\u044F\u0442\u044C.
-categoryDeleteOK.areYouSure=\u0412\u044B \u0443\u0432\u0435\u0440\u0435\u043D\u044B \u0447\u0442\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044E?
# ----------------------------------------------------------------- comments.jsp
diff --git a/app/src/main/resources/ApplicationResources_zh_CN.properties b/app/src/main/resources/ApplicationResources_zh_CN.properties
index 03792b4a7a..37844548cc 100644
--- a/app/src/main/resources/ApplicationResources_zh_CN.properties
+++ b/app/src/main/resources/ApplicationResources_zh_CN.properties
@@ -167,7 +167,6 @@ categoriesForm.noresults=\u76EE\u524D\u6CA1\u6709\u5206\u7C7B
# ----------------------------------------------------------- CategoriesForm.jsp
categoriesForm.subtitle=\u7BA1\u7406\u535A\u5BA2 {0} \u7684\u5206\u7C7B
-categoriesForm.root=\u6839
categoriesForm.rootTitle=\u5206\u7C7B
categoriesForm.rootPrompt=\u8FD9\u91CC\u662F\u4F60\u7684\u9876\u7EA7\u5206\u7C7B\uFF0C\u535A\u5BA2\u81F3\u5C11\u8981\u6709\u4E00\u4E2A\u5206\u7C7B\u3002\u5206\u7C7B\u662F\u7528\u6765\u7EC4\u7EC7\u4F60\u7684\u6587\u7AE0\uFF0C\u4F60\u7684\u8BFB\u8005\u4E5F\u53EF\u4EE5\u901A\u8FC7\u9009\u62E9\u67D0\u4E00\u4E2A\u5206\u7C7B\u6765\u8BA2\u9605\u4ED6\u611F\u5174\u8DA3\u7684\u4E13\u9898\u3002
@@ -175,24 +174,17 @@ categoriesForm.rootPrompt=\u8FD9\u91CC\u662F\u4F60\u7684\u9876\u7EA7\u5206\u7C7B
categoriesForm.addCategory=\u6DFB\u52A0\u5206\u7C7B
-categoriesForm.move=\u79FB\u52A8
-categoriesForm.move.confirm=\u786E\u5B9A\u8981\u79FB\u52A8\u9009\u4E2D\u7684\u5206\u7C7B\u5417\uFF1F
-categoriesForm.remove=\u79FB\u9664
-categoriesForm.imageUrl=Image URL
categoryForm.badURL=Image URL is invalid
# --------------------------------------------------------- CategoryDeleteOK.jsp
categoryDeleteOK.title=Delete Category
-categoryDeleteOK.removeCategory=\u6210\u529F\u79FB\u9664\u535A\u5BA2\u5206\u7C7B
categoryDeleteOK.warningCatInUse=\u8B66\u544A\uFF1A\u6B64\u5206\u7C7B\u4ECD\u7136\u5728\u4F7F\u7528\uFF01
-categoryDeleteOK.youMustMoveEntries=\u4F60\u5FC5\u987B\u5148\u628A\u6B64\u5206\u7C7B\u4E2D\u7684\u6587\u7AE0\u8F6C\u79FB\u5230\u53E6\u4E00\u4E2A\u5206\u7C7B\uFF0C\u7528\u9009\u62E9\u6846\u6765\u9009\u4E2D\u8981\u63A5\u6536\u8FD9\u4E9B\u6587\u7AE0\u7684\u5206\u7C7B\u3002
categoryDeleteOK.moveToWhere=\u628A\u8FD9\u4E9B\u5185\u5BB9\u8F6C\u79FB\u5230\u53E6\u4E00\u4E2A\u5206\u7C7B:
categoryDeleteOK.noEntriesInCat=\u6B64\u5206\u7C7B\u4E2D\u5DF2\u7ECF\u6CA1\u6709\u6587\u7AE0\u4E86\uFF0C\u53EF\u4EE5\u5B89\u5168\u5220\u9664\u3002
-categoryDeleteOK.areYouSure=\u4F60\u786E\u5B9A\u8981\u5220\u9664\u8FD9\u4E2A\u6587\u7AE0\u5206\u7C7B\u5417\uFF1F
# ----------------------------------------------------------------- comments.jsp
diff --git a/app/src/main/resources/struts.xml b/app/src/main/resources/struts.xml
index a688e21149..addfdc54a1 100644
--- a/app/src/main/resources/struts.xml
+++ b/app/src/main/resources/struts.xml
@@ -454,7 +454,7 @@
.Categories
- execute,move
+ execute,reorder
<%@ include file="/WEB-INF/jsps/taglibs-struts2.jsp" %>
-
-
-
-
-
-
-
-
+<%-- Categories: one list in display order. Rows are dragged (or moved with the arrow keys on
+ their handle) to reorder; Add, Edit and Delete open dialogs that post with AJAX and reload
+ the page, which then shows a short confirmation. Text the script needs is in data-* attributes. --%>
+
+"
+ data-msg-saved=""
+ data-msg-removed=""
+ data-msg-order-saved=""
+ data-msg-error=""
+ data-msg-name-required=""
+ data-msg-bad-url=""
+ data-title-add=""
+ data-title-edit=""
+ data-title-delete="">
+
+
+
+
+
+
+
+
+
+
+
-<%-- Form is a table of categories each with checkbox --%>
-
+<%-- carries the salt for the reorder post; the category ids are added by the script --%>
+
-
-
-
+
+ <%-- options are filled in by the script, without the category being deleted --%>
+
-
-
-
-
-
-
-
-
+
+
+
-
+
diff --git a/app/src/main/webapp/WEB-INF/jsps/editor/CategoriesSidebar.jsp b/app/src/main/webapp/WEB-INF/jsps/editor/CategoriesSidebar.jsp
deleted file mode 100644
index b8f683968b..0000000000
--- a/app/src/main/webapp/WEB-INF/jsps/editor/CategoriesSidebar.jsp
+++ /dev/null
@@ -1,55 +0,0 @@
-<%--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. The ASF licenses this file to You
- under the Apache License, Version 2.0 (the "License"); you may not
- use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License. For additional information regarding
- copyright in this work, please see the NOTICE file in the top level
- directory of this distribution.
---%>
-<%@ include file="/WEB-INF/jsps/taglibs-struts2.jsp" %>
-
-