From 6ad724d80cb7a0a08e8c4636cb57720089626607 Mon Sep 17 00:00:00 2001 From: Viliam Dias Date: Mon, 16 Nov 2015 14:25:22 -0200 Subject: [PATCH 1/4] A service to get the wiki sidebar page - getWikiSideBar: a new service to get the wiki sidebar file "_Sidebar.md". - getFileContent: must ignore MD files which starts with "_". --- .../gitbucket/core/service/WikiService.scala | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/scala/gitbucket/core/service/WikiService.scala b/src/main/scala/gitbucket/core/service/WikiService.scala index 4a8d1eb13..b6a0c463e 100644 --- a/src/main/scala/gitbucket/core/service/WikiService.scala +++ b/src/main/scala/gitbucket/core/service/WikiService.scala @@ -71,6 +71,20 @@ trait WikiService { } } + /** + * Returns the wiki sidebar page. + */ + def getWikiSideBar(owner: String, repository: String): Option[WikiPageInfo] = { + using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git => + if(!JGitUtil.isEmpty(git)){ + JGitUtil.getFileList(git, "master", ".").find(_.name == "_Sidebar.md").map { file => + WikiPageInfo(file.name, StringUtil.convertFromByteArray(git.getRepository.open(file.id).getBytes), + file.author, file.time, file.commitId) + } + } else None + } + } + /** * Returns the content of the specified file. */ @@ -93,7 +107,7 @@ trait WikiService { def getWikiPageList(owner: String, repository: String): List[String] = { using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git => JGitUtil.getFileList(git, "master", ".") - .filter(_.name.endsWith(".md")) + .filter(_.name.endsWith(".md")).filterNot(_.name.startsWith("_")) .map(_.name.stripSuffix(".md")) .sortBy(x => x) } From 51acf72e0dce79288afb1259d7745f4c764f926b Mon Sep 17 00:00:00 2001 From: Viliam Dias Date: Mon, 16 Nov 2015 14:33:02 -0200 Subject: [PATCH 2/4] A sidebar page for the wiki A simple wiki page (markdown file "_Sidebar.md") is used as a sidebar menu for the wiki. Github specification: https://help.github.com/articles/creating-a-sidebar/ - the sidebar is rendered below the pages index. - if you click on page index "counter" you can collapse or expand the page list. --- .../core/controller/WikiController.scala | 22 ++++++-- .../twirl/gitbucket/core/wiki/page.scala.html | 52 +++++++++++++++++-- .../webapp/assets/common/css/gitbucket.css | 30 +++++++++++ 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/src/main/scala/gitbucket/core/controller/WikiController.scala b/src/main/scala/gitbucket/core/controller/WikiController.scala index 7f876d059..625ba3453 100644 --- a/src/main/scala/gitbucket/core/controller/WikiController.scala +++ b/src/main/scala/gitbucket/core/controller/WikiController.scala @@ -38,7 +38,8 @@ trait WikiControllerBase extends ControllerBase { get("/:owner/:repository/wiki")(referrersOnly { repository => getWikiPage(repository.owner, repository.name, "Home").map { page => html.page("Home", page, getWikiPageList(repository.owner, repository.name), - repository, hasWritePermission(repository.owner, repository.name, context.loginAccount)) + repository, hasWritePermission(repository.owner, repository.name, context.loginAccount), + getWikiSideBar(repository.owner, repository.name)) } getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/Home/_edit") }) @@ -47,7 +48,8 @@ trait WikiControllerBase extends ControllerBase { getWikiPage(repository.owner, repository.name, pageName).map { page => html.page(pageName, page, getWikiPageList(repository.owner, repository.name), - repository, hasWritePermission(repository.owner, repository.name, context.loginAccount)) + repository, hasWritePermission(repository.owner, repository.name, context.loginAccount), + getWikiSideBar(repository.owner, repository.name)) } getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_edit") }) @@ -124,7 +126,11 @@ trait WikiControllerBase extends ControllerBase { updateLastActivityDate(repository.owner, repository.name) recordEditWikiPageActivity(repository.owner, repository.name, loginAccount.userName, form.pageName, commitId) } - redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}") + if(notReservedPageName(form.pageName)) { + redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}") + } else { + redirect(s"/${repository.owner}/${repository.name}/wiki") + } } }) @@ -140,7 +146,11 @@ trait WikiControllerBase extends ControllerBase { updateLastActivityDate(repository.owner, repository.name) recordCreateWikiPageActivity(repository.owner, repository.name, loginAccount.userName, form.pageName) - redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}") + if(notReservedPageName(form.pageName)) { + redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}") + } else { + redirect(s"/${repository.owner}/${repository.name}/wiki") + } } }) @@ -186,13 +196,15 @@ trait WikiControllerBase extends ControllerBase { override def validate(name: String, value: String, messages: Messages): Option[String] = if(value.exists("\\/:*?\"<>|".contains(_))){ Some(s"${name} contains invalid character.") - } else if(value.startsWith("_") || value.startsWith("-")){ + } else if(notReservedPageName(value) && (value.startsWith("_") || value.startsWith("-"))){ Some(s"${name} starts with invalid character.") } else { None } } + private def notReservedPageName(value: String) = value != "_Sidebar" + private def conflictForNew: Constraint = new Constraint(){ override def validate(name: String, value: String, messages: Messages): Option[String] = { targetWikiPage.map { _ => diff --git a/src/main/twirl/gitbucket/core/wiki/page.scala.html b/src/main/twirl/gitbucket/core/wiki/page.scala.html index 99afb548f..e9700d9d2 100644 --- a/src/main/twirl/gitbucket/core/wiki/page.scala.html +++ b/src/main/twirl/gitbucket/core/wiki/page.scala.html @@ -2,7 +2,8 @@ page: gitbucket.core.service.WikiService.WikiPageInfo, pages: List[String], repository: gitbucket.core.service.RepositoryService.RepositoryInfo, - hasWritePermission: Boolean)(implicit context: gitbucket.core.controller.Context) + hasWritePermission: Boolean, + sidebar: Option[gitbucket.core.service.WikiService.WikiPageInfo])(implicit context: gitbucket.core.controller.Context) @import context._ @import gitbucket.core.view.helpers._ @import gitbucket.core.service.WikiService._ @@ -26,10 +27,14 @@
@defining(15){ max => -
- Pages @pages.length -
-
+ +
+ + + Pages @pages.length +
+
+
@pages.zipWithIndex.map { case (page, i) => } + @sidebar.map { sidebarPage => +
+ @if(hasWritePermission){ + + + + } + @markdown(sidebarPage.content, repository, true, false, false, false, pages) +
+ }.getOrElse{ + @if(hasWritePermission){ + +
+ + Add a custom sidebar +
+
+ } + }
Clone this wiki locally
@@ -68,6 +92,24 @@ $(function(){ $(e.target).parents('div.show-more').remove(); }); + $('#show-pages-index').click(function(e){ + if($('#pages-index').is(":visible")){ + $('#triangle-down').hide(); + $('#triangle-right').show(); + $('#pages-index').hide(); + } else { + $('#triangle-right').hide(); + $('#triangle-down').show(); + $('#pages-index').show(); + } + }); + + @sidebar.map { sidebarPage => + $('#pages-index').hide(); + $('#triangle-down').hide(); + $('#triangle-right').show(); + } + @if(settings.ssh && loginAccount.isDefined){ $('#repository-url-http').click(function(){ $('#repository-url').val('@httpUrl(repository)'); diff --git a/src/main/webapp/assets/common/css/gitbucket.css b/src/main/webapp/assets/common/css/gitbucket.css index cc9f069c2..f1bb30739 100644 --- a/src/main/webapp/assets/common/css/gitbucket.css +++ b/src/main/webapp/assets/common/css/gitbucket.css @@ -1175,6 +1175,36 @@ a.absent { color: #c00; } +div.wiki-index-header { + background-color: #f5f5f5; + color: #333333; + margin: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + border: 1px solid #d8d8d8; + padding: 8px 8px 8px 8px; +} + +div.wiki-sidebar { + background-color: white; + border: 1px solid #d8d8d8; + padding: 4px; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + margin-bottom: 20px; + margin-top: 20px; +} + +div.wiki-index-content { + background-color: white; + border: 1px solid #d8d8d8; + padding: 0px; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + margin-bottom: 20px; + border-top: none; +} + /****************************************************************************/ /* Commit */ /****************************************************************************/ From 9777d543b1701ae8da714e37d3a13739453d3a3b Mon Sep 17 00:00:00 2001 From: Viliam Dias Date: Mon, 16 Nov 2015 16:35:07 -0200 Subject: [PATCH 3/4] Remove the getWikiSideBar service And use getWikiPage to avoid code repetition. --- .../gitbucket/core/controller/WikiController.scala | 4 ++-- .../scala/gitbucket/core/service/WikiService.scala | 14 -------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/main/scala/gitbucket/core/controller/WikiController.scala b/src/main/scala/gitbucket/core/controller/WikiController.scala index 625ba3453..a587c8eb5 100644 --- a/src/main/scala/gitbucket/core/controller/WikiController.scala +++ b/src/main/scala/gitbucket/core/controller/WikiController.scala @@ -39,7 +39,7 @@ trait WikiControllerBase extends ControllerBase { getWikiPage(repository.owner, repository.name, "Home").map { page => html.page("Home", page, getWikiPageList(repository.owner, repository.name), repository, hasWritePermission(repository.owner, repository.name, context.loginAccount), - getWikiSideBar(repository.owner, repository.name)) + getWikiPage(repository.owner, repository.name, "_Sidebar")) } getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/Home/_edit") }) @@ -49,7 +49,7 @@ trait WikiControllerBase extends ControllerBase { getWikiPage(repository.owner, repository.name, pageName).map { page => html.page(pageName, page, getWikiPageList(repository.owner, repository.name), repository, hasWritePermission(repository.owner, repository.name, context.loginAccount), - getWikiSideBar(repository.owner, repository.name)) + getWikiPage(repository.owner, repository.name, "_Sidebar")) } getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_edit") }) diff --git a/src/main/scala/gitbucket/core/service/WikiService.scala b/src/main/scala/gitbucket/core/service/WikiService.scala index b6a0c463e..29d8e56ce 100644 --- a/src/main/scala/gitbucket/core/service/WikiService.scala +++ b/src/main/scala/gitbucket/core/service/WikiService.scala @@ -71,20 +71,6 @@ trait WikiService { } } - /** - * Returns the wiki sidebar page. - */ - def getWikiSideBar(owner: String, repository: String): Option[WikiPageInfo] = { - using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git => - if(!JGitUtil.isEmpty(git)){ - JGitUtil.getFileList(git, "master", ".").find(_.name == "_Sidebar.md").map { file => - WikiPageInfo(file.name, StringUtil.convertFromByteArray(git.getRepository.open(file.id).getBytes), - file.author, file.time, file.commitId) - } - } else None - } - } - /** * Returns the content of the specified file. */ From ef3b02b718877d3f13ca6edd2dbfaa3c71055beb Mon Sep 17 00:00:00 2001 From: Viliam Dias Date: Mon, 7 Dec 2015 13:45:37 -0200 Subject: [PATCH 4/4] A simple wiki page (markdown file "_Footer.md") is used as footer for the wiki. Github specification: https://help.github.com/articles/creating-a-footer/ - the footer is rendered below the wiki page content. - a direct link to edit the footer. --- .../core/controller/WikiController.scala | 8 ++++--- .../twirl/gitbucket/core/wiki/page.scala.html | 24 +++++++++++++++++-- .../webapp/assets/common/css/gitbucket.css | 16 +++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/main/scala/gitbucket/core/controller/WikiController.scala b/src/main/scala/gitbucket/core/controller/WikiController.scala index a587c8eb5..1c16def7a 100644 --- a/src/main/scala/gitbucket/core/controller/WikiController.scala +++ b/src/main/scala/gitbucket/core/controller/WikiController.scala @@ -39,7 +39,8 @@ trait WikiControllerBase extends ControllerBase { getWikiPage(repository.owner, repository.name, "Home").map { page => html.page("Home", page, getWikiPageList(repository.owner, repository.name), repository, hasWritePermission(repository.owner, repository.name, context.loginAccount), - getWikiPage(repository.owner, repository.name, "_Sidebar")) + getWikiPage(repository.owner, repository.name, "_Sidebar"), + getWikiPage(repository.owner, repository.name, "_Footer")) } getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/Home/_edit") }) @@ -49,7 +50,8 @@ trait WikiControllerBase extends ControllerBase { getWikiPage(repository.owner, repository.name, pageName).map { page => html.page(pageName, page, getWikiPageList(repository.owner, repository.name), repository, hasWritePermission(repository.owner, repository.name, context.loginAccount), - getWikiPage(repository.owner, repository.name, "_Sidebar")) + getWikiPage(repository.owner, repository.name, "_Sidebar"), + getWikiPage(repository.owner, repository.name, "_Footer")) } getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_edit") }) @@ -203,7 +205,7 @@ trait WikiControllerBase extends ControllerBase { } } - private def notReservedPageName(value: String) = value != "_Sidebar" + private def notReservedPageName(value: String) = ! (Array[String]("_Sidebar","_Footer") contains value) private def conflictForNew: Constraint = new Constraint(){ override def validate(name: String, value: String, messages: Messages): Option[String] = { diff --git a/src/main/twirl/gitbucket/core/wiki/page.scala.html b/src/main/twirl/gitbucket/core/wiki/page.scala.html index e9700d9d2..74e9690a5 100644 --- a/src/main/twirl/gitbucket/core/wiki/page.scala.html +++ b/src/main/twirl/gitbucket/core/wiki/page.scala.html @@ -3,7 +3,8 @@ pages: List[String], repository: gitbucket.core.service.RepositoryService.RepositoryInfo, hasWritePermission: Boolean, - sidebar: Option[gitbucket.core.service.WikiService.WikiPageInfo])(implicit context: gitbucket.core.controller.Context) + sidebar: Option[gitbucket.core.service.WikiService.WikiPageInfo], + footer: Option[gitbucket.core.service.WikiService.WikiPageInfo])(implicit context: gitbucket.core.controller.Context) @import context._ @import gitbucket.core.view.helpers._ @import gitbucket.core.service.WikiService._ @@ -59,7 +60,7 @@ }.getOrElse{ @if(hasWritePermission){ - } } diff --git a/src/main/webapp/assets/common/css/gitbucket.css b/src/main/webapp/assets/common/css/gitbucket.css index f1bb30739..2053f0fac 100644 --- a/src/main/webapp/assets/common/css/gitbucket.css +++ b/src/main/webapp/assets/common/css/gitbucket.css @@ -1195,6 +1195,22 @@ div.wiki-sidebar { margin-top: 20px; } +div.wiki-sidebar-dotted { + background-color: white; + border: 1px dotted #d8d8d8; + padding: 4px; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + margin-bottom: 20px; + margin-top: 20px; +} + +div.wiki-footer { + margin-top: 50px; + background-color: #f5f5f5; + color: gray; +} + div.wiki-index-content { background-color: white; border: 1px solid #d8d8d8;