wiki.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2018 Gitote. All rights reserved.
  3. //
  4. // This source code is licensed under the MIT license found in the
  5. // LICENSE file in the root directory of this source tree.
  6. package repo
  7. import (
  8. "gitote/gitote/models"
  9. "gitote/gitote/pkg/context"
  10. "gitote/gitote/pkg/form"
  11. "gitote/gitote/pkg/markup"
  12. "io/ioutil"
  13. "strings"
  14. "time"
  15. "gitlab.com/gitote/git-module"
  16. )
  17. const (
  18. // WikiStartTPL page template
  19. WikiStartTPL = "repo/wiki/start"
  20. // WikiViewTPL page template
  21. WikiViewTPL = "repo/wiki/view"
  22. // WikiNewTPL page template
  23. WikiNewTPL = "repo/wiki/new"
  24. // WikiPagesTPL page template
  25. WikiPagesTPL = "repo/wiki/pages"
  26. )
  27. func MustEnableWiki(c *context.Context) {
  28. if !c.Repo.Repository.EnableWiki {
  29. c.Handle(404, "MustEnableWiki", nil)
  30. return
  31. }
  32. if c.Repo.Repository.EnableExternalWiki {
  33. c.Redirect(c.Repo.Repository.ExternalWikiURL)
  34. return
  35. }
  36. }
  37. // PageMeta contains the page meta information
  38. type PageMeta struct {
  39. Name string
  40. URL string
  41. Updated time.Time
  42. }
  43. func renderWikiPage(c *context.Context, isViewPage bool) (*git.Repository, string) {
  44. wikiRepo, err := git.OpenRepository(c.Repo.Repository.WikiPath())
  45. if err != nil {
  46. c.Handle(500, "OpenRepository", err)
  47. return nil, ""
  48. }
  49. commit, err := wikiRepo.GetBranchCommit("master")
  50. if err != nil {
  51. c.Handle(500, "GetBranchCommit", err)
  52. return nil, ""
  53. }
  54. // Get page list.
  55. if isViewPage {
  56. entries, err := commit.ListEntries()
  57. if err != nil {
  58. c.Handle(500, "ListEntries", err)
  59. return nil, ""
  60. }
  61. pages := make([]PageMeta, 0, len(entries))
  62. for i := range entries {
  63. if entries[i].Type == git.OBJECT_BLOB && strings.HasSuffix(entries[i].Name(), ".md") {
  64. name := strings.TrimSuffix(entries[i].Name(), ".md")
  65. pages = append(pages, PageMeta{
  66. Name: name,
  67. URL: models.ToWikiPageURL(name),
  68. })
  69. }
  70. }
  71. c.Data["Pages"] = pages
  72. }
  73. pageURL := c.Params(":page")
  74. if len(pageURL) == 0 {
  75. pageURL = "Home"
  76. }
  77. c.Data["PageURL"] = pageURL
  78. pageName := models.ToWikiPageName(pageURL)
  79. c.Data["old_title"] = pageName
  80. c.Data["Title"] = pageName
  81. c.Data["title"] = pageName
  82. c.Data["RequireHighlightJS"] = true
  83. blob, err := commit.GetBlobByPath(pageName + ".md")
  84. if err != nil {
  85. if git.IsErrNotExist(err) {
  86. c.Redirect(c.Repo.RepoLink + "/wiki/_pages")
  87. } else {
  88. c.Handle(500, "GetBlobByPath", err)
  89. }
  90. return nil, ""
  91. }
  92. r, err := blob.Data()
  93. if err != nil {
  94. c.Handle(500, "Data", err)
  95. return nil, ""
  96. }
  97. data, err := ioutil.ReadAll(r)
  98. if err != nil {
  99. c.Handle(500, "ReadAll", err)
  100. return nil, ""
  101. }
  102. if isViewPage {
  103. c.Data["content"] = string(markup.Markdown(data, c.Repo.RepoLink, c.Repo.Repository.ComposeMetas()))
  104. } else {
  105. c.Data["content"] = string(data)
  106. }
  107. return wikiRepo, pageName
  108. }
  109. func Wiki(c *context.Context) {
  110. c.Data["PageIsWiki"] = true
  111. if !c.Repo.Repository.HasWiki() {
  112. c.Data["Title"] = c.Tr("repo.wiki")
  113. c.Data["PageIsRepoWiki"] = true
  114. c.HTML(200, WikiStartTPL)
  115. return
  116. }
  117. wikiRepo, pageName := renderWikiPage(c, true)
  118. if c.Written() {
  119. return
  120. }
  121. // Get last change information.
  122. lastCommit, err := wikiRepo.GetCommitByPath(pageName + ".md")
  123. if err != nil {
  124. c.Handle(500, "GetCommitByPath", err)
  125. return
  126. }
  127. c.Data["Author"] = lastCommit.Author
  128. c.HTML(200, WikiViewTPL)
  129. }
  130. func WikiPages(c *context.Context) {
  131. c.Data["Title"] = c.Tr("repo.wiki.pages")
  132. c.Data["PageIsWiki"] = true
  133. if !c.Repo.Repository.HasWiki() {
  134. c.Redirect(c.Repo.RepoLink + "/wiki")
  135. return
  136. }
  137. wikiRepo, err := git.OpenRepository(c.Repo.Repository.WikiPath())
  138. if err != nil {
  139. c.Handle(500, "OpenRepository", err)
  140. return
  141. }
  142. commit, err := wikiRepo.GetBranchCommit("master")
  143. if err != nil {
  144. c.Handle(500, "GetBranchCommit", err)
  145. return
  146. }
  147. entries, err := commit.ListEntries()
  148. if err != nil {
  149. c.Handle(500, "ListEntries", err)
  150. return
  151. }
  152. pages := make([]PageMeta, 0, len(entries))
  153. for i := range entries {
  154. if entries[i].Type == git.OBJECT_BLOB && strings.HasSuffix(entries[i].Name(), ".md") {
  155. commit, err := wikiRepo.GetCommitByPath(entries[i].Name())
  156. if err != nil {
  157. c.ServerError("GetCommitByPath", err)
  158. return
  159. }
  160. name := strings.TrimSuffix(entries[i].Name(), ".md")
  161. pages = append(pages, PageMeta{
  162. Name: name,
  163. URL: models.ToWikiPageURL(name),
  164. Updated: commit.Author.When,
  165. })
  166. }
  167. }
  168. c.Data["Pages"] = pages
  169. c.HTML(200, WikiPagesTPL)
  170. }
  171. func NewWiki(c *context.Context) {
  172. c.Data["Title"] = c.Tr("repo.wiki.new_page")
  173. c.Data["PageIsWiki"] = true
  174. c.Data["RequireSimpleMDE"] = true
  175. if !c.Repo.Repository.HasWiki() {
  176. c.Data["title"] = "Home"
  177. }
  178. c.HTML(200, WikiNewTPL)
  179. }
  180. // NewWikiPost creates a new wiki
  181. func NewWikiPost(c *context.Context, f form.NewWiki) {
  182. c.Data["Title"] = c.Tr("repo.wiki.new_page")
  183. c.Data["PageIsWiki"] = true
  184. c.Data["RequireSimpleMDE"] = true
  185. if c.HasError() {
  186. c.HTML(200, WikiNewTPL)
  187. return
  188. }
  189. if err := c.Repo.Repository.AddWikiPage(c.User, f.Title, f.Content, f.Message); err != nil {
  190. if models.IsErrWikiAlreadyExist(err) {
  191. c.Data["Err_Title"] = true
  192. c.RenderWithErr(c.Tr("repo.wiki.page_already_exists"), WikiNewTPL, &f)
  193. } else {
  194. c.Handle(500, "AddWikiPage", err)
  195. }
  196. return
  197. }
  198. c.Redirect(c.Repo.RepoLink + "/wiki/" + models.ToWikiPageURL(models.ToWikiPageName(f.Title)))
  199. }
  200. func EditWiki(c *context.Context) {
  201. c.Data["PageIsWiki"] = true
  202. c.Data["PageIsWikiEdit"] = true
  203. c.Data["RequireSimpleMDE"] = true
  204. if !c.Repo.Repository.HasWiki() {
  205. c.Redirect(c.Repo.RepoLink + "/wiki")
  206. return
  207. }
  208. renderWikiPage(c, false)
  209. if c.Written() {
  210. return
  211. }
  212. c.HTML(200, WikiNewTPL)
  213. }
  214. // EditWikiPost edits a wiki
  215. func EditWikiPost(c *context.Context, f form.NewWiki) {
  216. c.Data["Title"] = c.Tr("repo.wiki.new_page")
  217. c.Data["PageIsWiki"] = true
  218. c.Data["RequireSimpleMDE"] = true
  219. if c.HasError() {
  220. c.HTML(200, WikiNewTPL)
  221. return
  222. }
  223. if err := c.Repo.Repository.EditWikiPage(c.User, f.OldTitle, f.Title, f.Content, f.Message); err != nil {
  224. c.Handle(500, "EditWikiPage", err)
  225. return
  226. }
  227. c.Redirect(c.Repo.RepoLink + "/wiki/" + models.ToWikiPageURL(models.ToWikiPageName(f.Title)))
  228. }
  229. // DeleteWikiPagePost deletes a wiki
  230. func DeleteWikiPagePost(c *context.Context) {
  231. pageURL := c.Params(":page")
  232. if len(pageURL) == 0 {
  233. pageURL = "Home"
  234. }
  235. pageName := models.ToWikiPageName(pageURL)
  236. if err := c.Repo.Repository.DeleteWikiPage(c.User, pageName); err != nil {
  237. c.Handle(500, "DeleteWikiPage", err)
  238. return
  239. }
  240. c.JSON(200, map[string]interface{}{
  241. "redirect": c.Repo.RepoLink + "/wiki/",
  242. })
  243. }