wiki.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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. // WIKI_START page template
  19. WIKI_START = "repo/wiki/start"
  20. // WIKI_VIEW page template
  21. WIKI_VIEW = "repo/wiki/view"
  22. // WIKI_NEW page template
  23. WIKI_NEW = "repo/wiki/new"
  24. // WIKI_PAGES page template
  25. WIKI_PAGES = "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. type PageMeta struct {
  38. Name string
  39. URL string
  40. Updated time.Time
  41. }
  42. func renderWikiPage(c *context.Context, isViewPage bool) (*git.Repository, string) {
  43. wikiRepo, err := git.OpenRepository(c.Repo.Repository.WikiPath())
  44. if err != nil {
  45. c.Handle(500, "OpenRepository", err)
  46. return nil, ""
  47. }
  48. commit, err := wikiRepo.GetBranchCommit("master")
  49. if err != nil {
  50. c.Handle(500, "GetBranchCommit", err)
  51. return nil, ""
  52. }
  53. // Get page list.
  54. if isViewPage {
  55. entries, err := commit.ListEntries()
  56. if err != nil {
  57. c.Handle(500, "ListEntries", err)
  58. return nil, ""
  59. }
  60. pages := make([]PageMeta, 0, len(entries))
  61. for i := range entries {
  62. if entries[i].Type == git.OBJECT_BLOB && strings.HasSuffix(entries[i].Name(), ".md") {
  63. name := strings.TrimSuffix(entries[i].Name(), ".md")
  64. pages = append(pages, PageMeta{
  65. Name: name,
  66. URL: models.ToWikiPageURL(name),
  67. })
  68. }
  69. }
  70. c.Data["Pages"] = pages
  71. }
  72. pageURL := c.Params(":page")
  73. if len(pageURL) == 0 {
  74. pageURL = "Home"
  75. }
  76. c.Data["PageURL"] = pageURL
  77. pageName := models.ToWikiPageName(pageURL)
  78. c.Data["old_title"] = pageName
  79. c.Data["Title"] = pageName
  80. c.Data["title"] = pageName
  81. c.Data["RequireHighlightJS"] = true
  82. blob, err := commit.GetBlobByPath(pageName + ".md")
  83. if err != nil {
  84. if git.IsErrNotExist(err) {
  85. c.Redirect(c.Repo.RepoLink + "/wiki/_pages")
  86. } else {
  87. c.Handle(500, "GetBlobByPath", err)
  88. }
  89. return nil, ""
  90. }
  91. r, err := blob.Data()
  92. if err != nil {
  93. c.Handle(500, "Data", err)
  94. return nil, ""
  95. }
  96. data, err := ioutil.ReadAll(r)
  97. if err != nil {
  98. c.Handle(500, "ReadAll", err)
  99. return nil, ""
  100. }
  101. if isViewPage {
  102. c.Data["content"] = string(markup.Markdown(data, c.Repo.RepoLink, c.Repo.Repository.ComposeMetas()))
  103. } else {
  104. c.Data["content"] = string(data)
  105. }
  106. return wikiRepo, pageName
  107. }
  108. func Wiki(c *context.Context) {
  109. c.Data["PageIsWiki"] = true
  110. if !c.Repo.Repository.HasWiki() {
  111. c.Data["Title"] = c.Tr("repo.wiki")
  112. c.Data["PageIsRepoWiki"] = true
  113. c.HTML(200, WIKI_START)
  114. return
  115. }
  116. wikiRepo, pageName := renderWikiPage(c, true)
  117. if c.Written() {
  118. return
  119. }
  120. // Get last change information.
  121. lastCommit, err := wikiRepo.GetCommitByPath(pageName + ".md")
  122. if err != nil {
  123. c.Handle(500, "GetCommitByPath", err)
  124. return
  125. }
  126. c.Data["Author"] = lastCommit.Author
  127. c.HTML(200, WIKI_VIEW)
  128. }
  129. func WikiPages(c *context.Context) {
  130. c.Data["Title"] = c.Tr("repo.wiki.pages")
  131. c.Data["PageIsWiki"] = true
  132. if !c.Repo.Repository.HasWiki() {
  133. c.Redirect(c.Repo.RepoLink + "/wiki")
  134. return
  135. }
  136. wikiRepo, err := git.OpenRepository(c.Repo.Repository.WikiPath())
  137. if err != nil {
  138. c.Handle(500, "OpenRepository", err)
  139. return
  140. }
  141. commit, err := wikiRepo.GetBranchCommit("master")
  142. if err != nil {
  143. c.Handle(500, "GetBranchCommit", err)
  144. return
  145. }
  146. entries, err := commit.ListEntries()
  147. if err != nil {
  148. c.Handle(500, "ListEntries", err)
  149. return
  150. }
  151. pages := make([]PageMeta, 0, len(entries))
  152. for i := range entries {
  153. if entries[i].Type == git.OBJECT_BLOB && strings.HasSuffix(entries[i].Name(), ".md") {
  154. commit, err := wikiRepo.GetCommitByPath(entries[i].Name())
  155. if err != nil {
  156. c.ServerError("GetCommitByPath", err)
  157. return
  158. }
  159. name := strings.TrimSuffix(entries[i].Name(), ".md")
  160. pages = append(pages, PageMeta{
  161. Name: name,
  162. URL: models.ToWikiPageURL(name),
  163. Updated: commit.Author.When,
  164. })
  165. }
  166. }
  167. c.Data["Pages"] = pages
  168. c.HTML(200, WIKI_PAGES)
  169. }
  170. func NewWiki(c *context.Context) {
  171. c.Data["Title"] = c.Tr("repo.wiki.new_page")
  172. c.Data["PageIsWiki"] = true
  173. c.Data["RequireSimpleMDE"] = true
  174. if !c.Repo.Repository.HasWiki() {
  175. c.Data["title"] = "Home"
  176. }
  177. c.HTML(200, WIKI_NEW)
  178. }
  179. func NewWikiPost(c *context.Context, f form.NewWiki) {
  180. c.Data["Title"] = c.Tr("repo.wiki.new_page")
  181. c.Data["PageIsWiki"] = true
  182. c.Data["RequireSimpleMDE"] = true
  183. if c.HasError() {
  184. c.HTML(200, WIKI_NEW)
  185. return
  186. }
  187. if err := c.Repo.Repository.AddWikiPage(c.User, f.Title, f.Content, f.Message); err != nil {
  188. if models.IsErrWikiAlreadyExist(err) {
  189. c.Data["Err_Title"] = true
  190. c.RenderWithErr(c.Tr("repo.wiki.page_already_exists"), WIKI_NEW, &f)
  191. } else {
  192. c.Handle(500, "AddWikiPage", err)
  193. }
  194. return
  195. }
  196. c.Redirect(c.Repo.RepoLink + "/wiki/" + models.ToWikiPageURL(models.ToWikiPageName(f.Title)))
  197. }
  198. func EditWiki(c *context.Context) {
  199. c.Data["PageIsWiki"] = true
  200. c.Data["PageIsWikiEdit"] = true
  201. c.Data["RequireSimpleMDE"] = true
  202. if !c.Repo.Repository.HasWiki() {
  203. c.Redirect(c.Repo.RepoLink + "/wiki")
  204. return
  205. }
  206. renderWikiPage(c, false)
  207. if c.Written() {
  208. return
  209. }
  210. c.HTML(200, WIKI_NEW)
  211. }
  212. func EditWikiPost(c *context.Context, f form.NewWiki) {
  213. c.Data["Title"] = c.Tr("repo.wiki.new_page")
  214. c.Data["PageIsWiki"] = true
  215. c.Data["RequireSimpleMDE"] = true
  216. if c.HasError() {
  217. c.HTML(200, WIKI_NEW)
  218. return
  219. }
  220. if err := c.Repo.Repository.EditWikiPage(c.User, f.OldTitle, f.Title, f.Content, f.Message); err != nil {
  221. c.Handle(500, "EditWikiPage", err)
  222. return
  223. }
  224. c.Redirect(c.Repo.RepoLink + "/wiki/" + models.ToWikiPageURL(models.ToWikiPageName(f.Title)))
  225. }
  226. func DeleteWikiPagePost(c *context.Context) {
  227. pageURL := c.Params(":page")
  228. if len(pageURL) == 0 {
  229. pageURL = "Home"
  230. }
  231. pageName := models.ToWikiPageName(pageURL)
  232. if err := c.Repo.Repository.DeleteWikiPage(c.User, pageName); err != nil {
  233. c.Handle(500, "DeleteWikiPage", err)
  234. return
  235. }
  236. c.JSON(200, map[string]interface{}{
  237. "redirect": c.Repo.RepoLink + "/wiki/",
  238. })
  239. }