diff --git a/CHANGES.md b/CHANGES.md index fa53dc883..3ae8a8473 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,16 @@ - 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. + When media uploads are on, the dialog can choose the category image + from the media library. 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 f841193e7..4f4ee6966 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 93a478a9e..d13c8e1ac 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 q = strategy.getDynamicQuery( + "SELECT e.category.id, COUNT(e) FROM WeblogEntry e WHERE e.website = ?1 " + + "GROUP BY e.category.id", Object[].class); + q.setParameter(1, weblog); + Map counts = new HashMap<>(); + for (Object[] row : q.getResultList()) { + counts.put((String) row[0], ((Number) row[1]).longValue()); + } + return counts; + } /** * @inheritDoc diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Categories.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Categories.java index 1716d1aad..c9f7e6854 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Categories.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/Categories.java @@ -18,62 +18,144 @@ package org.apache.roller.weblogger.ui.struts2.editor; +import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.roller.weblogger.WebloggerException; import org.apache.roller.weblogger.business.WebloggerFactory; import org.apache.roller.weblogger.business.WeblogEntryManager; +import org.apache.roller.weblogger.config.WebloggerRuntimeConfig; import org.apache.roller.weblogger.pojos.WeblogCategory; import org.apache.roller.weblogger.pojos.WeblogPermission; import org.apache.roller.weblogger.ui.struts2.util.UIAction; -import org.apache.struts2.convention.annotation.AllowedMethods; +import org.apache.roller.weblogger.util.cache.CacheManager; +import org.apache.struts2.interceptor.parameter.StrutsParameter; /** - * Manage weblog categories. + * Manage weblog categories: list them with their entry counts, and change + * their order. Adding, editing and removing are done by CategoryEdit and + * CategoryRemove. */ -// TODO: make this work @AllowedMethods({"execute","move"}) public class Categories extends UIAction { - private static Log log = LogFactory.getLog(Categories.class); + private static final Log log = LogFactory.getLog(Categories.class); + + // all categories from the action weblog, in display order + private List allCategories = Collections.emptyList(); - // all categories from the action weblog - private List allCategories; + // number of entries in each category, by category id + private Map entryCounts = Collections.emptyMap(); - public Categories() { - this.actionName = "categories"; - this.desiredMenu = "editor"; - this.pageTitle = "categoriesForm.rootTitle"; - } + // category ids in their new order, posted by reorder + private List categoryIds = new ArrayList<>(); - @Override - public List requiredWeblogPermissionActions() { - return Collections.singletonList(WeblogPermission.POST); - } + public Categories() { + this.actionName = "categories"; + this.desiredMenu = "editor"; + this.pageTitle = "categoriesForm.rootTitle"; + } - @Override - public String execute() { - try { + @Override + public List requiredWeblogPermissionActions() { + return Collections.singletonList(WeblogPermission.POST); + } + + @Override + public String execute() { + try { WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); - allCategories = wmgr.getWeblogCategories(getActionWeblog()); - } catch (WebloggerException ex) { - log.error("Error building categories list", ex); - addError("Error building categories list"); - } - - return LIST; - } - - public String move() { - return execute(); - } - - public List getAllCategories() { - return allCategories; - } - - public void setAllCategories(List allCategories) { - this.allCategories = allCategories; - } + allCategories = wmgr.getWeblogCategories(getActionWeblog()); + entryCounts = wmgr.getWeblogCategoryEntryCounts(getActionWeblog()); + } catch (WebloggerException ex) { + log.error("Error building categories list", ex); + addError("generic.error.check.logs"); + } + return LIST; + } + + /** + * Save a new display order. The posted ids must name every category of + * the weblog exactly once. + */ + public String reorder() { + try { + WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager(); + List current = wmgr.getWeblogCategories(getActionWeblog()); + + Map byId = new HashMap<>(); + for (WeblogCategory category : current) { + byId.put(category.getId(), category); + } + if (categoryIds.size() != current.size() + || !byId.keySet().equals(new HashSet<>(categoryIds))) { + addError("categoriesForm.error.reorder"); + return execute(); + } + + for (int position = 0; position < categoryIds.size(); position++) { + WeblogCategory category = byId.get(categoryIds.get(position)); + if (category.getPosition() != position) { + category.setPosition(position); + wmgr.saveWeblogCategory(category); + } + } + // the weblog's own list is sorted only when it is loaded, and themes + // and new categories read it, so put it in the new order too + getActionWeblog().getWeblogCategories() + .sort(Comparator.comparingInt(WeblogCategory::getPosition)); + WebloggerFactory.getWeblogger().flush(); + CacheManager.invalidate(getActionWeblog()); + addMessage("categoriesForm.orderSaved"); + } catch (WebloggerException ex) { + log.error("Error saving category order", ex); + addError("generic.error.check.logs"); + } + return execute(); + } + + public List getAllCategories() { + return allCategories; + } + + /** Number of entries in the category, in any status. */ + public long getEntryCount(String categoryId) { + Long count = entryCounts.get(categoryId); + return count == null ? 0 : count; + } + + /** + * True if removing the category means moving something to another one: + * its entries, or its role as the blogging clients' default category. + */ + public boolean isInUse(String categoryId) { + WeblogCategory clientDefault = getActionWeblog().getBloggerCategory(); + return getEntryCount(categoryId) > 0 + || (clientDefault != null && categoryId.equals(clientDefault.getId())); + } + + /** The media library filter that offers only images, for the category image chooser. */ + public String getImageChooserType() { + return MediaFileImageChooser.IMAGES_ONLY; + } + + /** True when media uploads are on, so an image can be chosen from the media library. */ + public boolean isMediaLibraryEnabled() { + return WebloggerRuntimeConfig.getBooleanProperty("uploads.enabled"); + } + + public List getCategoryIds() { + return categoryIds; + } + + @StrutsParameter + public void setCategoryIds(List categoryIds) { + this.categoryIds = categoryIds == null ? new ArrayList<>() : categoryIds; + } } diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageChooser.java b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageChooser.java index e0ab18b12..d9b699c1e 100644 --- a/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageChooser.java +++ b/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileImageChooser.java @@ -51,6 +51,9 @@ public class MediaFileImageChooser extends MediaFileBase { private static Log log = LogFactory.getLog(MediaFileImageChooser.class); + /** The search bean's type for images; the categories page opens the chooser with it. */ + static final String IMAGES_ONLY = "mediaFileView.image"; + private String directoryId; private String directoryName; @@ -136,6 +139,11 @@ public String execute() { return SUCCESS; } + /** True when the chooser lists only images, as when choosing a category image. */ + public boolean isImagesOnly() { + return IMAGES_ONLY.equals(bean.getType()); + } + public MediaFilePager getPager() { return pager; } diff --git a/app/src/main/resources/ApplicationResources.properties b/app/src/main/resources/ApplicationResources.properties index 888f3f87f..5ee815e50 100644 --- a/app/src/main/resources/ApplicationResources.properties +++ b/app/src/main/resources/ApplicationResources.properties @@ -165,7 +165,7 @@ categoryForm.edit.subtitle=Editing category categoryForm.add.title=Add Category categoryForm.add.subtitle=Adding category categoryForm.image=Image URL -categoryForm.created=Category created +categoryForm.created=Category "{0}" added categoryForm.changesSaved=Category "{0}" updated categoryForm.error.duplicateName=Category name already in use categoryForm.removed=Category "{0}" deleted @@ -183,32 +183,40 @@ categoriesForm.noresults=There are currently no categories # ----------------------------------------------------------- CategoriesForm.jsp categoriesForm.subtitle=Manage categories in weblog {0} -categoriesForm.root=root categoriesForm.rootTitle=Categories -categoriesForm.rootPrompt=\ -These are your top-level weblog categories. Roller requires at least one \ -category to be defined. \ -Categories are used to organize your weblog entries and your readers can \ -choose to subscribe to separate feeds for each of your categories. +categoriesForm.rootPrompt=Categories organize your entries, and readers can \ +follow a feed for each one. Drag a category by its handle, or focus the handle \ +and use the arrow keys, or on a touch screen use the up and down buttons, \ +to change the order your theme shows them in. A weblog needs at least one category. +categoriesForm.entryCount={0,choice,0#No entries|1#1 entry|1<{0,number,integer} entries} +categoriesForm.viewEntries=View the entries in {0} +categoriesForm.moveHandle=Move {0} +categoriesForm.moveUp=Move {0} up +categoriesForm.moveDown=Move {0} down +categoriesForm.orderSaved=Category order saved +categoriesForm.error.reorder=The categories changed while you were reordering them. \ +Reload the page and try again. +categoriesForm.lastCategory=A weblog needs at least one category. +categoryForm.imageHelp=Optional. Themes that show category images use this picture. +categoryForm.imageHelpMedia=Optional. Enter a URL or choose an image from the media library. Themes that show category images use this picture. +categoryForm.chooseImage=Choose +categoryForm.chooseImage.title=Choose a category image +categoryForm.chooseImage.back=Back categoriesForm.addCategory=Add Category -categoriesForm.move=Move -categoriesForm.move.confirm=Move selected categories? -categoriesForm.remove=Remove -categoriesForm.imageUrl=Image URL categoryForm.badURL=Image URL is invalid # --------------------------------------------------------- CategoryDeleteOK.jsp categoryDeleteOK.title=Delete Category -categoryDeleteOK.removeCategory=Delete Weblog Category -categoryDeleteOK.warningCatInUse=WARNING: This category is in use! -categoryDeleteOK.youMustMoveEntries=You must move the weblog entries in the \ -category to another category, use the combo-box to select which category \ -should receive the entries.

-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 @@ -772,6 +780,9 @@ maintenance.message.reset=Successfully reset the hit count of your Roller weblog mediaFileImageChooser.subtitle=Choose a Media File to be inserted mediaFileImageChooser.pageTip=Choose an image to insert it as a thumbnail, or a file to insert a link to it. An image gets its description as alt text. mediaFileImageChooser.insert=Insert {0} +mediaFileImageChooser.choose=Choose {0} +mediaFileImageChooser.imagePageTip=Click an image to choose it. +mediaFileImageChooser.noImages=This folder has no images. # -- Media File Add diff --git a/app/src/main/resources/ApplicationResources_de.properties b/app/src/main/resources/ApplicationResources_de.properties index 35d9ca673..90d3eab50 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 e8e795526..604cb3458 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 8c7f4c362..380c522e8 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 f6ca6b556..dae9f68d7 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 3adb9a1a4..adf8b1338 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 78aa084ca..26fe4e334 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 03792b4a7..37844548c 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 a688e2114..addfdc54a 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, or the up and down buttons on touch screens) 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 --%> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - " - data-category-name="" - data-category-desc="" - data-category-image=""> - - - - - - - - - - " - data-category-name="" - data-category-in-use=""> - - - - -
-
+ +

+
+ +
    + + + + + +
  • "> + + + + <%-- shown instead of the handle on touch screens, where it cannot be dragged --%> + + + + -<%-- ============================================================= --%> -<%-- add/edit category modal --%> + + + -
  • +
    +
+ +
+ +
+
+
+
+ +
+
+
-