Converted planet config, subscriptions and groups pages to Bootstrap. Code complete!
diff --git a/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetConfig.java b/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetConfig.java
index afa97cf..d110e69 100644
--- a/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetConfig.java
+++ b/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetConfig.java
@@ -18,9 +18,6 @@
 
 package org.apache.roller.weblogger.planet.ui;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.roller.RollerException;
@@ -33,9 +30,12 @@
 import org.apache.roller.weblogger.config.runtime.RuntimeConfigDefs;
 import org.apache.roller.weblogger.pojos.GlobalPermission;
 import org.apache.roller.weblogger.pojos.RuntimeConfigProperty;
-import org.apache.struts2.convention.annotation.AllowedMethods;
 import org.apache.struts2.interceptor.ParameterAware;
 
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
 
 /**
  * Planet Config Action.
diff --git a/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetSubscriptions.java b/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroupSubs.java
similarity index 61%
rename from app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetSubscriptions.java
rename to app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroupSubs.java
index 899eaa2..4e78ff0 100644
--- a/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetSubscriptions.java
+++ b/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroupSubs.java
@@ -16,77 +16,86 @@
 
 package org.apache.roller.weblogger.planet.ui;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.roller.RollerException;
 import org.apache.roller.planet.business.PlanetManager;
 import org.apache.roller.planet.business.fetcher.FeedFetcher;
+import org.apache.roller.planet.business.fetcher.FetcherException;
 import org.apache.roller.planet.pojos.PlanetGroup;
 import org.apache.roller.planet.pojos.Subscription;
 import org.apache.roller.weblogger.business.WebloggerFactory;
 import org.apache.roller.weblogger.pojos.GlobalPermission;
-import org.apache.struts2.convention.annotation.AllowedMethods;
+import org.apache.struts2.interceptor.ServletRequestAware;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
 
 
 /**
  * Manage planet group subscriptions, default group is "all".
  */
 // TODO: make this work @AllowedMethods({"execute","save","delete"})
-public class PlanetSubscriptions extends PlanetUIAction {
-    
-    private static final Log LOGGER = LogFactory.getLog(PlanetSubscriptions.class);
-    
-    // id of the group we are working in
-    private String groupHandle = null;
-    
+public class PlanetGroupSubs extends PlanetUIAction implements ServletRequestAware  {
+
+    private static final Log log = LogFactory.getLog(PlanetGroupSubs.class);
+
     // the planet group we are working in
     private PlanetGroup group = null;
-    
+
     // the subscription to deal with
     private String subUrl = null;
-    
-    
-    public PlanetSubscriptions() {
-        this.actionName = "planetSubscriptions";
+
+    private boolean createNew = false;
+
+    public PlanetGroupSubs() {
+        this.actionName = "planetGroupSubs";
         this.desiredMenu = "admin";
-        this.pageTitle = "planetSubscriptions.title";
     }
-    
-    
+
+
     @Override
     public List<String> requiredGlobalPermissionActions() {
         return Collections.singletonList(GlobalPermission.ADMIN);
     }
-    
+
     @Override
     public boolean isWeblogRequired() {
         return false;
     }
-    
-    
+
+
     @Override
-    public void myPrepare() {
-        
+    public void setServletRequest(HttpServletRequest request) {
+
         PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();
-        
-        // lookup group we are operating on, if none specified then use default
-        if (getGroupHandle() == null) {
-            setGroupHandle("all");
-        }
-        
+        String action = null;
         try {
-            setGroup(pmgr.getGroup(getPlanet(), getGroupHandle()));
-        } catch (RollerException ex) {
-            LOGGER.error("Error looking up planet group - " + getGroupHandle(), ex);
+            if (request.getParameter("createNew") != null) {
+                createNew = true;
+
+            } else if (request.getParameter("bean.id") != null) {
+                String groupId = request.getParameter("bean.id");
+                action = "looking up planet group by id: " + groupId;
+                setGroup(pmgr.getGroupById(groupId));
+
+            } else if (request.getParameter("groupHandle") != null) {
+                String groupHandle = request.getParameter("groupHandle");
+                action = "looking up planet group by handle: " + groupHandle;
+                setGroup(pmgr.getGroup(getPlanet(), groupHandle));
+
+            } else {
+                action = "getting default group";
+                setGroup(pmgr.getGroup(getPlanet(), "all"));
+            }
+
+        } catch (Exception ex) {
+            log.error("Error " + action, ex);
         }
     }
-    
-    
+
+
     /**
      * Populate page model and forward to subscription page
      */
@@ -94,22 +103,22 @@
         return LIST;
     }
 
-    
-    /** 
-     * Save subscription, add to current group 
+
+    /**
+     * Save subscription, add to current group
      */
     public String save() {
-        
+
         myValidate();
-        
-        if(!hasActionErrors()) {
+
+        if (!hasActionErrors()) {
             try {
                 PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();
 
                 // check if this subscription already exists before adding it
                 Subscription sub = pmgr.getSubscription(getSubUrl());
-                if(sub == null) {
-                    LOGGER.debug("Adding New Subscription - " + getSubUrl());
+                if (sub == null) {
+                    log.debug("Adding New Subscription - " + getSubUrl());
 
                     // sub doesn't exist yet, so we need to fetch it
                     FeedFetcher fetcher = WebloggerFactory.getWeblogger().getFeedFetcher();
@@ -117,19 +126,16 @@
 
                     // save new sub
                     pmgr.saveSubscription(sub);
-                } else {
-                    LOGGER.debug("Adding Existing Subscription - " + getSubUrl());
 
+                } else {
                     // Subscription already exists
-                    addMessage("planetSubscription.foundExisting", sub.getTitle());
+                    log.debug("Adding Existing Subscription - " + getSubUrl());
                 }
 
                 // add the sub to the group
                 group.getSubscriptions().add(sub);
                 sub.getGroups().add(group);
                 pmgr.saveGroup(group);
-
-                // flush changes
                 WebloggerFactory.getWeblogger().flush();
 
                 // clear field after success
@@ -137,22 +143,25 @@
 
                 addMessage("planetSubscription.success.saved");
 
+            } catch (FetcherException ex) {
+                addError("planetGroupSubs.error.fetchingFeed", ex.getRootCauseMessage());
+
             } catch (RollerException ex) {
-                LOGGER.error("Unexpected error saving subscription", ex);
-                addError("planetSubscriptions.error.duringSave", ex.getRootCauseMessage());
+                log.error("Unexpected error saving subscription", ex);
+                addError("planetGroupSubs.error.duringSave", ex.getRootCauseMessage());
             }
         }
-        
+
         return LIST;
     }
 
-    
-    /** 
-     * Delete subscription, reset form  
+
+    /**
+     * Delete subscription, reset form
      */
     public String delete() {
-        
-        if(getSubUrl() != null) {
+
+        if (getSubUrl() != null) {
             try {
 
                 PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();
@@ -170,54 +179,45 @@
                 addMessage("planetSubscription.success.deleted");
 
             } catch (RollerException ex) {
-                LOGGER.error("Error removing planet subscription", ex);
+                log.error("Error removing planet subscription", ex);
                 addError("planetSubscription.error.deleting");
             }
         }
 
         return LIST;
     }
-    
-    
-    /** 
+
+
+    /**
      * Validate posted subscription
      */
     private void myValidate() {
-        
-        if(StringUtils.isEmpty(getSubUrl())) {
+
+        if (StringUtils.isEmpty(getSubUrl())) {
             addError("planetSubscription.error.feedUrl");
         }
     }
-    
-    
+
+
     public List<Subscription> getSubscriptions() {
-        
+
         List<Subscription> subs = Collections.emptyList();
-        if(getGroup() != null) {
+        if (getGroup() != null) {
             Set<Subscription> subsSet = getGroup().getSubscriptions();
-            
+
             // iterate over list and build display list
             subs = new ArrayList<Subscription>();
             for (Subscription sub : subsSet) {
                 // only include external subs for display
-                if(!sub.getFeedURL().startsWith("weblogger:")) {
+                if (!sub.getFeedURL().startsWith("weblogger:")) {
                     subs.add(sub);
                 }
             }
         }
-        
+
         return subs;
     }
-    
-    
-    public String getGroupHandle() {
-        return groupHandle;
-    }
 
-    public void setGroupHandle(String groupHandle) {
-        this.groupHandle = groupHandle;
-    }
-    
     public PlanetGroup getGroup() {
         return group;
     }
@@ -232,5 +232,36 @@
 
     public void setSubUrl(String subUrl) {
         this.subUrl = subUrl;
-    }    
+    }
+
+    public boolean getCreateNew() {
+        return createNew;
+    }
+
+    public void setCreateNew(boolean createNew) {
+        this.createNew = createNew;
+    }
+
+    public String getGroupHandle() {
+        if (group != null) {
+            return group.getHandle();
+        }
+        return null;
+    }
+
+    @Override
+    public String getPageTitle() {
+        if (pageTitle == null) {
+            if (createNew) {
+                pageTitle = getText("planetGroupSubs.custom.title.new");
+            } else if (getGroup().getHandle().equals("all")) {
+                pageTitle = getText("planetGroupSubs.default.title");
+            } else {
+                pageTitle = getText("planetGroupSubs.custom.title", new String[] { getGroup().getHandle() } );
+            }
+        }
+        return pageTitle;
+    }
 }
+
+
diff --git a/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroups.java b/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroups.java
index f65c480..700d521 100644
--- a/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroups.java
+++ b/app/src/main/java/org/apache/roller/weblogger/planet/ui/PlanetGroups.java
@@ -18,6 +18,8 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -27,61 +29,76 @@
 import org.apache.roller.weblogger.business.Weblogger;
 import org.apache.roller.weblogger.business.WebloggerFactory;
 import org.apache.struts2.convention.annotation.AllowedMethods;
+import org.apache.struts2.interceptor.ServletRequestAware;
+
+import javax.servlet.http.HttpServletRequest;
 
 
 /**
  * Manage planet groups.
  */
 // TODO: make this work @AllowedMethods({"execute","save","delete"})
-public class PlanetGroups extends PlanetUIAction {
-    
+public class PlanetGroups extends PlanetUIAction implements ServletRequestAware  {
+
     private static Log log = LogFactory.getLog(PlanetGroups.class);
-    
+
     // a bean to manage submitted data
     private PlanetGroupsBean bean = new PlanetGroupsBean();
-    
+
     // the planet group we are working on
     private PlanetGroup group = null;
-    
-    
+
     public PlanetGroups() {
         this.actionName = "planetGroups";
         this.desiredMenu = "admin";
         this.pageTitle = "planetGroups.pagetitle";
     }
-    
-    
+
+
     @Override
     public boolean isWeblogRequired() {
         return false;
     }
-    
-    
+
+    @Override
+    public void setServletRequest(HttpServletRequest request) {
+        if (request.getParameter("groupHandle") != null) {
+            bean.setHandle(request.getParameter("groupHandle"));
+        }
+    }
+
     @Override
     public void myPrepare() {
-        
-        if(getPlanet() != null && getBean().getId() != null) {
+
+        if (getBean().getId() != null) {
             try {
                 PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();
                 setGroup(pmgr.getGroupById(getBean().getId()));
-            } catch(Exception ex) {
-                log.error("Error looking up planet group - " + getBean().getId(), ex);
+            } catch (Exception ex) {
+                log.error("Error looking up planet group by id: " + getBean().getId(), ex);
+            }
+
+        } else if (bean.getHandle() != null) {
+            try {
+                PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();
+                setGroup(pmgr.getGroup(getPlanet(), bean.getHandle()));
+            } catch (Exception ex) {
+                log.error("Error looking up planet group by handle: " + bean.getHandle(), ex);
             }
         }
     }
 
-    
-    /** 
+    /**
      * Show planet groups page.
      */
     public String execute() {
-        
+
         // if we are loading an existing group then populate the bean
-        if(getGroup() != null) {
+        if (getGroup() != null) {
             getBean().copyFrom(getGroup());
         }
-        
-        return LIST;
+
+        return "groups_list";
     }
 
 
@@ -124,70 +141,68 @@
             }
         }
 
-        return LIST;
+        return "subscriptions_list";
     }
 
-    
-    /** 
-     * Delete group, reset form  
+
+    /**
+     * Delete group, reset form
      */
     public String delete() {
-        
-        if(getGroup() != null) {
+
+        if (getGroup() != null) {
             try {
                 PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager();
                 pmgr.deleteGroup(getGroup());
                 WebloggerFactory.getWeblogger().flush();
-                
+
                 addMessage("planetSubscription.success.deleted");
 
                 setGroup(null);
 
-            } catch(Exception ex) {
-                log.error("Error deleting planet group - "+getBean().getId());
+            } catch (Exception ex) {
+                log.error("Error deleting planet group - " + getBean().getId());
                 addError("Error deleting planet group");
             }
         }
-        
-        return LIST;
+
+        return "groups_list";
     }
-    
-    
-    /** 
-     * Validate posted group 
+
+
+    /**
+     * Validate posted group
      */
     private void myValidate() {
-        
-        if(StringUtils.isEmpty(getBean().getTitle())) {
+
+        if (StringUtils.isEmpty(getBean().getTitle())) {
             addError("planetGroups.error.title");
         }
-        
-        if(StringUtils.isEmpty(getBean().getHandle())) {
+
+        if (StringUtils.isEmpty(getBean().getHandle())) {
             addError("planetGroups.error.handle");
         }
-        
-        if(getBean().getHandle() != null && "all".equals(getBean().getHandle())) {
+
+        if (getBean().getHandle() != null && "all".equals(getBean().getHandle())) {
             addError("planetGroups.error.nameReserved");
         }
-        
+
         // make sure duplicate group handles are prevented
     }
-    
-    
+
+
     public List<PlanetGroup> getGroups() {
         List<PlanetGroup> displayGroups = new ArrayList<PlanetGroup>();
-        
+
         for (PlanetGroup planetGroup : getPlanet().getGroups()) {
-            // The "all" group is considered a special group and cannot be
-            // managed independently
+            // The "all" group is considered a special group and cannot be managed independently
             if (!planetGroup.getHandle().equals("all")) {
                 displayGroups.add(planetGroup);
             }
         }
         return displayGroups;
     }
-    
-    
+
     public PlanetGroupsBean getBean() {
         return bean;
     }
@@ -195,7 +210,7 @@
     public void setBean(PlanetGroupsBean bean) {
         this.bean = bean;
     }
-    
+
     public PlanetGroup getGroup() {
         return group;
     }
@@ -203,5 +218,6 @@
     public void setGroup(PlanetGroup group) {
         this.group = group;
     }
-    
+
+
 }
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/util/menu/Menu.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/util/menu/Menu.java
index 8e9804e..dfa330d 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/core/util/menu/Menu.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/util/menu/Menu.java
@@ -27,10 +27,10 @@
  */
 public class Menu {
     
-    private List<MenuTab> tabs = new ArrayList<MenuTab>();
+    private List<MenuTab> tabs = new ArrayList<>();
     
     
-    public void addTab(MenuTab tab) {
+    void addTab(MenuTab tab) {
         this.tabs.add(tab);
     }
     
diff --git a/app/src/main/java/org/apache/roller/weblogger/ui/core/util/menu/MenuHelper.java b/app/src/main/java/org/apache/roller/weblogger/ui/core/util/menu/MenuHelper.java
index fff06dd..e416bf5 100644
--- a/app/src/main/java/org/apache/roller/weblogger/ui/core/util/menu/MenuHelper.java
+++ b/app/src/main/java/org/apache/roller/weblogger/ui/core/util/menu/MenuHelper.java
@@ -67,17 +67,13 @@
 
             // parse menus and cache so we can efficiently reuse them
             String menu = "editor";
-            ParsedMenu editorMenu = unmarshall(
-                    menu,
-                    MenuHelper.class
-                            .getResourceAsStream("/org/apache/roller/weblogger/ui/struts2/editor/editor-menu.xml"));
+            ParsedMenu editorMenu = unmarshall( menu,
+                MenuHelper.class.getResourceAsStream("/org/apache/roller/weblogger/ui/struts2/editor/editor-menu.xml"));
             menus.put(menu, editorMenu);
 
             menu = "admin";
-            ParsedMenu adminMenu = unmarshall(
-                    menu,
-                    MenuHelper.class
-                            .getResourceAsStream("/org/apache/roller/weblogger/ui/struts2/admin/admin-menu.xml"));
+            ParsedMenu adminMenu = unmarshall( menu,
+                MenuHelper.class.getResourceAsStream("/org/apache/roller/weblogger/ui/struts2/admin/admin-menu.xml"));
             menus.put(menu, adminMenu);
 
         } catch (Exception ex) {
@@ -112,8 +108,7 @@
         ParsedMenu menuConfig = menus.get(menuId);
         if (menuConfig != null) {
             try {
-                menu = buildMenu(menuId, menuConfig, currentAction, user,
-                        weblog);
+                menu = buildMenu(menuId, menuConfig, currentAction, user, weblog);
             } catch (WebloggerException ex) {
                 log.error("ERROR: fethcing user roles", ex);
             }
@@ -167,16 +162,14 @@
             if (configTab.getEnabledProperty() != null) {
                 includeTab = getBooleanProperty(configTab.getEnabledProperty());
             } else if (configTab.getDisabledProperty() != null) {
-                includeTab = !getBooleanProperty(configTab
-                        .getDisabledProperty());
+                includeTab = !getBooleanProperty(configTab.getDisabledProperty());
             }
 
             // user roles check
             if (includeTab && configTab.getGlobalPermissionActions() != null
                     && !configTab.getGlobalPermissionActions().isEmpty()) {
                 try {
-                    GlobalPermission perm = new GlobalPermission(
-                            configTab.getGlobalPermissionActions());
+                    GlobalPermission perm = new GlobalPermission( configTab.getGlobalPermissionActions());
                     if (!umgr.checkPermission(perm, user)) {
                         includeTab = false;
                     }
@@ -189,8 +182,7 @@
             // weblog permissions check
             if (includeTab && configTab.getWeblogPermissionActions() != null
                     && !configTab.getWeblogPermissionActions().isEmpty()) {
-                WeblogPermission perm = new WeblogPermission(weblog,
-                        configTab.getWeblogPermissionActions());
+                WeblogPermission perm = new WeblogPermission(weblog, configTab.getWeblogPermissionActions());
                 includeTab = umgr.checkPermission(perm, user);
             }
 
@@ -211,18 +203,15 @@
                     boolean includeItem = true;
 
                     if (configTabItem.getEnabledProperty() != null) {
-                        includeItem = getBooleanProperty(configTabItem
-                                .getEnabledProperty());
+                        includeItem = getBooleanProperty(configTabItem.getEnabledProperty());
                     } else if (configTabItem.getDisabledProperty() != null) {
-                        includeItem = !getBooleanProperty(configTabItem
-                                .getDisabledProperty());
+                        includeItem = !getBooleanProperty(configTabItem.getDisabledProperty());
                     }
 
                     // user roles check
                     if (includeItem
                             && configTabItem.getGlobalPermissionActions() != null
-                            && !configTabItem.getGlobalPermissionActions()
-                                    .isEmpty()) {
+                            && !configTabItem.getGlobalPermissionActions() .isEmpty()) {
                         GlobalPermission perm = new GlobalPermission(
                                 configTabItem.getGlobalPermissionActions());
                         if (!umgr.checkPermission(perm, user)) {
@@ -233,10 +222,8 @@
                     // weblog permissions check
                     if (includeItem
                             && configTabItem.getWeblogPermissionActions() != null
-                            && !configTabItem.getWeblogPermissionActions()
-                                    .isEmpty()) {
-                        WeblogPermission perm = new WeblogPermission(weblog,
-                                configTabItem.getWeblogPermissionActions());
+                            && !configTabItem.getWeblogPermissionActions().isEmpty()) {
+                        WeblogPermission perm = new WeblogPermission(weblog, configTabItem.getWeblogPermissionActions());
                         includeItem = umgr.checkPermission(perm, user);
                     }
 
@@ -461,8 +448,7 @@
                     element.getAttributeValue("globalPerms"), ","));
         }
         tabItem.setEnabledProperty(element.getAttributeValue("enabledProperty"));
-        tabItem.setDisabledProperty(element
-                .getAttributeValue("disabledProperty"));
+        tabItem.setDisabledProperty(element.getAttributeValue("disabledProperty"));
 
         return tabItem;
     }
diff --git a/app/src/main/resources/ApplicationResources.properties b/app/src/main/resources/ApplicationResources.properties
index 7e6d134..e2b08b9 100644
--- a/app/src/main/resources/ApplicationResources.properties
+++ b/app/src/main/resources/ApplicationResources.properties
@@ -30,6 +30,7 @@
 generic.no=No
 generic.name=Name
 generic.description=Description
+generic.action=Action
 generic.save=Save
 generic.rename=Rename
 generic.edit=Edit
@@ -173,7 +174,7 @@
 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 newsfeeds for each of your categories.
+choose to subscribe to separate feeds for each of your categories.
 categoriesForm.addCategory=Add Category
 categoriesForm.move=Move
 categoriesForm.move.confirm=Move selected categories?
@@ -341,8 +342,8 @@
 
 configForm.weblogSettings=Weblog Rendering Settings
 configForm.pageMaxEntries=Max number of entries to allow per page
-configForm.newsfeedMaxEntries=Number of entries to provide in newsfeeds
-configForm.styledFeeds=Display styled newsfeeds for browsers
+configForm.newsfeedMaxEntries=Number of entries to provide in feeds
+configForm.styledFeeds=Display styled feeds for browsers
 
 configForm.commentSettings=Comment and Trackback Settings
 configForm.enableComments=Allow weblog comments?
@@ -379,10 +380,10 @@
 
 createWebsite.tip.name=The name is the title of your weblog, it will be \
 displayed at the top of your weblog page, and in the title field of your \
-weblog''s newsfeed. This field should not include HTML.
+weblog''s feed. This field should not include HTML.
 createWebsite.tip.description=The description of your weblog may be displayed \
 at the top of your weblog (depending on the theme you choose), and it will be \
-used in description or subtitle field of your newsfeed. This field should not \
+used in description or subtitle field of your feed. This field should not \
 include HTML.
 createWebsite.tip.handle=The handle is a short one-word name for your \
 weblog. It will be used in your URL, so please limit it to simple ASCII \
@@ -1115,18 +1116,16 @@
 pingTarget.unknownHost=The hostname in this URL doesn''t seem to exist.
 pingTarget.notFound=Ping target id {0} was not found
 
-# --------------------------------------------------------------- Planet Roller
+# --------------------------------------------------------------- Planet Roller: config
 
 planetConfig.title=Planet Configuration
-planetConfig.subtitle=Configure Roller''s built-in newsfeed aggregator.
-planetConfig.prompt=Set the title, description, email address and site URL \
-to be included in newsfeeds produced by the aggregator. You can also setup a \
-proxy if one is required required by your network.
+planetConfig.subtitle=Configure Roller\'s built-in RSS/Atom feed aggregator.
+planetConfig.prompt=Roller's Planet feature gives you a way to aggregate all of the weblogs on your site along with feeds from other sites. On this page you can set title, description and email addresses that are to be displayed in the RSS or Atom feeds for your aggregation, and to be used in weblog templates that display your site. You can also configure a proxy if you Roller site requires one.
 
 ConfigForm.siteSettings=Planet Settings
-ConfigForm.title=Planet title\t
-ConfigForm.description=Planet description\t\t
-ConfigForm.adminName=Name of Planet administrator \t\t
+ConfigForm.title=Planet title
+ConfigForm.description=Planet description
+ConfigForm.adminName=Name of Planet administrator
 ConfigForm.adminEmail=Email of Planet administrator
 ConfigForm.absoluteUrl=Absolute URL to Planet page
 ConfigForm.proxyHost=Proxy host for feed fetcher
@@ -1140,56 +1139,63 @@
 ConfigForm.invalidFloatProperty=Property {0} must be a float: {1}
 ConfigForm.invalidProperty=Property {0} is null
 
-# ----------------------------------------------------- PlanetSubscriptions.jsp
+# ----------------------------------------------------- Planet Roller: group subscriptions
 
-planetSubscriptions.title=Subscriptions
+planetGroupSubs.default.title=Default Planet Group Subscriptions
+planetGroupSubs.default.subtitle=Manage feed subscriptions for Roller's Default Planet Group
+planetGroupSubs.default.desc=By default, Roller's Planet feature includes all weblogs on this Roller site in the aggregation. On this page you can add RSS and Atom feeds from other sites to this aggregation.
 
-planetSubscriptions.subtitle.add=\
-Manage newsfeed subscriptions in group [<b>{0}</b>].
-planetSubscriptions.prompt.add=To add a new subscription simply enter a \
-newsfeed URL then click the Save button.
+planetGroupSubs.custom.title=Custom Planet Group {0}
+planetGroupSubs.custom.title.new=New Custom Planet Group
+planetGroupSubs.custom.subtitle=Manage feed subscriptions for Custom Planet Group {0}
+planetGroupSubs.custom.desc=This is a Custom Planet Group. Once you have added one or more RSS/Atom feeds here Roller will create an aggregated feed that containing entries from all of the feeds you add. You can display that aggregated feed in a blog template or access it via URL.
 
-planetSubscriptions.subtitle.addMain=\
-Managing the main list of newsfeed subscriptions.
-planetSubscriptions.prompt.addMain=Use this page to add \
-subscriptions to the list of newsfeeds that are to be included on the main \
-Planet aggregator page. To add a new subscription simply enter a \
-newsfeed URL then click the Save button.
+planetGroupSubs.addFeed=Add a new RSS/Atom feed subscription
+planetGroupSubs.creatingNewGroup=Before you can add subscriptions you must set a name and handle for your new Custom Planet Feed.
+planetGroupSubs.editingExistingGroup=You can edit the name and handle for the group, but be aware that changing the handle will change the URL of the Planet Group.
 
-planetSubscriptions.existingTitle=Existing Subscriptions
-planetSubscriptions.column.title=Title
-planetSubscriptions.column.feedUrl=Feed URL
-planetSubscription.feedUrl=Newsfeed URL
+planetGroupSubs.noneDefinedCustom=No feed subscriptions exist for this Custom Planet Group
+planetGroupSubs.noneDefinedDefault=No additional feeds have been added to the Default Planet Group
+
+planetGroupSubs.properties=Properties
+planetGroupSubs.subscriptions=Subscriptions
+planetGroupSubs.column.title=Title
+planetGroupSubs.column.feedUrl=Feed URL
+planetSubscription.feedUrl=Feed URL
 planetSubscription.success.deleted=Subscription successfully deleted
 planetSubscription.foundExisting=Found existing subscription [{0}], adding it instead
 planetSubscription.success.saved=Saved subscription
-planetSubscription.error=Must specify newfeed URL
-planetSubscription.error.feedUrl=Newsfeed URL is required
-planetSubscriptions.error.duringSave=Duplicate subscription? - {0}
+planetSubscription.error=Must specify feed URL
+planetSubscription.error.feedUrl=Feed URL is required
+planetGroupSubs.error.duringSave=Unexpected error saving subscription: {0}
+planetGroupSubs.error.fetchingFeed=Error fetching subscription: {0}
 planetSubscription.error.deleting=Error deleting object
 
-# ------------------------------------------------------------ PlanetGroups.jsp
+planetGroupSubs.delete.confirm=Are you sure you want to delete this subscription?
+
+# ------------------------------------------------------------ Planet Roller: groups
 
 planetGroups.pagetitle=Custom Planet Groups
-planetGroups.subtitle=Add custom aggregation groups, each available as a newsfeed.
+planetGroups.subtitle=Manage Custom Planet Groups, each available for use in weblog templates or as a feed.
 
-planetGroups.prompt.add=To create a group, \
-just enter a display name and a unique handle to be used in the newsfeed URL \
-then click Save.
-planetGroups.prompt.edit=You are editing a custom aggregation group. Make \
-your changes and then click Save. Or, use click Delete to remove it.
+planetGroups.prompt.add=To create a group, just enter a display name and a unique handle to be used in the feed URL then click Save.
+planetGroups.prompt.edit=You are editing a custom aggregation group. Make your changes and then click Save. Or, use click Delete to remove it.
 
 planetGroups.existingTitle=Existing Custom Aggregation Groups
 planetGroups.existingPrompt=Select an existing custom aggregation group to edit.
 
+planetGroups.noneDefined=No Custom Planet Groups defined.
+
 planetGroups.column.title=Title
 planetGroups.column.subscriptions=Subscriptions
 planetGroups.column.handle=Handle
 
-planetGroups.tip.title=Title of group
-planetGroups.tip.handle=Handle of this group
+planetGroups.tip.title=Title of the group for display purposes.
+planetGroups.tip.handle=Handle of this group. A simple string with no spaces to be used in the group's URL.
 planetGroups.edit.tip=Edit this group
 
+planetGroupSubs.subscriptionDesc=Add subscriptions to this group via the form on the right.
+
 planetGroups.title=Title
 planetGroups.handle=Handle
 
@@ -1202,6 +1208,8 @@
 planetGroups.error.handle=Handle is required
 planetGroups.error.nameReserved=Can''t use handle ''all''
 
+planetGroups.delete.confirm=Are you sure you want to remove this group?
+
 # ------------------------------------------------------------------ Statistics
 
 statCount.weblogCommentCountType=Weblog comment count
@@ -1290,7 +1298,7 @@
 
 tabbedmenu.planet=Planet Admin
 tabbedmenu.admin.planetConfig=Configuration
-tabbedmenu.admin.planetSubscriptions=Subscriptions
+tabbedmenu.admin.planetGroupSubs=Subscriptions
 tabbedmenu.admin.planetGroups=Custom Groups
 
 # ---------------------------------------------------------------------- Search
diff --git a/app/src/main/resources/ApplicationResources_de.properties b/app/src/main/resources/ApplicationResources_de.properties
index e5c9cfa..a4f150e 100644
--- a/app/src/main/resources/ApplicationResources_de.properties
+++ b/app/src/main/resources/ApplicationResources_de.properties
@@ -607,15 +607,15 @@
 planetSubscription.foundExisting=Abonnement [{0}] exisitiert bereits, es wurde aber trotzdem hinzugef\u00FCgt
 planetSubscription.success.deleted=Abonnement erfolgreich gel\u00F6scht
 planetSubscription.success.saved=Abonnement gespeichert
-planetSubscriptions.column.feedUrl=Feed-URL
-planetSubscriptions.column.title=Titel
-planetSubscriptions.error.duringSave=Doppeltes Abonnement? - {0}
-planetSubscriptions.existingTitle=Existierende Abonnements
-planetSubscriptions.prompt.add=Um ein neues Abonnement hinzuzuf\u00FCgen geben Sie bitte die URL des Newsfeed ein und klicken dann auf Speichern.
-planetSubscriptions.prompt.addMain=Nutzen Sie diese Seite zum Hinzuf\u00FCgen von Abonnements zu der Liste der Newsfeeds, welche in der Haupt-Planet-Aggregator-Seite enthalten sein sollen. Um ein neues Abonnement hinzuzuf\u00FCgen geben Sie einfach die Adresse des Newsfeed ein und klicken Sie auf Speichern.
-planetSubscriptions.subtitle.add=Verwaltung der Newsfeed Abonnements in der Gruppe [<b>{0}</b>].
-planetSubscriptions.subtitle.addMain=Verwalten der Hauptliste der Newsfeed Abonnements.
-planetSubscriptions.title=Abonnements
+planetGroupSubs.column.feedUrl=Feed-URL
+planetGroupSubs.column.title=Titel
+planetGroupSubs.error.duringSave=Doppeltes Abonnement? - {0}
+planetGroupSubs.existingTitle=Existierende Abonnements
+planetGroupSubs.prompt.add=Um ein neues Abonnement hinzuzuf\u00FCgen geben Sie bitte die URL des Newsfeed ein und klicken dann auf Speichern.
+planetGroupSubs.prompt.addMain=Nutzen Sie diese Seite zum Hinzuf\u00FCgen von Abonnements zu der Liste der Newsfeeds, welche in der Haupt-Planet-Aggregator-Seite enthalten sein sollen. Um ein neues Abonnement hinzuzuf\u00FCgen geben Sie einfach die Adresse des Newsfeed ein und klicken Sie auf Speichern.
+planetGroupSubs.subtitle.add=Verwaltung der Newsfeed Abonnements in der Gruppe [<b>{0}</b>].
+planetGroupSubs.subtitle.addMain=Verwalten der Hauptliste der Newsfeed Abonnements.
+planetGroupSubs.title=Abonnements
 searchPager.home=Startseite
 searchPager.next=N\u00E4chste Seite
 searchPager.prev=Vorige Seite
@@ -637,7 +637,7 @@
 tabbedmenu.admin.pingTargets=Ping Ziele
 tabbedmenu.admin.planetConfig=Konfiguration
 tabbedmenu.admin.planetGroups=Benutzerdefinierte Gruppen
-tabbedmenu.admin.planetSubscriptions=Abonnements
+tabbedmenu.admin.planetGroupSubs=Abonnements
 tabbedmenu.admin.userAdmin=Benutzerverwaltung
 tabbedmenu.bookmarks.allFolders=Blogroll
 tabbedmenu.design=Design
@@ -672,7 +672,7 @@
 uploadFiles.error.badPath=Der Pfad [{0}] ist ung\u00FCltig. Pfade d\u00FCrfen keine "/", "", oder ".." enthalten.
 uploadFiles.error.upload=Hochladen von [{0}] fehlgeschlagen
 uploadFiles.upload=Hochladen
-# ----------------------------------------------------- PlanetSubscriptions.jsp
+# ----------------------------------------------------- PlanetGroupSubs.jsp
 uploadFiles.uploadedFile={0}
 uploadFiles.uploadedFiles=Hochgeladene Datei(en):
 user.account.activation.mail.content=<html><body style="background: white; color: black; font-size: 12px"> <p>Zum Aktivieren Ihres neuen Roller-Benutzerkontos mit dem Benutzernamen [{1}] klicken Sie bitte auf den folgenden Link:</p> <p><a href="{2}">{2}</a></p></body></html>
diff --git a/app/src/main/resources/ApplicationResources_es.properties b/app/src/main/resources/ApplicationResources_es.properties
index bdf6ec7..7799536 100644
--- a/app/src/main/resources/ApplicationResources_es.properties
+++ b/app/src/main/resources/ApplicationResources_es.properties
@@ -338,20 +338,20 @@
 planetConfig.subtitle=Configurar agregador de noticias de Roller
 planetConfig.prompt=Establecer el t\u00EDtulo, direcci\u00F3n de email y URL del sitio que se incluir\u00E1n en la suscripci\u00F3n de noticias poducida por el agregador. Puede tambi\u00E9n configurar un proxy si es necesario para su red.
 planetConfig.title=Configuraci\u00F3n de Planet
-planetSubscriptions.title=Suscripciones
-planetSubscriptions.subtitle.add=Administrar suscripciones de noticias en el grupo [<b>{0}</b>].
-planetSubscriptions.prompt.add=Para a\u00F1adir una nueva suscripci\u00F3n simplemente introduzca el t\u00EDtulo, la URL de la suscripci\u00F3n de noticias y la URL del sitio, finalmente haga click en el bot\u00F3n Guardar.
-planetSubscriptions.subtitle.addMain=Administrando la lista principal de suscripciones de noticias.
-planetSubscriptions.prompt.addMain=Use esta p\u00E1gina para a\u00F1adir y editar suscripciones\: la lista de suscripciones de noticias que se incluye en la p\u00E1gina principal del agregador Planet. Para a\u00F1adir una nueva suscripci\u00F3n simplemente introduzca el t\u00EDtulo, el t\u00EDtulo, la URL de la suscripci\u00F3n de noticias y la URL del sitio, finalmente haga click en el bot\u00F3n Guardar.
-planetSubscriptions.existingTitle=Suscripciones existentes
-planetSubscriptions.column.title=T\u00EDtulo
-planetSubscriptions.column.feedUrl=URL de la suscripci\u00F3n
+planetGroupSubs.title=Suscripciones
+planetGroupSubs.subtitle.add=Administrar suscripciones de noticias en el grupo [<b>{0}</b>].
+planetGroupSubs.prompt.add=Para a\u00F1adir una nueva suscripci\u00F3n simplemente introduzca el t\u00EDtulo, la URL de la suscripci\u00F3n de noticias y la URL del sitio, finalmente haga click en el bot\u00F3n Guardar.
+planetGroupSubs.subtitle.addMain=Administrando la lista principal de suscripciones de noticias.
+planetGroupSubs.prompt.addMain=Use esta p\u00E1gina para a\u00F1adir y editar suscripciones\: la lista de suscripciones de noticias que se incluye en la p\u00E1gina principal del agregador Planet. Para a\u00F1adir una nueva suscripci\u00F3n simplemente introduzca el t\u00EDtulo, el t\u00EDtulo, la URL de la suscripci\u00F3n de noticias y la URL del sitio, finalmente haga click en el bot\u00F3n Guardar.
+planetGroupSubs.existingTitle=Suscripciones existentes
+planetGroupSubs.column.title=T\u00EDtulo
+planetGroupSubs.column.feedUrl=URL de la suscripci\u00F3n
 planetSubscription.feedUrl=URL de la suscripci\u00F3n de noticias
 planetSubscription.success.deleted=Suscripci\u00F3n eliminada con \u00E9xito
 planetSubscription.success.saved=Suscripci\u00F3n guardada
 planetSubscription.error=Debe especificar la URL de la suscripci\u00F3n de noticias
 planetSubscription.error.feedUrl=La URL de la suscripci\u00F3n de noticias es obligatoria
-planetSubscriptions.error.duringSave=\u00BFSuscripci\u00F3n repetida? - {0}
+planetGroupSubs.error.duringSave=\u00BFSuscripci\u00F3n repetida? - {0}
 planetSubscription.error.deleting=Error eliminando objeto
 planetGroups.pagetitle=Grupos Planet personalizados
 planetGroups.subtitle=A\u00F1adir agregador personalizado de grupos, disponible en forma de suscripci\u00F3n de noticias.
@@ -394,7 +394,7 @@
 tabbedmenu.admin.cacheInfo=Informaci\u00F3n de cach\u00E9
 tabbedmenu.planet=Administraci\u00F3n de Planet
 tabbedmenu.admin.planetConfig=Configuraci\u00F3n
-tabbedmenu.admin.planetSubscriptions=Suscripciones
+tabbedmenu.admin.planetGroupSubs=Suscripciones
 tabbedmenu.admin.planetGroups=Grupos personalizados
 themeEditor.title=Tema del weblog
 themeEditor.subtitle=Seleccionar tema para el weblog <span>{0}</span>
diff --git a/app/src/main/resources/ApplicationResources_fr.properties b/app/src/main/resources/ApplicationResources_fr.properties
index 32cf84a..5332039 100644
--- a/app/src/main/resources/ApplicationResources_fr.properties
+++ b/app/src/main/resources/ApplicationResources_fr.properties
@@ -709,26 +709,26 @@
 ConfigForm.proxyPort=Port du serveur Proxy
 #pour la récuperation des fils d'information
 
-# ----------------------------------------------------- PlanetSubscriptions.jsp
+# ----------------------------------------------------- PlanetGroupSubs.jsp
 
-planetSubscriptions.title=Souscriptions
+planetGroupSubs.title=Souscriptions
 
-planetSubscriptions.subtitle.add=\
+planetGroupSubs.subtitle.add=\
 Gestion des souscriptions aux fils d'information dans le groupe [<b>{0}</b>].
-planetSubscriptions.prompt.add=Pour ajouter une nouvelle souscription, entrez son titre, \
+planetGroupSubs.prompt.add=Pour ajouter une nouvelle souscription, entrez son titre, \
 l'adresse URL du fil d'information et celle du site, puis cliquez sur 'Enregistrer'.
 
-planetSubscriptions.subtitle.addMain=\
+planetGroupSubs.subtitle.addMain=\
 Gérer la liste principale de souscriptions aux fils d'information.
-planetSubscriptions.prompt.addMain=Utilisez cette page pour ajouter ou éditer les souscriptions qui \
+planetGroupSubs.prompt.addMain=Utilisez cette page pour ajouter ou éditer les souscriptions qui \
 s'ajouterons à la page d'aggrégation de Planet. \
 Pour ajouter une nouvelle souscription, entrez son titre, \
 l'adresse URL du fil d'information et celle du site, puis cliquez sur 'Enregistrer'.
 
-planetSubscriptions.existingTitle=Souscriptions existantes
+planetGroupSubs.existingTitle=Souscriptions existantes
 
-planetSubscriptions.column.title=Titre
-planetSubscriptions.column.feedUrl=URL du fil
+planetGroupSubs.column.title=Titre
+planetGroupSubs.column.feedUrl=URL du fil
 
 planetSubscription.feedUrl=URL du fil d'information
 
@@ -739,7 +739,7 @@
 
 planetSubscription.error=Vous devez specifier une adresse URL pour le fil d'information
 planetSubscription.error.feedUrl=URL du fil requise
-planetSubscriptions.error.duringSave=La souscription {0} semble déjà exister
+planetGroupSubs.error.duringSave=La souscription {0} semble déjà exister
 de la souscription.
 
 # ------------------------------------------------------------ PlanetGroups.jsp
@@ -807,7 +807,7 @@
 
 tabbedmenu.planet=Admin. Planet
 tabbedmenu.admin.planetConfig=Configuration
-tabbedmenu.admin.planetSubscriptions=Souscriptions
+tabbedmenu.admin.planetGroupSubs=Souscriptions
 tabbedmenu.admin.planetGroups=Groupes personnalisés
 
 # ---------------------------------------------------------------------- Search
diff --git a/app/src/main/resources/ApplicationResources_ja.properties b/app/src/main/resources/ApplicationResources_ja.properties
index 03b5a9d..5a210c2 100644
--- a/app/src/main/resources/ApplicationResources_ja.properties
+++ b/app/src/main/resources/ApplicationResources_ja.properties
@@ -548,7 +548,7 @@
 planetConfig.subtitle=Roller\u5185\u8535\u306E\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9\u30FB\u30A2\u30B0\u30EA\u30B2\u30FC\u30BF\u3092\u8A2D\u5B9A
 planetConfig.title=Planet \u8A2D\u5B9A
 
-# ----------------------------------------------------- PlanetSubscriptions.jsp
+# ----------------------------------------------------- PlanetGroupSubs.jsp
 
 planetSubscription.success.saved=\u8CFC\u8AAD\u304C\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F
 
@@ -1065,7 +1065,7 @@
 categoryForm.changesSaved=\u30AB\u30C6\u30B4\u30EA "{0}" \u304C\u66F4\u65B0\u3055\u308C\u307E\u3057\u305F
 mediaFileView.dirPageTip=\u3053\u308C\u306F\u30E1\u30C7\u30A3\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30B5\u30D6\u30D5\u30A9\u30EB\u30C0\u3067\u3059\u3002
 userRegister.heading.identification=\u3069\u306E\u3088\u3046\u306B\u8B58\u5225\u3055\u308C\u305F\u3044\u3067\u3059\u304B?
-planetSubscriptions.subtitle.add=\u30B0\u30EB\u30FC\u30D7 [<b>{0}</b>] \u306E\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9\u30FB\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3092\u7BA1\u7406\u3057\u307E\u3059\u3002
+planetGroupSubs.subtitle.add=\u30B0\u30EB\u30FC\u30D7 [<b>{0}</b>] \u306E\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9\u30FB\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3092\u7BA1\u7406\u3057\u307E\u3059\u3002
 pageForm.launch=\u8868\u793A
 error.unexpected=\u4E88\u671F\u305B\u306C\u30A8\u30E9\u30FC\u3067\u3059\u3002\u30A8\u30E9\u30FC\u304C\u518D\u767A\u3059\u308B\u5834\u5408\u3001\u7BA1\u7406\u8005\u306B\u9023\u7D61\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 mediaFileView.date=\u65E5\u4ED8
@@ -1115,7 +1115,7 @@
 userRegister.tip.openIdUrl=Open ID\u8B58\u5225\u5B50(URL\u5F62\u5F0F)\u3002
 pingTarget.editTarget=Ping\u30BF\u30FC\u30B2\u30C3\u30C8\u3092\u7DE8\u96C6\u3059\u308B
 mediaFileAdd.directory=\u30D5\u30A9\u30EB\u30C0
-planetSubscriptions.title=\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3
+planetGroupSubs.title=\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3
 mediaFileView.size=\u30B5\u30A4\u30BA
 stylesheetEdit.tip=\u3053\u306E\u30D5\u30A9\u30FC\u30E0\u3092\u4F7F\u3063\u3066\u3001\u3042\u306A\u305F\u306E\u30C6\u30FC\u30DE\u306E\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u3092\u7DE8\u96C6\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002
 themeEditor.importAndOverwriteTemplates.tooltip=\u3053\u306E\u30D6\u30ED\u30B0\u306F\u3001\u3059\u3067\u306B\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u30FB\u30BF\u30D6\u3067\u5B9A\u7FA9\u3055\u308C\u305F\u30AB\u30B9\u30BF\u30E0\u30FB\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u6301\u3063\u3066\u3044\u307E\u3059\u3002\u5171\u6709\u30C6\u30FC\u30DE\u3068\u540C\u540D\u306E\u65E2\u5B58\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u4E0A\u66F8\u304D\u3057\u305F\u3044\u5834\u5408\u306F\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u65E2\u5B58\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u4F7F\u3063\u3066\u5358\u306B\u30AB\u30B9\u30BF\u30E0\u30FB\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u5207\u308A\u66FF\u3048\u305F\u3044\u5834\u5408\u306F\u9078\u629E\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
@@ -1157,7 +1157,7 @@
 maintenance.message.reset=\u30A2\u30AF\u30BB\u30B9\u30AB\u30A6\u30F3\u30BF\u304C\u6B63\u5E38\u306B\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F
 email.comment.commenter.email=\u30B3\u30E1\u30F3\u30C8\u6295\u7A3F\u8005\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9
 welcome.user.account.not.activated=\u30B7\u30B9\u30C6\u30E0\u306B\u30ED\u30B0\u30A4\u30F3\u3059\u308B\u306B\u306F\u3001\u30E1\u30FC\u30EB\u3067\u9001\u4FE1\u3055\u308C\u305F\u30EA\u30F3\u30AF\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u3042\u306A\u305F\u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u6709\u52B9\u5316\u3057\u306A\u3051\u308C\u3070\u306A\u308A\u307E\u305B\u3093\u3002
-planetSubscriptions.prompt.add=\u65B0\u3057\u3044\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3092\u8FFD\u52A0\u3059\u308B\u306B\u306F\u3001\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9URL\u3092\u5165\u529B\u3057\u3066\u3001\u4FDD\u5B58\u30DC\u30BF\u30F3\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u304F\u3060\u3055\u3044\u3002
+planetGroupSubs.prompt.add=\u65B0\u3057\u3044\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3092\u8FFD\u52A0\u3059\u308B\u306B\u306F\u3001\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9URL\u3092\u5165\u529B\u3057\u3066\u3001\u4FDD\u5B58\u30DC\u30BF\u30F3\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 MediaFile.error.view=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u8868\u793A\u3059\u308B\u969B\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
 mediaFileAdd.multipleNames=(\u8907\u6570\u306E\u540D\u524D)
 macro.bookmark.urlFeed=\u30B5\u30A4\u30C8\u306ERSS\u30D5\u30A3\u30FC\u30C9\u306EURL
@@ -1188,10 +1188,10 @@
 weblogEdit.enclosureURL=\u30A8\u30F3\u30AF\u30ED\u30FC\u30B8\u30E3URL
 userRegister.success.ready=\u30D5\u30A9\u30FC\u30E0\u306F\u554F\u984C\u306A\u304F\u5165\u529B\u3055\u308C\u3066\u3044\u308B\u3088\u3046\u3067\u3059\u3002\u4EE5\u4E0B\u306E\u30DC\u30BF\u30F3\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 pageForm.tip=\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u7DE8\u96C6\u3057\u3066\u3001\u751F\u6210\u3055\u308C\u308B\u30DA\u30FC\u30B8\u3092\u5909\u66F4\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3067\u4F7F\u7528\u3059\u308B\u3053\u3068\u306E\u3067\u304D\u308B\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u304A\u3088\u3073\u30B3\u30FC\u30C9\u306B\u3064\u3044\u3066\u306FRoller\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u30FB\u30AC\u30A4\u30C9\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u3053\u308C\u306F\u4E0A\u7D1A\u30E6\u30FC\u30B6\u30FC\u306E\u305F\u3081\u306E\u3082\u306E\u3067\u3042\u308A\u3001\u3082\u3057\u3042\u306A\u305F\u304CHTML\u306B\u8A73\u3057\u304F\u306A\u3044\u5834\u5408\u306F\u305D\u306E\u307E\u307E\u306B\u3057\u3066\u304A\u3044\u305F\u65B9\u304C\u826F\u3044\u3067\u3057\u3087\u3046\u3002
-planetSubscriptions.column.feedUrl=\u30D5\u30A3\u30FC\u30C9URL
+planetGroupSubs.column.feedUrl=\u30D5\u30A3\u30FC\u30C9URL
 mediaFileSuccess.createPost=\u65B0\u3057\u304F\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u3092\u4F7F\u3063\u3066\u65B0\u3057\u3044\u30A8\u30F3\u30C8\u30EA\u3092\u4F5C\u6210\u3059\u308B
 bookmarkForm.requiredFields={0}\u3068{1}\u306F\u5FC5\u9808\u3067\u3059\u3002
-planetSubscriptions.column.title=\u30BF\u30A4\u30C8\u30EB
+planetGroupSubs.column.title=\u30BF\u30A4\u30C8\u30EB
 bookmarksForm.deleteFolder.confirm=\u30D5\u30A9\u30EB\u30C0\u3068\u3001\u30D5\u30A9\u30EB\u30C0\u306B\u542B\u307E\u308C\u308B\u30D6\u30C3\u30AF\u30DE\u30FC\u30AF\u3092\u524A\u9664\u3057\u3066\u3088\u308D\u3057\u3044\u3067\u3059\u304B?
 planetSubscription.error=\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9URL\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
 mediaFile.update.success=\u30E1\u30C7\u30A3\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB\u306F\u6B63\u5E38\u306B\u66F4\u65B0\u3055\u308C\u307E\u3057\u305F\u3002
@@ -1241,7 +1241,7 @@
 createWebsite.disabled=\u7533\u3057\u8A33\u3042\u308A\u307E\u305B\u3093\u304C\u3001\u65B0\u3057\u3044\u30D6\u30ED\u30B0\u306E\u4F5C\u6210\u306F\u3001\u7BA1\u7406\u8005\u306B\u3088\u3063\u3066\u7121\u52B9\u306B\u3055\u308C\u3066\u3044\u307E\u3059\u3002
 macro.weblog.postcomment=\u30B3\u30E1\u30F3\u30C8\u3092\u6295\u7A3F
 Entry.error.categoryNull=\u30AB\u30C6\u30B4\u30EA\u306F\u5FC5\u9808\u9805\u76EE\u3067\u3059
-planetSubscriptions.prompt.addMain=\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3092\u3001\u30E1\u30A4\u30F3Planet\u30A2\u30B0\u30EA\u30B2\u30FC\u30BF\u30FC\u30FB\u30DA\u30FC\u30B8\u306B\u542B\u307E\u308C\u308B\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9\u4E00\u89A7\u306B\u8FFD\u52A0\u3059\u308B\u306B\u306F\u3053\u306E\u30DA\u30FC\u30B8\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u65B0\u3057\u3044\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3092\u8FFD\u52A0\u3059\u308B\u306B\u306F\u3001\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9URL\u3092\u5165\u529B\u3057\u3066\u4FDD\u5B58\u30DC\u30BF\u30F3\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u304F\u3060\u3055\u3044\u3002
+planetGroupSubs.prompt.addMain=\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3092\u3001\u30E1\u30A4\u30F3Planet\u30A2\u30B0\u30EA\u30B2\u30FC\u30BF\u30FC\u30FB\u30DA\u30FC\u30B8\u306B\u542B\u307E\u308C\u308B\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9\u4E00\u89A7\u306B\u8FFD\u52A0\u3059\u308B\u306B\u306F\u3053\u306E\u30DA\u30FC\u30B8\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u65B0\u3057\u3044\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3092\u8FFD\u52A0\u3059\u308B\u306B\u306F\u3001\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9URL\u3092\u5165\u529B\u3057\u3066\u4FDD\u5B58\u30DC\u30BF\u30F3\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u304F\u3060\u3055\u3044\u3002
 mediaFileView.audio=\u97F3\u58F0
 weblogEdit.mediaCastResponseError=\u30A8\u30F3\u30AF\u30ED\u30FC\u30B8\u30E3\u30FB\u30B5\u30FC\u30D0\u306F\u30A8\u30E9\u30FC\u3092\u8FD4\u3057\u307E\u3057\u305F\u3002\u6B63\u3057\u3044URL\u3067\u3059\u304B?
 themeEditor.importRequired=\u4ECA\u56DE\u304C\u521D\u3081\u3066\u306E\u30AB\u30B9\u30BF\u30E0\u30FB\u30C6\u30FC\u30DE\u306E\u4F7F\u7528\u3067\u3042\u308B\u305F\u3081\u3001\u65E2\u5B58\u306E\u30C6\u30FC\u30DE\u304B\u3089\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u30B3\u30D4\u30FC\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
@@ -1262,7 +1262,7 @@
 pageForm.templateLanguage=\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u306E\u8A00\u8A9E
 mediaFile.deleteFolder.success=\u30D5\u30A9\u30EB\u30C0\u306F\u6B63\u5E38\u306B\u524A\u9664\u3055\u308C\u307E\u3057\u305F\u3002
 mediaFileEdit.includesEnclosure=\u3053\u306E\u30A8\u30F3\u30C8\u30EA\u306F\u4EE5\u4E0B\u306E\u30E1\u30C7\u30A3\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB\u30FB\u30A8\u30F3\u30AF\u30ED\u30FC\u30B8\u30E3\u3092\u542B\u307F\u307E\u3059\:
-planetSubscriptions.error.duringSave=\u91CD\u8907\u3059\u308B\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3? - {0}
+planetGroupSubs.error.duringSave=\u91CD\u8907\u3059\u308B\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3? - {0}
 weblogEntry.pendingEntryContent=\u30E6\u30FC\u30B6\u30FC [{0}] \u306F\u3001\u3042\u306A\u305F\u306E\u30EC\u30D3\u30E5\u30FC\u3092\u53D7\u3051\u308B\u305F\u3081\u306B\u65B0\u3057\u3044\u30A8\u30F3\u30C8\u30EA\u30FC\u3092\u9001\u4FE1\u3057\u307E\u3057\u305F\u3002\u3053\u306E\u6295\u7A3F\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3001\u516C\u958B\u3059\u308B\u304B\u30E6\u30FC\u30B6\u30FC [{1}] \u304C\u518D\u5EA6\u7DE8\u96C6\u3067\u304D\u308B\u3088\u3046\u306B\u4E0B\u66F8\u304D\u3068\u3057\u3066\u4FDD\u5B58\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30EC\u30D3\u30E5\u30FC\u5F85\u3061\u306E\u6295\u7A3F\u3092\u7DE8\u96C6\u3059\u308B\u305F\u3081\u306E\u30EA\u30F3\u30AF\u306F\u3053\u3061\u3089\u3067\u3059\:<{2}>
 websiteSettings.analyticsTrackingCode=\u30C8\u30E9\u30C3\u30AD\u30F3\u30B0\u30FB\u30B3\u30FC\u30C9
 mediaFileView.mb=MB
@@ -1295,7 +1295,7 @@
 mediaFile.includeInGallery.error=\u30E1\u30C7\u30A3\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB {0} \u3092\u30AE\u30E3\u30E9\u30EA\u30FC\u306B\u8FFD\u52A0\u3059\u308B\u969B\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
 WeblogConfig.error.analyticsCodeSize=\u30A2\u30CA\u30EA\u30C6\u30A3\u30AF\u30B9\u30FB\u30C8\u30E9\u30C3\u30AD\u30F3\u30B0\u30FB\u30B3\u30FC\u30C9\u306F1200\u6587\u5B57\u4EE5\u5185\u3067\u306A\u3051\u308C\u3070\u306A\u308A\u307E\u305B\u3093
 Entry.error.titleNull=\u30BF\u30A4\u30C8\u30EB\u306F\u5FC5\u9808\u9805\u76EE\u3067\u3059
-planetSubscriptions.subtitle.addMain=\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9\u30FB\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u306E\u30E1\u30A4\u30F3\u30FB\u30EA\u30B9\u30C8\u3092\u7BA1\u7406\u3057\u307E\u3059\u3002
+planetGroupSubs.subtitle.addMain=\u30CB\u30E5\u30FC\u30B9\u30D5\u30A3\u30FC\u30C9\u30FB\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u306E\u30E1\u30A4\u30F3\u30FB\u30EA\u30B9\u30C8\u3092\u7BA1\u7406\u3057\u307E\u3059\u3002
 mediaFile.move.errors=\u30E1\u30C7\u30A3\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u79FB\u52D5\u3059\u308B\u969B\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
 mediaFileSuccess.addAnother=\u4ED6\u306E\u30E1\u30C7\u30A3\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3059\u308B
 pingTarget.pingUrlMissing=Ping URL\u306F\u5FC5\u9808\u9805\u76EE\u3067\u3059
@@ -1389,7 +1389,7 @@
 weblogEdit.enclosureLength=\u9577\u3055
 weblogEntryQuery.label.startDate=\u958B\u59CB\u65E5
 mediaFileEdit.pagetip=\u3053\u306E\u30E1\u30C7\u30A3\u30A2\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u60C5\u5831\u3092\u7DE8\u96C6\u3057\u307E\u3059\u3002\u305D\u308C\u305E\u308C\u306E\u30D5\u30A1\u30A4\u30EB\u306B\u306F\u540D\u524D\u304C\u5FC5\u8981\u3067\u3059\u304C\u3001\u4ED6\u306E\u9805\u76EE\u306F\u7701\u7565\u3067\u304D\u307E\u3059\u3002
-planetSubscriptions.existingTitle=\u65E2\u5B58\u306E\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3
+planetGroupSubs.existingTitle=\u65E2\u5B58\u306E\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3
 stylesheetEdit.default.success=\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u304C\u6B63\u5E38\u306B\u524A\u9664\u3055\u308C\u307E\u3057\u305F\u3002\u5171\u6709\u306E\u30C6\u30FC\u30DE\u30FB\u30C7\u30D5\u30A9\u30EB\u30C8\u304C\u6709\u52B9\u306B\u306A\u308A\u307E\u3057\u305F\u3002
 pageRemoves.youSure=\u3053\u306E\u30DA\u30FC\u30B8\u3092\u524A\u9664\u3057\u307E\u3059\u304B\uFF1F
 mediaFileAdd.fileLocation=\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3059\u308B\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E
@@ -1429,7 +1429,7 @@
 mediaFileSuccess.bytes=\u30D0\u30A4\u30C8
 mediaFileView.moveSelected=\u9078\u629E\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u3092\u30D5\u30A9\u30EB\u30C0\u306B\u79FB\u52D5\:
 oauthKeys.urls=OAuth\u306EURL
-tabbedmenu.admin.planetSubscriptions=\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3
+tabbedmenu.admin.planetGroupSubs=\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3
 weblogEdit.submittedForReview=\u30A8\u30F3\u30C8\u30EA\u30FC\u304C\u30EC\u30D3\u30E5\u30FC\u3092\u53D7\u3051\u308B\u305F\u3081\u306B\u9001\u4FE1\u3055\u308C\u307E\u3057\u305F
 installer.upgradeTables=\u30C6\u30FC\u30D6\u30EB\u3092\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u3057\u307E\u3059\u304B?
 configForm.none=\u6307\u5B9A\u306A\u3057
diff --git a/app/src/main/resources/ApplicationResources_ko.properties b/app/src/main/resources/ApplicationResources_ko.properties
index 5cad3a1..cc8144a 100644
--- a/app/src/main/resources/ApplicationResources_ko.properties
+++ b/app/src/main/resources/ApplicationResources_ko.properties
@@ -778,24 +778,24 @@
 ConfigForm.message.saveSucceeded=\ud50c\ub798\ub2db \ud658\uacbd \uc124\uc815\uc774 \uc800\uc7a5\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
 ConfigForm.error.saveFailed=\ud50c\ub798\ub2db \ud658\uacbd \uc124\uc815\uc744 \uc800\uc7a5\ud558\ub294 \uc911\uc5d0 \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4.
 
-# ----------------------------------------------------- PlanetSubscriptions.jsp
+# ----------------------------------------------------- PlanetGroupSubs.jsp
 
-planetSubscriptions.title=\uad6c\ub3c5
+planetGroupSubs.title=\uad6c\ub3c5
 
-planetSubscriptions.subtitle.add=\
+planetGroupSubs.subtitle.add=\
 \uadf8\ub8f9, [<b>{0}</b>] \ub0b4\uc758 \ub274\uc2a4\ud53c\ub4dc \uad6c\ub3c5 \uad00\ub9ac.
-planetSubscriptions.prompt.add=\uc0c8\ub85c\uc6b4 \uad6c\ub3c5\uc744 \ucd94\uac00\ud558\ub824\uba74, \
+planetGroupSubs.prompt.add=\uc0c8\ub85c\uc6b4 \uad6c\ub3c5\uc744 \ucd94\uac00\ud558\ub824\uba74, \
 \ub274\uc2a4\ud53c\ub4dc URL\uc744 \uc785\ub825\ud558\uc2e0 \ud6c4 \uc800\uc7a5 \ubc84\ud2bc\uc744 \ud074\ub9ad\ud558\uc2ed\uc2dc\uc624.
 
-planetSubscriptions.subtitle.addMain=\ub274\uc2a4\ud53c\ub4dc \uad6c\ub3c5 \uba54\uc778 \ubaa9\ub85d \uad00\ub9ac
-planetSubscriptions.prompt.addMain=\uc774 \ud398\uc774\uc9c0\ub97c \uc0ac\uc6a9\ud558\uc5ec \
+planetGroupSubs.subtitle.addMain=\ub274\uc2a4\ud53c\ub4dc \uad6c\ub3c5 \uba54\uc778 \ubaa9\ub85d \uad00\ub9ac
+planetGroupSubs.prompt.addMain=\uc774 \ud398\uc774\uc9c0\ub97c \uc0ac\uc6a9\ud558\uc5ec \
 \uba54\uc778 \ud50c\ub798\ub2db \ud1b5\ud569 \uae30\ub2a5 \ud398\uc774\uc9c0\uc5d0 \ud3ec\ud568\ub420 \ub274\uc2a4\ud53c\ub4dc \ubaa9\ub85d\uc5d0 \uad6c\ub3c5\uc744 \ucd94\uac00\ud558\uc2ed\uc2dc\uc624. \
 \uc0c8\ub85c\uc6b4 \uad6c\ub3c5\uc744 \ucd94\uac00\ud558\uc2dc\ub824\uba74 \ub274\uc2a4\ud53c\ub4dc URL\uc744 \uc785\ub825\ud558\uc2dc\uace0 \uc800\uc7a5 \ubc84\ud2bc\uc744 \ud074\ub9ad\ud558\uc2ed\uc2dc\uc624.
 
-planetSubscriptions.existingTitle=\uae30\uc874 \uad6c\ub3c5
+planetGroupSubs.existingTitle=\uae30\uc874 \uad6c\ub3c5
 
-planetSubscriptions.column.title=\uc81c\ubaa9
-planetSubscriptions.column.feedUrl=\ud53c\ub4dc URL
+planetGroupSubs.column.title=\uc81c\ubaa9
+planetGroupSubs.column.feedUrl=\ud53c\ub4dc URL
 
 planetSubscription.feedUrl=\ub274\uc2a4\ud53c\ub4dc URL
 planetSubscription.success.deleted=\uad6c\ub3c5\uc774 \uc131\uacf5\uc801\uc73c\ub85c \uc0ad\uc81c\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
@@ -804,7 +804,7 @@
 
 planetSubscription.error=\ub274\uc2a4\ud53c\ub4dc URL\uc744 \uc124\uc815\ud574\uc57c \ud569\ub2c8\ub2e4.
 planetSubscription.error.feedUrl=\ub274\uc2a4\ud53c\ub4dc URL\uc744 \uc785\ub825\ud558\uc2ed\uc2dc\uc624.
-planetSubscriptions.error.duringSave=\uc911\ubcf5\ub41c \uad6c\ub3c5\uc785\ub2c8\ub2e4 - {0}.
+planetGroupSubs.error.duringSave=\uc911\ubcf5\ub41c \uad6c\ub3c5\uc785\ub2c8\ub2e4 - {0}.
 planetSubscription.error.deleting=\uac1d\uccb4 \uc0ad\uc81c \uc624\ub958
 
 # ------------------------------------------------------------ PlanetGroups.jsp
@@ -882,7 +882,7 @@
 tabbedmenu.admin.cacheInfo=\uce90\uc2dc \uc815\ubcf4
 tabbedmenu.planet=\ud50c\ub798\ub2db \uad00\ub9ac\uc790
 tabbedmenu.admin.planetConfig=\ud658\uacbd\uc124\uc815
-tabbedmenu.admin.planetSubscriptions=\uad6c\ub3c5
+tabbedmenu.admin.planetGroupSubs=\uad6c\ub3c5
 tabbedmenu.admin.planetGroups=\ucee4\uc2a4\ud140 \uadf8\ub8f9
 
 # ---------------------------------------------------------------------- Search
diff --git a/app/src/main/resources/ApplicationResources_ru.properties b/app/src/main/resources/ApplicationResources_ru.properties
index efa850c..ce5c695 100644
--- a/app/src/main/resources/ApplicationResources_ru.properties
+++ b/app/src/main/resources/ApplicationResources_ru.properties
@@ -464,19 +464,19 @@
 planetConfig.title=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 Planet

 planetConfig.tip.description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0449\u0435\u0435\u0441\u044F \u0432 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0435 \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u043E\u0439 \u043B\u0435\u043D\u0442\u044B

 

-# ----------------------------------------------------- PlanetSubscriptions.jsp

+# ----------------------------------------------------- PlanetGroupSubs.jsp

 

-planetSubscriptions.title=\u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0438

-planetSubscriptions.subtitle.add=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0430\u043C\u0438 \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u044B\u0445 \u043B\u0435\u043D\u0442 \u0432 \u0433\u0440\u0443\u043F\u043F\u0435 [<b>{0}</b>]

-planetSubscriptions.prompt.add=\u0427\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043D\u043E\u0432\u0443\u044E \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0443, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435, URL \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u043E\u0439 \u043B\u0435\u043D\u0442\u044B, URL \u0441\u0430\u0439\u0442\u0430 \u0438 \u043D\u0430\u0436\u043C\u0438\u0442\u0435 \u043A\u043D\u043E\u043F\u043A\u0443 "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C"

+planetGroupSubs.title=\u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0438

+planetGroupSubs.subtitle.add=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0430\u043C\u0438 \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u044B\u0445 \u043B\u0435\u043D\u0442 \u0432 \u0433\u0440\u0443\u043F\u043F\u0435 [<b>{0}</b>]

+planetGroupSubs.prompt.add=\u0427\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043D\u043E\u0432\u0443\u044E \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0443, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435, URL \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u043E\u0439 \u043B\u0435\u043D\u0442\u044B, URL \u0441\u0430\u0439\u0442\u0430 \u0438 \u043D\u0430\u0436\u043C\u0438\u0442\u0435 \u043A\u043D\u043E\u043F\u043A\u0443 "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C"

 

-planetSubscriptions.subtitle.addMain=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0433\u043B\u0430\u0432\u043D\u044B\u043C \u0441\u043F\u0438\u0441\u043A\u043E\u043C \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u044B\u0445 \u043F\u043E\u0434\u043F\u0438\u0441\u043E\u043A

-planetSubscriptions.prompt.addMain=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u044D\u0442\u0443 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u0434\u043B\u044F \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0438 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043F\u043E\u0434\u043F\u0438\u0441\u043E\u043A: \u0441\u043F\u0438\u0441\u043E\u043A \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u044B\u0445 \u043B\u0435\u043D\u0442 \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u043E\u0439 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043E\u0440\u0430 Planet. \u0427\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043D\u043E\u0432\u0443\u044E \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0443, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435, URL \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u043E\u0439 \u043B\u0435\u043D\u0442\u044B, URL \u0441\u0430\u0439\u0442\u0430 \u0438 \u043D\u0430\u0436\u043C\u0438\u0442\u0435 \u043A\u043D\u043E\u043F\u043A\u0443 "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C"

+planetGroupSubs.subtitle.addMain=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0433\u043B\u0430\u0432\u043D\u044B\u043C \u0441\u043F\u0438\u0441\u043A\u043E\u043C \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u044B\u0445 \u043F\u043E\u0434\u043F\u0438\u0441\u043E\u043A

+planetGroupSubs.prompt.addMain=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u044D\u0442\u0443 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u0434\u043B\u044F \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0438 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043F\u043E\u0434\u043F\u0438\u0441\u043E\u043A: \u0441\u043F\u0438\u0441\u043E\u043A \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u044B\u0445 \u043B\u0435\u043D\u0442 \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u043E\u0439 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043E\u0440\u0430 Planet. \u0427\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043D\u043E\u0432\u0443\u044E \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0443, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435, URL \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u043E\u0439 \u043B\u0435\u043D\u0442\u044B, URL \u0441\u0430\u0439\u0442\u0430 \u0438 \u043D\u0430\u0436\u043C\u0438\u0442\u0435 \u043A\u043D\u043E\u043F\u043A\u0443 "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C"

 

-planetSubscriptions.existingTitle=\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438

+planetGroupSubs.existingTitle=\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438

 

-planetSubscriptions.column.title=\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A, \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435

-planetSubscriptions.column.feedUrl=URL \u043B\u0435\u043D\u0442\u044B

+planetGroupSubs.column.title=\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A, \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435

+planetGroupSubs.column.feedUrl=URL \u043B\u0435\u043D\u0442\u044B

 planetSubscription.feedUrl=URL \u043D\u043E\u0432\u043E\u0441\u043D\u043E\u0439 \u043B\u0435\u043D\u0442\u044B

 

 planetSubscription.success.deleted=\u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0443\u0434\u0430\u043B\u0435\u043D\u0430

@@ -484,7 +484,7 @@
 

 planetSubscription.error=\u0414\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D URL \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u043E\u0439 \u043B\u0435\u043D\u0442\u044B

 planetSubscription.error.feedUrl=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F URL (\u0430\u0434\u0440\u0435\u0441) \u043D\u043E\u0432\u043E\u0441\u0442\u043D\u043E\u0439 \u043B\u0435\u043D\u0442\u044B

-planetSubscriptions.error.duringSave=\u041F\u0440\u043E\u0434\u0443\u0431\u043B\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0443? {0}

+planetGroupSubs.error.duringSave=\u041F\u0440\u043E\u0434\u0443\u0431\u043B\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0443? {0}

 planetSubscription.error.deleting=\u041E\u0448\u0438\u0431\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u043E\u0431\u044A\u0435\u043A\u0442\u0430

 

 # ------------------------------------------------------------ PlanetGroups.jsp

@@ -537,7 +537,7 @@
 tabbedmenu.admin.pingTargets=\u0410\u0434\u0440\u0435\u0441\u0430\u0442\u044B \u043F\u0438\u043D\u0433\u0430

 tabbedmenu.planet=Planet Admin

 tabbedmenu.admin.planetConfig=\u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F

-tabbedmenu.admin.planetSubscriptions=\u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0438

+tabbedmenu.admin.planetGroupSubs=\u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0438

 tabbedmenu.admin.planetGroups=\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u0433\u0440\u0443\u043F\u043F\u044B

 

 

diff --git a/app/src/main/resources/ApplicationResources_zh_CN.properties b/app/src/main/resources/ApplicationResources_zh_CN.properties
index 470a468..77c7ec8 100644
--- a/app/src/main/resources/ApplicationResources_zh_CN.properties
+++ b/app/src/main/resources/ApplicationResources_zh_CN.properties
@@ -369,15 +369,15 @@
 planetSubscription.foundExisting=\u53D1\u73B0\u5DF2\u7ECF\u5B58\u5728\u8BA2\u9605 [{0}] \uFF0C\u66FF\u6362\u5417
 planetSubscription.success.deleted=\u8BA2\u9605\u6210\u529F\u5220\u9664
 planetSubscription.success.saved=\u8BA2\u9605\u5DF2\u4FDD\u5B58
-planetSubscriptions.column.feedUrl=\u65B0\u95FB\u79CD\u5B50URL
-planetSubscriptions.column.title=\u6807\u9898
-planetSubscriptions.error.duringSave=\u590D\u5236\u8BA2\u9605\uFF1F\uFF0D{0}
-planetSubscriptions.existingTitle=\u5B58\u5728\u7684\u8BA2\u9605
-planetSubscriptions.prompt.add=\u6DFB\u52A0\u4E00\u4E2A\u65B0\u7684\u8BA2\u9605\u5F88\u7B80\u5355\uFF1A\u8F93\u5165\u6807\u9898\u3001\u65B0\u95FB\u79CD\u5B50URL\u7136\u540E\u4FDD\u5B58\u3002
-planetSubscriptions.prompt.addMain=\u5728\u8FD9\u4E2A\u9875\u9762\u4E2D\u6DFB\u52A0\u3001\u7F16\u8F91\u8BA2\u9605\uFF1A\u65B0\u95FB\u79CD\u5B50\u5217\u8868\u5728\u884C\u661F\u65B0\u95FB\u805A\u5408\u5668\u9875\u9762\u4E4B\u4E2D\u3002\u6DFB\u52A0\u4E00\u4E2A\u65B0\u8BA2\u9605\u5F88\u7B80\u5355\uFF1A\u8F93\u5165\u6807\u9898\u3001\u65B0\u95FB\u79CD\u5B50URL\u7136\u540E\u4FDD\u5B58\u3002
-planetSubscriptions.subtitle.add=\u7BA1\u7406\u7FA4\u7EC4 [<b>{0}</b>] \u7684\u8BA2\u9605\u3002
-planetSubscriptions.subtitle.addMain=\u7BA1\u7406\u4E3B\u65B0\u95FB\u8BA2\u9605\u5217\u8868\u3002
-planetSubscriptions.title=\u8BA2\u9605
+planetGroupSubs.column.feedUrl=\u65B0\u95FB\u79CD\u5B50URL
+planetGroupSubs.column.title=\u6807\u9898
+planetGroupSubs.error.duringSave=\u590D\u5236\u8BA2\u9605\uFF1F\uFF0D{0}
+planetGroupSubs.existingTitle=\u5B58\u5728\u7684\u8BA2\u9605
+planetGroupSubs.prompt.add=\u6DFB\u52A0\u4E00\u4E2A\u65B0\u7684\u8BA2\u9605\u5F88\u7B80\u5355\uFF1A\u8F93\u5165\u6807\u9898\u3001\u65B0\u95FB\u79CD\u5B50URL\u7136\u540E\u4FDD\u5B58\u3002
+planetGroupSubs.prompt.addMain=\u5728\u8FD9\u4E2A\u9875\u9762\u4E2D\u6DFB\u52A0\u3001\u7F16\u8F91\u8BA2\u9605\uFF1A\u65B0\u95FB\u79CD\u5B50\u5217\u8868\u5728\u884C\u661F\u65B0\u95FB\u805A\u5408\u5668\u9875\u9762\u4E4B\u4E2D\u3002\u6DFB\u52A0\u4E00\u4E2A\u65B0\u8BA2\u9605\u5F88\u7B80\u5355\uFF1A\u8F93\u5165\u6807\u9898\u3001\u65B0\u95FB\u79CD\u5B50URL\u7136\u540E\u4FDD\u5B58\u3002
+planetGroupSubs.subtitle.add=\u7BA1\u7406\u7FA4\u7EC4 [<b>{0}</b>] \u7684\u8BA2\u9605\u3002
+planetGroupSubs.subtitle.addMain=\u7BA1\u7406\u4E3B\u65B0\u95FB\u8BA2\u9605\u5217\u8868\u3002
+planetGroupSubs.title=\u8BA2\u9605
 tabbedmenu.admin=\u670D\u52A1\u5668\u7BA1\u7406
 tabbedmenu.admin.cacheInfo=\u7F13\u5B58\u4FE1\u606F
 tabbedmenu.admin.commentManagement=\u8BC4\u8BBA
@@ -385,7 +385,7 @@
 tabbedmenu.admin.pingTargets=Ping\u76EE\u6807
 tabbedmenu.admin.planetConfig=\u914D\u7F6E
 tabbedmenu.admin.planetGroups=\u5B9A\u5236\u7FA4\u7EC4
-tabbedmenu.admin.planetSubscriptions=\u8BA2\u9605
+tabbedmenu.admin.planetGroupSubs=\u8BA2\u9605
 tabbedmenu.admin.userAdmin=\u7528\u6237\u7BA1\u7406
 tabbedmenu.bookmarks=\u4E66\u7B7E
 tabbedmenu.bookmarks.allFolders=\u4E66\u7B7E\u5939
diff --git a/app/src/main/resources/org/apache/roller/weblogger/ui/struts2/admin/admin-menu.xml b/app/src/main/resources/org/apache/roller/weblogger/ui/struts2/admin/admin-menu.xml
index d090bdc..2e18a81 100644
--- a/app/src/main/resources/org/apache/roller/weblogger/ui/struts2/admin/admin-menu.xml
+++ b/app/src/main/resources/org/apache/roller/weblogger/ui/struts2/admin/admin-menu.xml
@@ -42,8 +42,8 @@
                    name="tabbedmenu.admin.planetConfig" />
         
         <!-- globalPerms="admin" -->
-        <menu-item action="planetSubscriptions"
-                   name="tabbedmenu.admin.planetSubscriptions" />
+        <menu-item action="planetGroupSubs"
+                   name="tabbedmenu.admin.planetGroupSubs" />
         
         <!-- globalPerms="admin" -->
         <menu-item action="planetGroups"
diff --git a/app/src/main/resources/struts.xml b/app/src/main/resources/struts.xml
index 3f302f1..a8ed5cc 100644
--- a/app/src/main/resources/struts.xml
+++ b/app/src/main/resources/struts.xml
@@ -286,14 +286,15 @@
             <result name="input" type="tiles">.PlanetConfig</result>
         </action>
         
-        <action name="planetSubscriptions"
-                class="org.apache.roller.weblogger.planet.ui.PlanetSubscriptions">
-            <result name="list" type="tiles">.PlanetSubscriptions</result>
+        <action name="planetGroupSubs"
+                class="org.apache.roller.weblogger.planet.ui.PlanetGroupSubs">
+            <result name="list" type="tiles">.PlanetGroupSubs</result>
         </action>
         
         <action name="planetGroups"
                 class="org.apache.roller.weblogger.planet.ui.PlanetGroups">
-            <result name="list" type="tiles">.PlanetGroups</result>
+            <result name="groups_list" type="tiles">.PlanetGroups</result>
+            <result name="subscriptions_list" type="tiles">.PlanetGroupSubs</result>
         </action>
     </package>
     
diff --git a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetConfig.jsp b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetConfig.jsp
index c9a6607..936a426 100644
--- a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetConfig.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetConfig.jsp
@@ -19,67 +19,55 @@
 <%@ include file="/WEB-INF/jsps/taglibs-struts2.jsp" %>
 
 
-<p class="subtitle"><s:text name="planetConfig.subtitle" /></a>
-<p><s:text name="planetConfig.prompt" /></a>
+<p class="subtitle"><s:text name="planetConfig.subtitle"/></p>
+<p><s:text name="planetConfig.prompt"/></p>
 
-<s:form action="planetConfig!save">
-	<s:hidden name="salt" />
 
-    <table class="formtableNoDesc">
-    
+<s:form action="planetConfig!save" theme="bootstrap" cssClass="form-horizontal">
+    <s:hidden name="salt"/>
+
     <s:iterator var="dg" value="globalConfigDef.displayGroups">
-    
-        <tr>
-            <td colspan="3"><h2><s:text name="%{#dg.key}" /></h2></td>
-        </tr>
-    
+
+        <h2><s:text name="%{#dg.key}"/></h2>
+
         <s:iterator var="pd" value="#dg.propertyDefs">
-            
-            <tr>
-                <td class="label"><s:text name="%{#pd.key}" /></td>
-              
-                  <%-- "string" type means use a simple textbox --%>
-                  <s:if test="#pd.type == 'string'">
-                    <td class="field"><input type="text" name='<s:property value="#pd.name"/>' value='<s:property value="properties[#pd.name].value"/>' size="35" /></td>
-                  </s:if>
-                  
-                  <%-- "text" type means use a full textarea --%>
-                  <s:elseif test="#pd.type == 'text'">
-                    <td class="field">
-                      <textarea name='<s:property value="#pd.name"/>' rows="<s:property value="#pd.rows"/>" cols="<s:property value="#pd.cols"/>"><s:property value="properties[#pd.name].value"/></textarea>
-                    </td>
-                  </s:elseif>
-                  
-                  <%-- "boolean" type means use a checkbox --%>
-                  <s:elseif test="#pd.type == 'boolean'">
-                      <s:if test="properties[#pd.name].value == 'true'">
-                          <td class="field"><input type="checkbox" name='<s:property value="#pd.name"/>' CHECKED></td>
-                      </s:if>
-                      <s:else>
-                          <td class="field"><input type="checkbox" name='<s:property value="#pd.name"/>'></td>
-                      </s:else>
-                  </s:elseif>
-                  
-                  <%-- if it's something we don't understand then use textbox --%>
-                  <s:else>
-                    <td class="field"><input type="text" name='<s:property value="#pd.name"/>' size="50" /></td>
-                  </s:else>
-                
-                <td class="description"><%-- <s:text name="" /> --%></td>
-            </tr>
-          
+
+            <%-- "string" type means use a simple textbox --%>
+            <s:if test="#pd.type == 'string'">
+                <s:textfield name="%{#pd.name}" label="%{getText(#pd.key)}" size="35"
+                             value="%{properties[#pd.name].value} "/>
+            </s:if>
+
+            <%-- "text" type means use a full textarea --%>
+            <s:elseif test="#pd.type == 'text'">
+                <s:textarea name="%{#pd.name}" label="%{getText(#pd.key)}" rows="#pd.rows" cols="#pd.cols"
+                            value="%{properties[#pd.name].value} "/>
+            </s:elseif>
+
+            <%-- "boolean" type means use a checkbox --%>
+            <s:elseif test="#pd.type == 'boolean'">
+
+                <s:if test="properties[#pd.name].value == 'true'">
+                    <s:checkbox name="%{#pd.name}" label="%{getText(#pd.key)}" cssClass="boolean"
+                                fieldValue="true" checked="true" onchange="formChanged()"/>
+                </s:if>
+                <s:if test="properties[#pd.name].value != 'true'">
+                    <s:checkbox name="%{#pd.name}" label="%{getText(#pd.key)}" cssClass="boolean"
+                                fieldValue="false" onchange="formChanged()"/>
+                </s:if>
+
+            </s:elseif>
+
+            <%-- if it's something we don't understand then use textbox --%>
+            <s:else>
+                <s:textfield name="%{#pd.name}" label="%{getText(#pd.key)}" size="35"
+                             value="%{properties[#pd.name].value}"/>
+            </s:else>
+
         </s:iterator>
-      
-        <tr>
-            <td colspan="2">&nbsp;</td>
-        </tr>
-        
+
     </s:iterator>
 
-    </table>
-    
-    <div class="control">
-        <input class="buttonBox" type="submit" value="<s:text name="generic.save"/>"/>
-    </div>
-    
+     <input class="btn btn-default" type="submit" value="<s:text name="generic.save"/>"/>
+
 </s:form>
diff --git a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSidebar.jsp b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSidebar.jsp
new file mode 100644
index 0000000..8d2a29f
--- /dev/null
+++ b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSidebar.jsp
@@ -0,0 +1,31 @@
+<%--
+  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" %>
+
+
+<%-- ================================================================== --%>
+<%-- add new custom planet group --%>
+
+<s:url var="createNewUrl" action="planetGroupSubs" namespace="/roller-ui/admin">
+    <s:param name="createNew">true</s:param>
+</s:url>
+
+<s:a href="%{createNewUrl}">
+    <span class="glyphicon glyphicon-plus" aria-hidden="true"> </span>
+    Create new Custom Planet Group
+</s:a>
diff --git a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSubs.jsp b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSubs.jsp
new file mode 100644
index 0000000..833d98f
--- /dev/null
+++ b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSubs.jsp
@@ -0,0 +1,155 @@
+<%--
+  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" %>
+
+        
+<%-- ================================================================== --%>
+<%-- add/edit custom planet group form --%>
+
+
+<%-- title for default planet group --%>
+<s:if test="groupHandle == 'all'" >
+    <p class="subtitle"><s:text name="planetGroupSubs.default.subtitle" /></p>
+    <p><s:text name="planetGroupSubs.default.desc" /></p>
+</s:if>
+
+<%-- title for a custom planet group --%>
+<s:else>
+    <p class="subtitle">
+        <s:text name="planetGroupSubs.custom.subtitle" >
+            <s:param value="groupHandle" />
+        </s:text>
+    </p>
+    <p><s:text name="planetGroupSubs.custom.desc" /></p>
+</s:else>
+
+
+<%-- only show edit form for custom group --%>
+<s:if test="groupHandle != 'all'">
+
+    <h3><s:text name="planetGroupSubs.properties"/></h3>
+
+    <s:if test="createNew">
+        <s:text name="planetGroupSubs.creatingNewGroup" />
+    </s:if>
+    <s:else>
+        <s:text name="planetGroupSubs.editingExistingGroup" />
+    </s:else>
+
+    <br/>
+
+    <s:form action="planetGroups!save" theme="bootstrap" cssClass="form-horizontal">
+        <s:hidden name="salt"/>
+        <s:hidden name="bean.id"/>
+
+        <s:textfield name="bean.title" size="40" maxlength="255"
+            onchange="validate()" onkeyup="validate()"
+            label="%{getText('planetGroups.title')}"
+            tooltip="%{getText('planetGroups.tip.title')}"/>
+
+        <s:textfield name="bean.handle" size="40" maxlength="255"
+            onchange="validate()" onkeyup="validate()"
+            label="%{getText('planetGroups.handle')}"
+            tooltip="%{getText('planetGroups.tip.handle')}"/>
+
+
+        <div class="form-group ">
+            <label class="col-sm-3 control-label"></label>
+            <div class="col-sm-9 controls">
+                <s:submit value="%{getText('generic.save')}" cssClass="btn btn-default"/>
+                <input type="button" class="btn"
+                       value='<s:text name="generic.cancel" />'
+                       onclick="window.location='<s:url action="planetGroups"/>'"/>
+            </div>
+        </div>
+
+    </s:form>
+
+</s:if>
+
+
+<%-- ================================================================== --%>
+<%-- table of planet group's subscription  --%>
+
+<s:if test="!createNew">
+
+    <h3><s:text name="planetGroupSubs.subscriptions"/></h3>
+    <s:text name="planetGroupSubs.subscriptionDesc" />
+
+    <s:if test="%{subscriptions.isEmpty()}">
+        <s:if test="groupHandle == 'all'">
+            <s:text name="planetGroupSubs.noneDefinedDefault" />
+        </s:if>
+        <s:else>
+            <s:text name="planetGroupSubs.noneDefinedCustom" />
+        </s:else>
+    </s:if>
+    <s:else>
+
+        <table class="table">
+            <tr>
+                <th width="30%"> <s:text name="planetGroupSubs.column.title"/> </th>
+                <th width="55%"> <s:text name="planetGroupSubs.column.feedUrl"/> </th>
+                <th width="15%"> <s:text name="generic.delete"/> </th>
+            </tr>
+
+            <s:iterator var="sub" value="subscriptions">
+                <tr>
+                    <td class="rollertable"><s:property value="#sub.title"/></td>
+                    <td><s:set var="feedURL" value="#sub.feedURL"/> ${fn:substring(feedURL, 0, 100)} </td>
+                    <td>
+                        <a href="javascript: void(0);" onclick="confirmDelete('<s:property value="feedURL"/>')">
+                            <span class="glyphicon glyphicon-remove" aria-hidden="true"> </span>
+                            <s:text name="generic.delete"/>
+                        </a>
+                    </td>
+                </tr>
+            </s:iterator>
+        </table>
+
+        <%-- planet subscription delete logic --%>
+
+        <s:form action="planetGroupSubs!delete" id="deleteForm">
+            <input type="hidden" name="salt" value='<s:property value="salt" />' />
+            <input type="hidden" name="subUrl"/>
+            <input type="hidden" name="groupHandle"/>
+        </s:form>
+
+    </s:else>
+
+</s:if>
+
+
+<%-- ================================================================== --%>
+
+<script>
+
+    function confirmDelete(subUrl) {
+        if (window.confirm('<s:text name="planetGroupSubs.delete.confirm" />')) {
+            var form = $("#deleteForm");
+            form.find('input[name="subUrl"]').val(subUrl);
+            form.find('input[name="groupHandle"]').val('<s:property value="groupHandle" />');
+            form.submit();
+        }
+    }
+
+    function validateProperties() {
+
+    }
+
+</script>
\ No newline at end of file
diff --git a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSubsSidebar.jsp b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSubsSidebar.jsp
new file mode 100644
index 0000000..578ca58
--- /dev/null
+++ b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroupSubsSidebar.jsp
@@ -0,0 +1,50 @@
+<%--
+  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" %>
+
+
+<%-- ================================================================== --%>
+<%-- add new planet feed subscription --%>
+
+<s:if test="!createNew">
+
+    <s:text name="planetGroupSubs.addFeed"/>
+
+    <s:form action="planetGroupSubs!save" theme="bootstrap" cssClass="form-horizontal">
+        <s:hidden name="salt"/>
+        <s:hidden name="groupHandle"/>
+        <s:textfield name="subUrl" size="40" maxlength="255" label="%{getText('planetSubscription.feedUrl')}"/>
+        <s:submit value="%{getText('generic.save')}" cssClass="btn btn-default" />
+    </s:form>
+
+</s:if>
+
+<%-- ================================================================== --%>
+
+<script>
+
+    function isValidUrl(url) {
+        return /^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i.test(url);
+    }
+
+    function validateUrl() {
+
+    }
+
+</script>
+
diff --git a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroups.jsp b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroups.jsp
index f518ac6..b84503c 100644
--- a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroups.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetGroups.jsp
@@ -17,109 +17,69 @@
 --%>
 <%@ include file="/WEB-INF/jsps/taglibs-struts2.jsp" %>
 
-<p class="subtitle"><s:text name="planetGroups.subtitle" /></p>
+<p class="subtitle"><s:text name="planetGroups.subtitle"/></p>
 
-<p>
-    <s:if test="group == null" >
-        <s:text name="planetGroups.prompt.add" />
-    </s:if>
-    <s:else>
-        <s:text name="planetGroups.prompt.edit" />
-    </s:else>
-</p>
 
-<s:form action="planetGroups!save">
-	<s:hidden name="salt" />
-    <s:hidden name="bean.id" />
-    
-    <div class="formrow">
-        <label for="bean.title" class="formrow" /><s:text name="planetGroups.title" /></label>
-        <s:textfield name="bean.title" size="40" maxlength="255" />
-        <img src="<s:url value="/images/help.png"/>" alt="help" title='<s:text name="planetGroups.tip.title" />' />
-    </div>
-    
-    <div class="formrow">
-        <label for="bean.handle" class="formrow" /><s:text name="planetGroups.handle" /></label>
-        <s:textfield name="bean.handle" size="40" maxlength="255" />
-        <img src="<s:url value="/images/help.png"/>" alt="help" title='<s:text name="planetGroups.tip.handle" />' />
-    </div>
-    
-    <p />
-    
-    <div class="formrow">
-        <label class="formrow" />&nbsp;</label>
-        <s:submit value="%{getText('generic.save')}" />
-        &nbsp;
-        <input type="button" 
-               value='<s:text name="generic.cancel" />'
-               onclick="window.location='<s:url action="planetGroups"/>'"/>
-        
-        <s:if test="group != null" >
-            &nbsp;&nbsp;
-            <s:url var="deleteUrl" action="planetGroups!delete">
-                <s:param name="bean.id" value="%{bean.id}" />
-            </s:url>
-            <input type="button" 
-                   value='<s:text name="generic.delete" />'
-                   onclick="window.location='<s:property value="%{deleteUrl}"/>'" />
-        </s:if>
-    </div>
-    
-</s:form>
+<%-- ================================================================== --%>
+<%-- table of custom planet groups (excluding the default group) --%>
 
-<br style="clear:left" />
+<s:if test="%{!groups.isEmpty()}">
 
-<h2><s:text name="planetGroups.existingTitle" /></h2>
-<p><i><s:text name="planetGroups.existingPrompt" /></i></p>
+    <table class="table">
 
-<table class="rollertable">
-<tr class="rHeaderTr">
-    <th class="rollertable" width="30%">
-        <s:text name="planetGroups.column.title" />
-    </th>
-    <th class="rollertable" width="50%">
-        <s:text name="planetGroups.column.handle" />
-    </th>
-    <th class="rollertable" width="10%">
-        <s:text name="generic.edit" />
-    </th>
-    <th class="rollertable" width="10%">
-        <s:text name="planetGroups.column.subscriptions" />
-    </th>
-</tr>
+        <tr>
+            <th width="50%"> <s:text name="planetGroups.column.title"/> </th>
+            <th width="20%"> <s:text name="planetGroups.column.handle"/> </th>
+            <th width="15%"> <s:text name="generic.edit"/> </th>
+            <th width="15%"> <s:text name="generic.delete"/> </th>
+        </tr>
 
-<s:iterator var="group" value="groups" status="rowstatus">
-    <s:if test="#rowstatus.odd == true">
-        <tr class="rollertable_odd">
-    </s:if>
-    <s:else>
-        <tr class="rollertable_even">
-    </s:else>
-    
-    <td class="rollertable">
-        <s:property value="#group.title" />
-    </td>
-    
-    <td class="rollertable">
-        <s:property value="#group.handle" />
-    </td>
-    
-    <td class="rollertable">
-        <s:url var="groupUrl" action="planetGroups">
-            <s:param name="bean.id" value="#group.id" />
-        </s:url>
-        <s:a href="%{groupUrl}"><img src='<s:url value="/images/page_white_edit.png"/>' border="0" alt="icon" 
-                                     title="<s:text name='planetGroups.edit.tip' />" /></s:a>
-    </td>       
-    
-    <td class="rollertable">
-        <s:url var="subUrl" action="planetSubscriptions">
-            <s:param name="groupHandle" value="#group.handle" />
-        </s:url>
-        <s:a href="%{subUrl}"><img src='<s:url value="/images/page_white_edit.png"/>' border="0" alt="icon" 
-                                   title="<s:text name='planetGroups.subscriptions.tip' />" /></s:a>
-    </td>       
-    
-    </tr>
-</s:iterator>
-</table>
+        <s:iterator var="group" value="groups">
+            <tr>
+                <td> <s:property value="#group.title"/> </td>
+                <td> <s:property value="#group.handle"/> </td>
+
+                <td>
+                    <s:url var="groupUrl" action="planetGroupSubs">
+                        <s:param name="bean.id" value="#group.id"/>
+                    </s:url>
+                    <s:a href="%{groupUrl}">
+                        <span class="glyphicon glyphicon-edit" aria-hidden="true"></span>
+                        <s:text name='generic.edit'/>
+                    </s:a>
+                </td>
+
+                <td>
+                    <a href="javascript: void(0);" onclick="confirmDelete('<s:property value="#group.handle"/>')">
+                        <span class="glyphicon glyphicon-remove" aria-hidden="true"> </span>
+                        <s:text name="generic.delete"/>
+                    </a>
+                </td>
+
+            </tr>
+        </s:iterator>
+
+    </table>
+
+    <%-- planet group delete logic --%>
+
+    <s:form action="planetGroups!delete" id="deleteForm">
+        <input type="hidden" name="salt" value='<s:property value="salt" />' />
+        <input type="hidden" name="bean.handle"/>
+    </s:form>
+
+    <script>
+        function confirmDelete(groupHandle) {
+            if (window.confirm('<s:text name="planetGroups.delete.confirm" />')) {
+                var form = $("#deleteForm");
+                form.find('input[name="bean.handle"]').val(groupHandle);
+                form.submit();
+            }
+        }
+    </script>
+
+</s:if>
+<s:else>
+    <s:text name="planetGroups.noneDefined"/>
+</s:else>
+
diff --git a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetSubscriptions.jsp b/app/src/main/webapp/WEB-INF/jsps/admin/PlanetSubscriptions.jsp
deleted file mode 100644
index 32b9e41..0000000
--- a/app/src/main/webapp/WEB-INF/jsps/admin/PlanetSubscriptions.jsp
+++ /dev/null
@@ -1,101 +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" %>
-
-<script>
-function confirmSubDelete(subUrl) {
-  if (window.confirm('Are you sure you want to remove this subscription?')) {
-    document.location.href='<s:url action="planetSubscriptions!delete" />?groupHandle=<s:property value="groupHandle"/>&subUrl='+encodeURIComponent(subUrl);
-  }
-}
-</script>
-        
-      
-<s:if test="groupHandle == 'all'" >
-    <p class="subtitle"><s:text name="planetSubscriptions.subtitle.addMain" /></p>
-    <p><s:text name="planetSubscriptions.prompt.addMain" /></p>
-</s:if>
-<s:else>
-    <p class="subtitle">
-        <s:text name="planetSubscriptions.subtitle.add" >
-            <s:param value="groupHandle" />
-        </s:text>
-    </p>
-    <p><s:text name="planetSubscriptions.prompt.add" /></p>
-</s:else>
-
-
-<s:form action="planetSubscriptions!save">
-	<s:hidden name="salt" />
-    <s:hidden name="groupHandle" />
-    
-    <div class="formrow">
-        <label for="feedURL" class="formrow" /><s:text name="planetSubscription.feedUrl" /></label>
-        <s:textfield name="subUrl" size="40" maxlength="255" />
-        &nbsp;<s:submit value="%{getText('generic.save')}" />
-    </div>
-</s:form>
-
-<br style="clear:left" />
-
-<h2>
-    <s:text name="planetSubscriptions.existingTitle" />
-    <s:if test="groupHandle != 'all'" >
-        &nbsp;[group: <s:property value="groupHandle" />]
-    </s:if>
-</h2>
-
-<table class="rollertable">
-    <tr class="rHeaderTr">
-        <th class="rollertable" width="30%">
-            <s:text name="planetSubscriptions.column.title" />
-        </th>
-        <th class="rollertable" width="60%">
-            <s:text name="planetSubscriptions.column.feedUrl" />
-        </th>
-        <th class="rollertable" width="10%">
-            <s:text name="generic.delete" />
-        </th>
-    </tr>
-    <s:iterator var="sub" value="subscriptions" status="rowstatus">
-        <s:if test="#rowstatus.odd == true">
-            <tr class="rollertable_odd">
-        </s:if>
-        <s:else>
-            <tr class="rollertable_even">
-        </s:else>
-        
-        <td class="rollertable">
-            <s:property value="#sub.title" />
-        </td>
-        
-        <td class="rollertable">
-            <s:set var="feedURL" value="#sub.feedURL" />
-            ${fn:substring(feedURL, 0, 100)}
-        </td>
-        
-        <td class="rollertable">
-            <img src='<s:url value="/images/delete.png"/>' />
-            <a href="javascript: void(0);" onclick="confirmSubDelete('<s:property value="feedURL"/>')">
-                <s:text name="generic.delete"/>
-            </a>
-        </td>       
-        
-        </tr>
-    </s:iterator>
-</table>
diff --git a/app/src/main/webapp/WEB-INF/jsps/core/MainMenuSidebar.jsp b/app/src/main/webapp/WEB-INF/jsps/core/MainMenuSidebar.jsp
index ba13272..29cbb23 100644
--- a/app/src/main/webapp/WEB-INF/jsps/core/MainMenuSidebar.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/core/MainMenuSidebar.jsp
@@ -58,13 +58,6 @@
                     <a href="<s:url action="globalConfig" namespace="/roller-ui/admin" />"><s:text name="yourWebsites.globalAdmin" /></a></h4>          
                     <p><s:text name="yourWebsites.globalAdmin.desc" /></p>
 
-                    <%-- Planet settings --%>
-                    
-                    <s:if test="getBooleanProp('planet.aggregator.enabled')">
-                        <h4><span class="glyphicon glyphicon-globe" aria-hidden="true"></span>
-                        <a href="<s:url action="planetConfig" namespace="/roller-ui/admin" />"><s:text name="yourWebsites.planetAdmin" /></a></h4>
-                        <p><s:text name="yourWebsites.planetAdmin.desc" /></p>
-                    </s:if>
                 </s:if>
                 
                 <br />
diff --git a/app/src/main/webapp/WEB-INF/jsps/editor/Bookmarks.jsp b/app/src/main/webapp/WEB-INF/jsps/editor/Bookmarks.jsp
index a68ffd1..0fe20f2 100644
--- a/app/src/main/webapp/WEB-INF/jsps/editor/Bookmarks.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/editor/Bookmarks.jsp
@@ -791,11 +791,7 @@
     }
 
     function isValidUrl(url) {
-        if (/^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i.test(url)) {
-            return true;
-        } else {
-            return false;
-        }
+        return /^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i.test(url);
     }
 
     function saveBookmark() {
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/bannerStatus.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/bannerStatus.jsp
index f3b3c28..4af4c2e 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/bannerStatus.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/bannerStatus.jsp
@@ -52,6 +52,7 @@
 
                     <s:set var="tabMenu" value="menu"/>
                     <s:if test="#tabMenu != null">
+
                         <s:iterator var="tab" value="#tabMenu.tabs">
                             <li class="dropdown">
                                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
@@ -70,6 +71,7 @@
                                 </ul>
                             </li>
                         </s:iterator>
+
                     </s:if>
                     
                 </s:if>
@@ -78,6 +80,7 @@
 
                     <s:set var="tabMenu" value="menu"/>
                     <s:if test="#tabMenu != null">
+
                         <s:iterator var="tab" value="#tabMenu.tabs">
                             <li class="dropdown">
                                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
@@ -95,6 +98,7 @@
                                 </ul>
                             </li>
                         </s:iterator>
+
                     </s:if>
 
                 </s:if>
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-errorpage.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-errorpage.jsp
index 12ecdc6..6b46c64 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-errorpage.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-errorpage.jsp
@@ -31,7 +31,7 @@
             <tiles:insertAttribute name="banner" />
         </div>
         
-        <div id="wrapper"> 
+        <div id="wrapper" class="container">
             <div id="leftcontent_wrap">
                 <div id="leftcontent"> 
                 </div>
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-installpage.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-installpage.jsp
index 879097e..dfb5bcd 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-installpage.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-installpage.jsp
@@ -31,7 +31,7 @@
             <tiles:insertAttribute name="banner" />
         </div>
         
-        <div id="wrapper"> 
+        <div id="wrapper" class="container">
             <div id="leftcontent_wrap">
                 <div id="leftcontent"> 
                 </div>
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-loginpage.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-loginpage.jsp
index 83a5022..e9d503f 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-loginpage.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-loginpage.jsp
@@ -32,16 +32,19 @@
 <tiles:insertAttribute name="banner"/>
 <tiles:insertAttribute name="bannerStatus"/>
 
-<div class="row">
-    <div class="col-md-4"></div>
+<div class="container">
 
-    <div class="col-md-4">
-        <h1 class="roller-page-title"><s:property value="pageTitle"/></h1>
-        <tiles:insertAttribute name="messages"/>
-        <tiles:insertAttribute name="content"/>
+    <div class="row">
+        <div class="col-md-4"></div>
+
+        <div class="col-md-4">
+            <h1 class="roller-page-title"><s:property value="pageTitle"/></h1>
+            <tiles:insertAttribute name="messages"/>
+            <tiles:insertAttribute name="content"/>
+        </div>
+
+        <div class="col-md-4"></div>
     </div>
-
-    <div class="col-md-4"></div>
 </div>
 
 </body>
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-mainmenupage.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-mainmenupage.jsp
index 0c89f15..939bbef 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-mainmenupage.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-mainmenupage.jsp
@@ -33,26 +33,29 @@
 
 <tiles:insertAttribute name="bannerStatus"/>
 
-<div class="row">
-    
-    <div class="col-md-3 roller-column-left">
-        <div class="panel panel-default">
-            <div class="panel-body">
-                <tiles:insertAttribute name="sidebar"/>
-            </div>
-        </div>
-    </div>
-    
-    <div class="col-md-9 roller-column-right">
+<div class="container">
 
-        <div class="panel panel-default">
-            <div class="panel-body">
-                <h2 class="roller-page-title"><s:property value="pageTitle"/></h2>
-                <tiles:insertAttribute name="messages"/>
-                <tiles:insertAttribute name="content"/>
+    <div class="row">
+
+        <div class="col-md-3 roller-column-left">
+            <div class="panel panel-default">
+                <div class="panel-body">
+                    <tiles:insertAttribute name="sidebar"/>
+                </div>
             </div>
         </div>
 
+        <div class="col-md-9 roller-column-right">
+
+            <div class="panel panel-default">
+                <div class="panel-body">
+                    <h2 class="roller-page-title"><s:property value="pageTitle"/></h2>
+                    <tiles:insertAttribute name="messages"/>
+                    <tiles:insertAttribute name="content"/>
+                </div>
+            </div>
+
+        </div>
     </div>
 </div>
 
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-popuppage.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-popuppage.jsp
index 91300e3..1455f3d 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-popuppage.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-popuppage.jsp
@@ -27,7 +27,7 @@
 

     <body>

 

-        <div id="wrapper"> 

+        <div id="wrapper" class="container">

             <div id="leftcontent_wrap">

                 <div id="leftcontent"> 

                 </div>

diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-simple-tabbedpage.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-simple-tabbedpage.jsp
index a2bff81..4b7197b 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-simple-tabbedpage.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-simple-tabbedpage.jsp
@@ -30,13 +30,16 @@
 
 <tiles:insertAttribute name="bannerStatus"/>
 
-<div class="row">
-    <div class="col-md-12 roller-column-left">
-        <div class="panel panel-default">
-            <div class="panel-body">
-                <tiles:insertAttribute name="messages"/>
-                <h2 class="roller-page-title"><s:property value="pageTitle"/></h2>
-                <tiles:insertAttribute name="content"/>
+<div class="container">
+
+    <div class="row">
+        <div class="col-md-12 roller-column-left">
+            <div class="panel panel-default">
+                <div class="panel-body">
+                    <tiles:insertAttribute name="messages"/>
+                    <h2 class="roller-page-title"><s:property value="pageTitle"/></h2>
+                    <tiles:insertAttribute name="content"/>
+                </div>
             </div>
         </div>
     </div>
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-simplepage.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-simplepage.jsp
index 21a1d8b..cd11777 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-simplepage.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-simplepage.jsp
@@ -32,20 +32,23 @@
 <tiles:insertAttribute name="banner"/>
 <tiles:insertAttribute name="bannerStatus"/>
 
-<div class="row">
-    <div class="col-md-2"></div>
+<div class="container">
 
-    <div class="col-md-8">
-        <h1 class="roller-page-title"><s:property value="pageTitle"/></h1>
-        <tiles:insertAttribute name="messages"/>
-        <div class="panel">
-            <div class="panel-body">
-                <tiles:insertAttribute name="content"/>
+    <div class="row">
+        <div class="col-md-2"></div>
+
+        <div class="col-md-8">
+            <h1 class="roller-page-title"><s:property value="pageTitle"/></h1>
+            <tiles:insertAttribute name="messages"/>
+            <div class="panel">
+                <div class="panel-body">
+                    <tiles:insertAttribute name="content"/>
+                </div>
             </div>
         </div>
-    </div>
 
-    <div class="col-md-2"></div>
+        <div class="col-md-2"></div>
+    </div>
 </div>
 
 </body>
diff --git a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-tabbedpage.jsp b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-tabbedpage.jsp
index 6bd6ca2..9ac335b 100644
--- a/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-tabbedpage.jsp
+++ b/app/src/main/webapp/WEB-INF/jsps/tiles/tiles-tabbedpage.jsp
@@ -29,40 +29,43 @@
 </head>
 <body>
 
-<tiles:insertAttribute name="bannerStatus" />
+<tiles:insertAttribute name="bannerStatus"/>
 
-<tilesx:useAttribute name="sidebar" id="sidebar" classname="java.lang.String" />
+<tilesx:useAttribute name="sidebar" id="sidebar" classname="java.lang.String"/>
 
+<div class="container">
 
-<div class="row">
+    <div class="row">
 
-    <div class="col-md-8 roller-column-left">
-        <div class="panel panel-default">
-            <div class="panel-body">
-                <tiles:insertAttribute name="messages"/>
-                <h2 class="roller-page-title"><s:property value="pageTitle"/></h2>
-                <tiles:insertAttribute name="content"/>
-            </div>
-        </div>
-    </div>
-
-    <div class="col-md-4 roller-column-right">
-        <div class="panel panel-default">
-            <div class="panel-body">
-                <s:if test="authenticatedUser != null || actionWeblog != null">
-                    <tiles:insertAttribute name="userStatus"/>
-                </s:if>
-            </div>
-        </div>
-
-        <c:if test="${sidebar != '/WEB-INF/jsps/tiles/empty.jsp'}">
-            <s:property value="sidebar" />
+        <div class="col-md-8 roller-column-left">
             <div class="panel panel-default">
-                <div class="panel-body">
-                    <tiles:insertAttribute name="sidebar"/>
+                <div class="panel-body" style="min-height: 30em">
+                    <tiles:insertAttribute name="messages"/>
+                    <h2 class="roller-page-title"><s:property value="pageTitle"/></h2>
+                    <tiles:insertAttribute name="content"/>
                 </div>
             </div>
-        </c:if>
+        </div>
+
+        <div class="col-md-4 roller-column-right">
+            <div class="panel panel-default">
+                <div class="panel-body">
+                    <s:if test="authenticatedUser != null || actionWeblog != null">
+                        <tiles:insertAttribute name="userStatus"/>
+                    </s:if>
+                </div>
+            </div>
+
+            <c:if test="${sidebar != '/WEB-INF/jsps/tiles/empty.jsp'}">
+                <s:property value="sidebar"/>
+                <div class="panel panel-default">
+                    <div class="panel-body">
+                        <tiles:insertAttribute name="sidebar"/>
+                    </div>
+                </div>
+            </c:if>
+
+        </div>
 
     </div>
 
diff --git a/app/src/main/webapp/WEB-INF/tiles.xml b/app/src/main/webapp/WEB-INF/tiles.xml
index 1968f67..4f38a19 100644
--- a/app/src/main/webapp/WEB-INF/tiles.xml
+++ b/app/src/main/webapp/WEB-INF/tiles.xml
@@ -204,12 +204,14 @@
         <put-attribute name="content" value="/WEB-INF/jsps/admin/PlanetConfig.jsp" />
     </definition>
     
-    <definition name=".PlanetSubscriptions" extends=".tiles-tabbedpage" >
-        <put-attribute name="content" value="/WEB-INF/jsps/admin/PlanetSubscriptions.jsp" />
+    <definition name=".PlanetGroupSubs" extends=".tiles-tabbedpage" >
+        <put-attribute name="content" value="/WEB-INF/jsps/admin/PlanetGroupSubs.jsp" />
+        <put-attribute name="sidebar" value="/WEB-INF/jsps/admin/PlanetGroupSubsSidebar.jsp" />
     </definition>
     
     <definition name=".PlanetGroups" extends=".tiles-tabbedpage" >
         <put-attribute name="content" value="/WEB-INF/jsps/admin/PlanetGroups.jsp" />
+        <put-attribute name="sidebar" value="/WEB-INF/jsps/admin/PlanetGroupSidebar.jsp" />
     </definition>
 
     <!-- weblog editor pages (and associates) -->
diff --git a/app/src/main/webapp/roller-ui/styles/roller.css b/app/src/main/webapp/roller-ui/styles/roller.css
index 8c8a5fd..fd9a8a5 100644
--- a/app/src/main/webapp/roller-ui/styles/roller.css
+++ b/app/src/main/webapp/roller-ui/styles/roller.css
@@ -22,6 +22,10 @@
     border:0;
 }
 
+.container {
+    margin: 1em;
+}
+
 .roller-page-title {
     margin-top: 0px;
     margin-bottom: 5px;
@@ -292,7 +296,6 @@
 }
 
 
-
 /* theme edit */
 
 .row-display-flex {