]> source.dussan.org Git - gitblit.git/commitdiff
RSS syndication feature. Documentation. CSS tweaks.
authorJames Moger <james.moger@gitblit.com>
Sat, 11 Jun 2011 20:23:49 +0000 (16:23 -0400)
committerJames Moger <james.moger@gitblit.com>
Sat, 11 Jun 2011 20:23:49 +0000 (16:23 -0400)
20 files changed:
NOTICE
distrib/gitblit.properties
docs/00_index.mkd
docs/00_setup.mkd
docs/01_faq.mkd
src/com/gitblit/Build.java
src/com/gitblit/Constants.java
src/com/gitblit/DownloadZipServlet.java
src/com/gitblit/GitBlitServer.java
src/com/gitblit/JettyLoginService.java
src/com/gitblit/SyndicationServlet.java [new file with mode: 0644]
src/com/gitblit/utils/SyndicationUtils.java [new file with mode: 0644]
src/com/gitblit/wicket/GitBlitWebApp.properties
src/com/gitblit/wicket/pages/MetricsPage.java
src/com/gitblit/wicket/pages/RepositoryPage.html
src/com/gitblit/wicket/pages/RepositoryPage.java
src/com/gitblit/wicket/panels/BranchesPanel.html
src/com/gitblit/wicket/panels/BranchesPanel.java
src/com/gitblit/wicket/resources/feed_16x16.png [new file with mode: 0644]
src/com/gitblit/wicket/resources/gitblit.css

diff --git a/NOTICE b/NOTICE
index d58975a3a71801e3448ea33b89dad31a855071bd..b45f30b8bd5157036dc29f6f6afc082bcd247a0d 100644 (file)
--- a/NOTICE
+++ b/NOTICE
@@ -95,6 +95,22 @@ JSch
 \r
    http://www.jcraft.com/jsch\r
 \r
+---------------------------------------------------------------------------\r
+Rome\r
+---------------------------------------------------------------------------\r
+   Rome RSS and Atom Java Utilities, released under the\r
+   Apache Software License, Version 1.1.\r
+\r
+   http://rome.dev.java.net\r
+\r
+---------------------------------------------------------------------------\r
+jdom\r
+---------------------------------------------------------------------------\r
+   jdom xml library, released under the\r
+   Apache-style Software License.\r
+\r
+   http://www.jdom.org\r
+\r
 ---------------------------------------------------------------------------\r
 JUnit\r
 ---------------------------------------------------------------------------\r
index 5c6603a02c985fa1e063b109f1a9ebad3029b327..2d55a5840cdc7eb0a0b4b32779d5c06b62f86025 100644 (file)
@@ -64,6 +64,9 @@ web.allowAdministration = true
 # Allow dyanamic zip downloads.   \r
 web.allowZipDownloads = true\r
 \r
+# Default number of entries to include in RSS/Atom Syndication links\r
+web.syndicationEntries = 25\r
+\r
 # This is the message display above the repositories table.\r
 # This can point to a file with Markdown content.\r
 # Specifying "gitblit" uses the internal welcome message.\r
index fbd736a2172b8c2923371e5352f1e1875664a6c1..f84773ebba9f6d7741b093cc0814d15d14a2f5bc 100644 (file)
@@ -32,6 +32,7 @@ sources @ [Github][gitbltsrc]
 - Automatically generates a self-signed certificate for https communications\r
 - Git-notes support\r
 - Branch metrics (uses Google Charts)\r
+- HEAD and branch RSS feeds\r
 - Blame annotations view\r
 - Dates can optionally be displayed using the browser's reported timezone\r
 - Display of Author and Committer email addresses can be disabled\r
@@ -60,6 +61,7 @@ sources @ [Github][gitbltsrc]
 - Gitblit may have security holes.  Patches welcome.  :)\r
 \r
 ### Todo List\r
+- Custom BASIC authentication servlet or servlet filter\r
 - Code documentation\r
 - Unit testing\r
 - Update Build.java to JGit 1.0.0, when its released\r
@@ -110,6 +112,8 @@ The following dependencies are automatically downloaded from the Apache Maven re
 - [JCommander](http://jcommander.org) (Apache 2.0)\r
 - [BouncyCastle](http://www.bouncycastle.org) (MIT/X11)\r
 - [JSch - Java Secure Channel](http://www.jcraft.com/jsch) (BSD)\r
+- [Rome](http://rome.dev.java.net) (Apache 1.1)\r
+- [jdom](http://www.jdom.org) (Apache-style JDOM license)\r
 \r
 ### Other Build Dependencies\r
 - [Fancybox image viewer](http://fancybox.net) (MIT and GPL dual-licensed)\r
index fc2fd852c3c7ed2a34cd7b08ed9e539d1e4cb1ae..ccf38b830e8f66c0f8afc8b251d0c76817ee9ef6 100644 (file)
@@ -91,7 +91,7 @@ You must tell Git not to verify the self-signed certificate in order to perform
     3. <pre>Key = *http.sslVerify*       \r
        Value = *false*</pre>\r
 - Command-line Git ([Git-Config Manual Page](http://www.kernel.org/pub/software/scm/git/docs/git-config.html))\r
-    <pre>git-config --global --bool --add http.sslVerify false</pre>\r
+    <pre>git config --global --bool --add http.sslVerify false</pre>\r
 \r
 ### Cloning an Access Restricted Repository \r
 - Eclipse/Egit<br/>Nothing special to configure, EGit figures out everything.\r
index e6760ced1dc2c2f1985493a604449a7c10023963..3605387ab3007370b3eb44539f257d78dde757c1 100644 (file)
@@ -100,5 +100,4 @@ Yes.  Most messages are localized to a standard Java properties file.
 [jgit]: http://eclipse.org/jgit "Eclipse JGit Site"\r
 [git]: http://git-scm.com "Official Git Site"\r
 [mina]: http://mina.apache.org "Apache Mina"\r
-[bouncycastle]: http://bouncycastle.org "The Legion of the Bouncy Castle"\r
-[hg4j]: http://code.google.com/p/hg4j/ "hg4j"
\ No newline at end of file
+[bouncycastle]: http://bouncycastle.org "The Legion of the Bouncy Castle"
\ No newline at end of file
index a98169e51d76baa1d821a3212eb80077c2833d29..30c4aa00a0f001541b3cdd1e983e5e04ed640888 100644 (file)
@@ -61,6 +61,8 @@ public class Build {
                downloadFromApache(MavenObject.BOUNCYCASTLE, BuildType.RUNTIME);\r
                downloadFromApache(MavenObject.BOUNCYCASTLE_MAIL, BuildType.RUNTIME);\r
                downloadFromApache(MavenObject.JSCH, BuildType.RUNTIME);\r
+               downloadFromApache(MavenObject.ROME, BuildType.RUNTIME);\r
+               downloadFromApache(MavenObject.JDOM, BuildType.RUNTIME);\r
 \r
                downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME);\r
                downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.RUNTIME);\r
@@ -82,7 +84,9 @@ public class Build {
                downloadFromApache(MavenObject.BOUNCYCASTLE, BuildType.COMPILETIME);\r
                downloadFromApache(MavenObject.BOUNCYCASTLE_MAIL, BuildType.COMPILETIME);\r
                downloadFromApache(MavenObject.JSCH, BuildType.COMPILETIME);\r
-\r
+               downloadFromApache(MavenObject.ROME, BuildType.COMPILETIME);\r
+               downloadFromApache(MavenObject.JDOM, BuildType.COMPILETIME);\r
+               \r
                downloadFromEclipse(MavenObject.JGIT, BuildType.COMPILETIME);\r
                downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.COMPILETIME);\r
                \r
@@ -401,6 +405,16 @@ public class Build {
                                "1.4.0", 181000, 0, 0, "eb47e8cad2dd7f92fd7e77df1d1529cae87361f7",\r
                                "",\r
                                "");\r
+               \r
+               public static final MavenObject ROME = new MavenObject("rome", "rome", "rome",\r
+                               "0.9", 208000, 196000, 407000, "dee2705dd01e79a5a96a17225f5a1ae30470bb18",\r
+                               "226f851dc44fd94fe70b9c471881b71f88949cbf",\r
+                               "8d7d867b97eeb3a9196c3926da550ad042941c1b");\r
+\r
+               public static final MavenObject JDOM = new MavenObject("jdom", "org/jdom", "jdom",\r
+                               "1.1", 153000, 235000, 445000, "1d04c0f321ea337f3661cf7ede8f4c6f653a8fdd",\r
+                               "a7ed425c4c46605b8f2bf2ee118c1609682f4f2c",\r
+                               "f3df91edccba2f07a0fced70887c2f7b7836cb75");\r
 \r
                public final String name;\r
                public final String group;\r
index 55232842ff30ecb57df9337c8e3033e9d849d687..88b13e06b44e8033c69d0754dd93e71cef478c15 100644 (file)
@@ -36,6 +36,8 @@ public class Constants {
        public static final String GIT_SERVLET_PATH = "/git/";\r
 \r
        public static final String ZIP_SERVLET_PATH = "/zip/";\r
+       \r
+       public static final String SYNDICATION_SERVLET_PATH = "/feed/";\r
 \r
        public static final String BORDER = "***********************************************************";\r
 \r
index 86ca4e779d3298894d719f072aed7ddfa0080411..174547462a3a7225fa3f3bbf342961ffa80fba30 100644 (file)
@@ -41,7 +41,10 @@ public class DownloadZipServlet extends HttpServlet {
        }\r
 \r
        public static String asLink(String baseURL, String repository, String objectId, String path) {\r
-               return baseURL + (baseURL.endsWith("/") ? "" : "/") + "zip?r=" + repository\r
+               if (baseURL.charAt(baseURL.length() - 1) == '/') {\r
+                       baseURL = baseURL.substring(0, baseURL.length() - 1);\r
+               }\r
+               return baseURL + Constants.ZIP_SERVLET_PATH + "?r=" + repository\r
                                + (path == null ? "" : ("&p=" + path))\r
                                + (objectId == null ? "" : ("&h=" + objectId));\r
        }\r
index 928bf7e6f37d84ade789c737c5fad288b7675831..2495aeeabc87a1f0a6fc2a2bc41ac2756f1a3bc8 100644 (file)
@@ -240,6 +240,9 @@ public class GitBlitServer {
                // Zip Servlet\r
                rootContext.addServlet(DownloadZipServlet.class, Constants.ZIP_SERVLET_PATH + "*");\r
 \r
+               // Syndication Servlet\r
+               rootContext.addServlet(SyndicationServlet.class, Constants.SYNDICATION_SERVLET_PATH + "*");\r
+\r
                // Git Servlet\r
                ServletHolder gitServlet = null;\r
                String gitServletPathSpec = Constants.GIT_SERVLET_PATH + "*";\r
index 63a986186768c1fd9f9d3be8541b4a43e96cf32f..22f9ce3116d41e4a4fa064dc6b6f6be3aff79d03 100644 (file)
@@ -412,7 +412,7 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi
                FileWriter writer = new FileWriter(realmFileCopy);\r
                properties\r
                                .store(writer,\r
-                                               "# Git:Blit realm file format: username=password,\\#permission,repository1,repository2...");\r
+                                               "# Gitblit realm file format: username=password,\\#permission,repository1,repository2...");\r
                writer.close();\r
                if (realmFileCopy.exists() && realmFileCopy.length() > 0) {\r
                        if (realmFile.delete()) {\r
diff --git a/src/com/gitblit/SyndicationServlet.java b/src/com/gitblit/SyndicationServlet.java
new file mode 100644 (file)
index 0000000..d2b396e
--- /dev/null
@@ -0,0 +1,91 @@
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit;\r
+\r
+import java.util.List;\r
+\r
+import javax.servlet.http.HttpServlet;\r
+\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.revwalk.RevCommit;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.gitblit.models.RepositoryModel;\r
+import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.StringUtils;\r
+import com.gitblit.utils.SyndicationUtils;\r
+\r
+public class SyndicationServlet extends HttpServlet {\r
+\r
+       private static final long serialVersionUID = 1L;\r
+\r
+       private transient Logger logger = LoggerFactory.getLogger(SyndicationServlet.class);\r
+\r
+       public static String asLink(String baseURL, String repository, String objectId, int length) {\r
+               if (baseURL.charAt(baseURL.length() - 1) == '/') {\r
+                       baseURL = baseURL.substring(0, baseURL.length() - 1);\r
+               }\r
+               return baseURL + Constants.SYNDICATION_SERVLET_PATH + "?r=" + repository\r
+                               + (objectId == null ? "" : ("&h=" + objectId)) + (length > 0 ? "&l=" + length : "");\r
+       }\r
+\r
+       private void processRequest(javax.servlet.http.HttpServletRequest request,\r
+                       javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException,\r
+                       java.io.IOException {\r
+               String hostUrl = request.getRequestURL().toString();\r
+               String servlet = request.getServletPath();\r
+               hostUrl = hostUrl.substring(0, hostUrl.indexOf(servlet));\r
+               String repositoryName = request.getParameter("r");\r
+               String objectId = request.getParameter("h");\r
+               String l = request.getParameter("l");\r
+               int length = GitBlit.getInteger(Keys.web.syndicationEntries, 25);\r
+               if (StringUtils.isEmpty(objectId)) {\r
+                       objectId = org.eclipse.jgit.lib.Constants.HEAD;\r
+               }\r
+               if (!StringUtils.isEmpty(l)) {\r
+                       try {\r
+                               length = Integer.parseInt(l);\r
+                       } catch (NumberFormatException x) {\r
+                       }\r
+               }\r
+               \r
+               // TODO confirm repository is accessible!!\r
+\r
+               Repository repository = GitBlit.self().getRepository(repositoryName);\r
+               RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);\r
+               List<RevCommit> commits = JGitUtils.getRevLog(repository, objectId, 0, length);\r
+               try {\r
+                       SyndicationUtils.toRSS(hostUrl, model.name + " " + objectId, model.description, model.name, commits, response.getOutputStream());\r
+               } catch (Exception e) {\r
+                       logger.error("An error occurred during feed generation", e);\r
+               }\r
+       }\r
+\r
+       @Override\r
+       protected void doPost(javax.servlet.http.HttpServletRequest request,\r
+                       javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException,\r
+                       java.io.IOException {\r
+               processRequest(request, response);\r
+       }\r
+\r
+       @Override\r
+       protected void doGet(javax.servlet.http.HttpServletRequest request,\r
+                       javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException,\r
+                       java.io.IOException {\r
+               processRequest(request, response);\r
+       }\r
+}\r
diff --git a/src/com/gitblit/utils/SyndicationUtils.java b/src/com/gitblit/utils/SyndicationUtils.java
new file mode 100644 (file)
index 0000000..da937f9
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.utils;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.io.OutputStreamWriter;\r
+import java.text.MessageFormat;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.jgit.revwalk.RevCommit;\r
+\r
+import com.sun.syndication.feed.synd.SyndContent;\r
+import com.sun.syndication.feed.synd.SyndContentImpl;\r
+import com.sun.syndication.feed.synd.SyndEntry;\r
+import com.sun.syndication.feed.synd.SyndEntryImpl;\r
+import com.sun.syndication.feed.synd.SyndFeed;\r
+import com.sun.syndication.feed.synd.SyndFeedImpl;\r
+import com.sun.syndication.io.FeedException;\r
+import com.sun.syndication.io.SyndFeedOutput;\r
+\r
+public class SyndicationUtils {\r
+\r
+       public static void toRSS(String hostUrl, String title, String description, String repository, List<RevCommit> commits, OutputStream os)\r
+                       throws IOException, FeedException {\r
+\r
+               SyndFeed feed = new SyndFeedImpl();\r
+               feed.setFeedType("rss_1.0");\r
+               feed.setTitle(title);\r
+               feed.setLink(MessageFormat.format("{0}/summary/{1}", hostUrl, repository));\r
+               feed.setDescription(description);\r
+\r
+               List<SyndEntry> entries = new ArrayList<SyndEntry>();\r
+               for (RevCommit commit : commits) {\r
+                       SyndEntry entry = new SyndEntryImpl();\r
+                       entry.setTitle(commit.getShortMessage());\r
+                       entry.setAuthor(commit.getAuthorIdent().getName());\r
+                       entry.setLink(MessageFormat.format("{0}/commit/{1}/{2}", hostUrl, repository, commit.getName()));\r
+                       entry.setPublishedDate(commit.getCommitterIdent().getWhen());\r
+\r
+                       SyndContent content = new SyndContentImpl();\r
+                       content.setType("text/html");\r
+                       String html = StringUtils.escapeForHtml(commit.getFullMessage(), false);\r
+                       content.setValue(StringUtils.breakLinesForHtml(html));\r
+                       entry.setDescription(content);\r
+                       entries.add(entry);\r
+               }\r
+               feed.setEntries(entries);\r
+\r
+               OutputStreamWriter writer = new OutputStreamWriter(os);\r
+               SyndFeedOutput output = new SyndFeedOutput();\r
+               output.output(feed, writer);\r
+               writer.close();\r
+       }\r
+}\r
index d6102dbf2a9f0fd24fa4b3915e08b14c3e92b5a0..50a4ef42d67b0234f48d222706f7c9c11d662169 100644 (file)
@@ -98,4 +98,5 @@ gb.ownerDescription = the owner may edit repository settings
 gb.blob = blob\r
 gb.commitActivityTrend = commit activity trend\r
 gb.commitActivityDOW = commit activity by day of week\r
-gb.commitActivityAuthors = primary authors by commit activity
\ No newline at end of file
+gb.commitActivityAuthors = primary authors by commit activity\r
+gb.feed = feed
\ No newline at end of file
index 4d0cd4cb9ffdfc79c346f62ba6bfaac29d67c11f..461bebec9c9e8a564f55066ebcf415d032c0b4e5 100644 (file)
@@ -134,7 +134,7 @@ public class MetricsPage extends RepositoryPage {
                SimpleDateFormat sdf = new SimpleDateFormat("E");\r
                Calendar cal = Calendar.getInstance();\r
 \r
-               List<Metric> sorted = new ArrayList<Metric>(7);\r
+               List<Metric> sorted = new ArrayList<Metric>();\r
                int firstDayOfWeek = cal.getFirstDayOfWeek();\r
                int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);\r
 \r
@@ -144,7 +144,7 @@ public class MetricsPage extends RepositoryPage {
                        String day = sdf.format(cal.getTime());\r
                        for (Metric metric : list) {\r
                                if (metric.name.equals(day)) {\r
-                                       sorted.add(i, metric);\r
+                                       sorted.add(metric);\r
                                        list.remove(metric);\r
                                        break;\r
                                }\r
index 0e0ce476e9ff494b0deec0acb6b9773f051e5b89..cff7d0686d54aaedc8ee3f6a3386a014cdafdbe2 100644 (file)
@@ -9,15 +9,18 @@
                <!-- page header bar -->        \r
                <div>\r
                        <!-- floating search form on right -->\r
-                       <form wicket:id="searchForm">\r
-                               <div class="search">\r
+                       <div class="search">\r
+                               <form wicket:id="searchForm">\r
                                        <select wicket:id="searchType"/>                        \r
                                        <input type="text" id="searchBox" wicket:id="searchBox" size="25" value=""/>\r
-                               </div>\r
-                       </form>\r
+                               </form>\r
+                       </div>\r
                \r
                        <!-- page nav links -->\r
-                       <div class="page_nav">          \r
+                       <div class="page_nav">\r
+                               <a style="text-decoration: none;" wicket:id="syndication">\r
+                                       <img style="border:0px;vertical-align:middle;" src="/com/gitblit/wicket/resources/feed_16x16.png"></img>\r
+                               </a>                            \r
                                <a wicket:id="summary"><wicket:message key="gb.summary"></wicket:message></a> | <a wicket:id="log"><wicket:message key="gb.log"></wicket:message></a> | <a wicket:id="branches"><wicket:message key="gb.branches"></wicket:message></a> | <a wicket:id="tags"><wicket:message key="gb.tags"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> <span wicket:id="extra"><span wicket:id="extraSeparator"></span><span wicket:id="extraLink"></span></span>\r
                        </div>\r
                </div>\r
index cff59f26acb46de0c1d7902c94e0a17869aa7204..c3a6b03b1f5864d09ba23a4a3f9cb7cb1c0ca1d1 100644 (file)
@@ -30,6 +30,7 @@ import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.StatelessForm;\r
 import org.apache.wicket.markup.html.form.TextField;\r
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.apache.wicket.markup.html.link.ExternalLink;\r
 import org.apache.wicket.markup.html.panel.Fragment;\r
 import org.apache.wicket.markup.repeater.Item;\r
 import org.apache.wicket.markup.repeater.data.DataView;\r
@@ -45,6 +46,7 @@ import org.slf4j.LoggerFactory;
 \r
 import com.gitblit.GitBlit;\r
 import com.gitblit.Keys;\r
+import com.gitblit.SyndicationServlet;\r
 import com.gitblit.models.RepositoryModel;\r
 import com.gitblit.utils.JGitUtils;\r
 import com.gitblit.utils.JGitUtils.SearchType;\r
@@ -157,6 +159,9 @@ public abstract class RepositoryPage extends BasePage {
                        }\r
                };\r
                add(extrasView);\r
+               \r
+               add(new ExternalLink("syndication", SyndicationServlet.asLink(getRequest()\r
+                               .getRelativePathPrefixToContextRoot(), repositoryName, null, 0)));\r
 \r
                // disable current page\r
                disablePageLink(getPageName());\r
index 91c34d2d80ef2c04a04ea25343c2bbb9fc6124bc..7e87067a61fbf030a3768d6090bfd0a6570dc7c1 100644 (file)
@@ -28,7 +28,7 @@
        <!-- branch page links -->\r
        <wicket:fragment wicket:id="branchPageLinks">\r
                <span class="link">\r
-                       <a wicket:id="log"><wicket:message key="gb.log"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | <a wicket:id="metrics"><wicket:message key="gb.metrics"></wicket:message></a>\r
+                       <a wicket:id="log"><wicket:message key="gb.log"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | <a wicket:id="metrics"><wicket:message key="gb.metrics"></wicket:message></a> | <a wicket:id="syndication"><wicket:message key="gb.feed"></wicket:message></a>\r
                </span>\r
        </wicket:fragment>\r
 \r
index b11c03ab39170f4af33074c0b98bc827a08e030e..302b48dd160a83fe62283efdc8862fe8c55ec57f 100644 (file)
@@ -21,6 +21,7 @@ import java.util.List;
 \r
 import org.apache.wicket.markup.html.basic.Label;\r
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.apache.wicket.markup.html.link.ExternalLink;\r
 import org.apache.wicket.markup.html.panel.Fragment;\r
 import org.apache.wicket.markup.repeater.Item;\r
 import org.apache.wicket.markup.repeater.data.DataView;\r
@@ -29,6 +30,7 @@ import org.apache.wicket.model.StringResourceModel;
 import org.eclipse.jgit.lib.Constants;\r
 import org.eclipse.jgit.lib.Repository;\r
 \r
+import com.gitblit.SyndicationServlet;\r
 import com.gitblit.models.RefModel;\r
 import com.gitblit.models.RepositoryModel;\r
 import com.gitblit.utils.JGitUtils;\r
@@ -101,6 +103,8 @@ public class BranchesPanel extends BasePanel {
                                                        .newObjectParameter(model.name, entry.getName())));\r
                                        fragment.add(new BookmarkablePageLink<Void>("metrics", MetricsPage.class,\r
                                                        WicketUtils.newObjectParameter(model.name, entry.getName())));\r
+                                       fragment.add(new ExternalLink("syndication", SyndicationServlet.asLink(getRequest()\r
+                                                       .getRelativePathPrefixToContextRoot(), model.name, entry.getName(), 0)));\r
                                        item.add(fragment);\r
                                } else {\r
                                        Fragment fragment = new Fragment("branchLinks", "branchPanelLinks", this);\r
diff --git a/src/com/gitblit/wicket/resources/feed_16x16.png b/src/com/gitblit/wicket/resources/feed_16x16.png
new file mode 100644 (file)
index 0000000..99987a3
Binary files /dev/null and b/src/com/gitblit/wicket/resources/feed_16x16.png differ
index 7143f8549625f0a03efafae5e2734699e3943ece..498c1a77142e2fae2319e09d8f6980cdd04b1c82 100644 (file)
@@ -486,6 +486,10 @@ table.plain {
        padding: 8px;\r
 }\r
 \r
+table.plain td {\r
+       white-space: nowrap;\r
+}\r
+\r
 table.plain td.edit {  \r
        padding: 3px;\r
 }\r