diff --git a/src/main/scala/gitbucket/core/controller/WikiController.scala b/src/main/scala/gitbucket/core/controller/WikiController.scala index ef9d327..b81e75e 100644 --- a/src/main/scala/gitbucket/core/controller/WikiController.scala +++ b/src/main/scala/gitbucket/core/controller/WikiController.scala @@ -38,7 +38,9 @@ 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), + getWikiPage(repository.owner, repository.name, "_Sidebar"), + getWikiPage(repository.owner, repository.name, "_Footer")) } getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/Home/_edit") }) @@ -47,7 +49,9 @@ 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), + getWikiPage(repository.owner, repository.name, "_Sidebar"), + getWikiPage(repository.owner, repository.name, "_Footer")) } getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_edit") }) @@ -124,7 +128,11 @@ 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 +148,11 @@ 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 +198,15 @@ 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) = ! (Array[String]("_Sidebar","_Footer") contains value) + private def conflictForNew: Constraint = new Constraint(){ override def validate(name: String, value: String, messages: Messages): Option[String] = { targetWikiPage.map { _ => diff --git a/src/main/scala/gitbucket/core/service/WikiService.scala b/src/main/scala/gitbucket/core/service/WikiService.scala index 4a8d1eb..29d8e56 100644 --- a/src/main/scala/gitbucket/core/service/WikiService.scala +++ b/src/main/scala/gitbucket/core/service/WikiService.scala @@ -93,7 +93,7 @@ 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) } diff --git a/src/main/twirl/gitbucket/core/wiki/page.scala.html b/src/main/twirl/gitbucket/core/wiki/page.scala.html index 3fcadd7..0d0d5f6 100644 --- a/src/main/twirl/gitbucket/core/wiki/page.scala.html +++ b/src/main/twirl/gitbucket/core/wiki/page.scala.html @@ -2,7 +2,9 @@ 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], + 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._ @@ -28,9 +30,13 @@ @defining(15){ max => <div class="panel panel-default"> <div class="panel-heading strong"> - Pages <span class="badge">@pages.length</span> + <a id="show-pages-index" href="javascript:void(0);"> + <span id="triangle-down" class="octicon octicon-triangle-down"></span> + <span id="triangle-right" class="octicon octicon-triangle-right" style="display: none;"></span> + <span class="strong">Pages</span> <span class="badge">@pages.length</span> + </a> </div> - <ul class="list-group list-group-flush"> + <ul id="pages-index" class="list-group list-group-flush"> @pages.zipWithIndex.map { case (page, i) => <li class="list-group-item page-link" style="border: none; @if(i > max - 1){display:none;}"> <a href="@url(repository)/wiki/@urlEncode(page)" class="strong">@page</a> @@ -44,6 +50,20 @@ </ul> </div> } + @sidebar.map { sidebarPage => + <div class="wiki-sidebar"> + @if(hasWritePermission){ + <a href="@url(repository)/wiki/_Sidebar/_edit" style="text-decoration: none;"><span class="octicon octicon-pencil pull-right"></span></a> + } + @markdown(sidebarPage.content, repository, true, false, false, false, pages) + </div> + }.getOrElse{ + @if(hasWritePermission){ + <a class="button-link" href="@url(repository)/wiki/_Sidebar/_edit" style="text-decoration: none;"> + <div class="wiki-sidebar-dotted text-center"><i class="octicon octicon-plus"></i> Add a custom sidebar</div> + </a> + } + } <div class="small"> <strong>Clone this wiki locally</strong> </div> @@ -69,6 +89,20 @@ pages = pages ) </div> + @footer.map { footerPage => + <div class="wiki-sidebar wiki-footer"> + @if(hasWritePermission){ + <a href="@url(repository)/wiki/_Footer/_edit" style="text-decoration: none;"><span class="octicon octicon-pencil pull-right"></span></a> + } + @markdown(footerPage.content, repository, true, false, false, false, pages) + </div> + }.getOrElse{ + @if(hasWritePermission){ + <a class="button-link" href="@url(repository)/wiki/_Footer/_edit" style="text-decoration: none;"> + <div class="wiki-sidebar-dotted text-center"><i class="octicon octicon-plus"></i> Add a custom footer</div> + </a> + } + } </div> } } @@ -79,6 +113,24 @@ $(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 3501e79..c18b891 100644 --- a/src/main/webapp/assets/common/css/gitbucket.css +++ b/src/main/webapp/assets/common/css/gitbucket.css @@ -613,6 +613,11 @@ margin-bottom: -3px; } +a#show-pages-index { + color: #333; + text-decoration: none; +} + /* ul.nav-stacked.side-menu li span.header { border-top-right-radius: 3px; @@ -1331,6 +1336,55 @@ 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: 8px 10px 0px 10px; + border-radius: 3px; + margin-bottom: 20px; + margin-top: 20px; +} + +div.wiki-sidebar-dotted { + background-color: white; + border: 1px dashed #ddd; + padding: 10px 15px; + margin-bottom: 20px; + margin-top: 20px; + border-radius: 3px; + font-size: 16px; +} + +div.wiki-footer { + margin-top: 50px; + background-color: #f5f5f5; + color: gray; +} + +/* +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 */ /****************************************************************************/