You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

wiki.go 7.1 kB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package repo
  5. import (
  6. "io/ioutil"
  7. "strings"
  8. "time"
  9. "code.gitea.io/git"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/auth"
  12. "code.gitea.io/gitea/modules/base"
  13. "code.gitea.io/gitea/modules/context"
  14. "code.gitea.io/gitea/modules/markdown"
  15. )
  16. const (
  17. tplWikiStart base.TplName = "repo/wiki/start"
  18. tplWikiView base.TplName = "repo/wiki/view"
  19. tplWikiNew base.TplName = "repo/wiki/new"
  20. tplWikiPages base.TplName = "repo/wiki/pages"
  21. )
  22. // MustEnableWiki check if wiki is enabled, if external then redirect
  23. func MustEnableWiki(ctx *context.Context) {
  24. if !ctx.Repo.Repository.EnableUnit(models.UnitTypeWiki) &&
  25. !ctx.Repo.Repository.EnableUnit(models.UnitTypeExternalWiki) {
  26. ctx.Handle(404, "MustEnableWiki", nil)
  27. return
  28. }
  29. unit, err := ctx.Repo.Repository.GetUnit(models.UnitTypeExternalWiki)
  30. if err == nil {
  31. ctx.Redirect(unit.ExternalWikiConfig().ExternalWikiURL)
  32. return
  33. }
  34. }
  35. // PageMeta wiki page meat information
  36. type PageMeta struct {
  37. Name string
  38. URL string
  39. Updated time.Time
  40. }
  41. func renderWikiPage(ctx *context.Context, isViewPage bool) (*git.Repository, string) {
  42. wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
  43. if err != nil {
  44. ctx.Handle(500, "OpenRepository", err)
  45. return nil, ""
  46. }
  47. commit, err := wikiRepo.GetBranchCommit("master")
  48. if err != nil {
  49. ctx.Handle(500, "GetBranchCommit", err)
  50. return nil, ""
  51. }
  52. // Get page list.
  53. if isViewPage {
  54. entries, err := commit.ListEntries()
  55. if err != nil {
  56. ctx.Handle(500, "ListEntries", err)
  57. return nil, ""
  58. }
  59. pages := make([]PageMeta, 0, len(entries))
  60. for i := range entries {
  61. if entries[i].Type == git.ObjectBlob && strings.HasSuffix(entries[i].Name(), ".md") {
  62. name := strings.TrimSuffix(entries[i].Name(), ".md")
  63. pages = append(pages, PageMeta{
  64. Name: name,
  65. URL: models.ToWikiPageURL(name),
  66. })
  67. }
  68. }
  69. ctx.Data["Pages"] = pages
  70. }
  71. pageURL := ctx.Params(":page")
  72. if len(pageURL) == 0 {
  73. pageURL = "Home"
  74. }
  75. ctx.Data["PageURL"] = pageURL
  76. pageName := models.ToWikiPageName(pageURL)
  77. ctx.Data["old_title"] = pageName
  78. ctx.Data["Title"] = pageName
  79. ctx.Data["title"] = pageName
  80. ctx.Data["RequireHighlightJS"] = true
  81. blob, err := commit.GetBlobByPath(pageURL + ".md")
  82. if err != nil {
  83. if git.IsErrNotExist(err) {
  84. ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
  85. } else {
  86. ctx.Handle(500, "GetBlobByPath", err)
  87. }
  88. return nil, ""
  89. }
  90. r, err := blob.Data()
  91. if err != nil {
  92. ctx.Handle(500, "Data", err)
  93. return nil, ""
  94. }
  95. data, err := ioutil.ReadAll(r)
  96. if err != nil {
  97. ctx.Handle(500, "ReadAll", err)
  98. return nil, ""
  99. }
  100. if isViewPage {
  101. ctx.Data["content"] = string(markdown.Render(data, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas()))
  102. } else {
  103. ctx.Data["content"] = string(data)
  104. }
  105. return wikiRepo, pageURL
  106. }
  107. // Wiki render wiki page
  108. func Wiki(ctx *context.Context) {
  109. ctx.Data["PageIsWiki"] = true
  110. if !ctx.Repo.Repository.HasWiki() {
  111. ctx.Data["Title"] = ctx.Tr("repo.wiki")
  112. ctx.HTML(200, tplWikiStart)
  113. return
  114. }
  115. wikiRepo, pagePath := renderWikiPage(ctx, true)
  116. if ctx.Written() {
  117. return
  118. }
  119. // Get last change information.
  120. lastCommit, err := wikiRepo.GetCommitByPath(pagePath + ".md")
  121. if err != nil {
  122. ctx.Handle(500, "GetCommitByPath", err)
  123. return
  124. }
  125. ctx.Data["Author"] = lastCommit.Author
  126. ctx.HTML(200, tplWikiView)
  127. }
  128. // WikiPages render wiki pages list page
  129. func WikiPages(ctx *context.Context) {
  130. ctx.Data["Title"] = ctx.Tr("repo.wiki.pages")
  131. ctx.Data["PageIsWiki"] = true
  132. if !ctx.Repo.Repository.HasWiki() {
  133. ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
  134. return
  135. }
  136. wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
  137. if err != nil {
  138. ctx.Handle(500, "OpenRepository", err)
  139. return
  140. }
  141. commit, err := wikiRepo.GetBranchCommit("master")
  142. if err != nil {
  143. ctx.Handle(500, "GetBranchCommit", err)
  144. return
  145. }
  146. entries, err := commit.ListEntries()
  147. if err != nil {
  148. ctx.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.ObjectBlob && strings.HasSuffix(entries[i].Name(), ".md") {
  154. c, err := wikiRepo.GetCommitByPath(entries[i].Name())
  155. if err != nil {
  156. ctx.Handle(500, "GetCommit", 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: c.Author.When,
  164. })
  165. }
  166. }
  167. ctx.Data["Pages"] = pages
  168. ctx.HTML(200, tplWikiPages)
  169. }
  170. // NewWiki render wiki create page
  171. func NewWiki(ctx *context.Context) {
  172. ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
  173. ctx.Data["PageIsWiki"] = true
  174. ctx.Data["RequireSimpleMDE"] = true
  175. if !ctx.Repo.Repository.HasWiki() {
  176. ctx.Data["title"] = "Home"
  177. }
  178. ctx.HTML(200, tplWikiNew)
  179. }
  180. // NewWikiPost response fro wiki create request
  181. func NewWikiPost(ctx *context.Context, form auth.NewWikiForm) {
  182. ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
  183. ctx.Data["PageIsWiki"] = true
  184. ctx.Data["RequireSimpleMDE"] = true
  185. if ctx.HasError() {
  186. ctx.HTML(200, tplWikiNew)
  187. return
  188. }
  189. wikiPath := models.ToWikiPageURL(form.Title)
  190. if err := ctx.Repo.Repository.AddWikiPage(ctx.User, wikiPath, form.Content, form.Message); err != nil {
  191. if models.IsErrWikiAlreadyExist(err) {
  192. ctx.Data["Err_Title"] = true
  193. ctx.RenderWithErr(ctx.Tr("repo.wiki.page_already_exists"), tplWikiNew, &form)
  194. } else {
  195. ctx.Handle(500, "AddWikiPage", err)
  196. }
  197. return
  198. }
  199. ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + wikiPath)
  200. }
  201. // EditWiki render wiki modify page
  202. func EditWiki(ctx *context.Context) {
  203. ctx.Data["PageIsWiki"] = true
  204. ctx.Data["PageIsWikiEdit"] = true
  205. ctx.Data["RequireSimpleMDE"] = true
  206. if !ctx.Repo.Repository.HasWiki() {
  207. ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
  208. return
  209. }
  210. renderWikiPage(ctx, false)
  211. if ctx.Written() {
  212. return
  213. }
  214. ctx.HTML(200, tplWikiNew)
  215. }
  216. // EditWikiPost response fro wiki modify request
  217. func EditWikiPost(ctx *context.Context, form auth.NewWikiForm) {
  218. ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
  219. ctx.Data["PageIsWiki"] = true
  220. ctx.Data["RequireSimpleMDE"] = true
  221. if ctx.HasError() {
  222. ctx.HTML(200, tplWikiNew)
  223. return
  224. }
  225. oldWikiPath := ctx.Params(":page")
  226. newWikiPath := models.ToWikiPageURL(form.Title)
  227. if err := ctx.Repo.Repository.EditWikiPage(ctx.User, oldWikiPath, newWikiPath, form.Content, form.Message); err != nil {
  228. ctx.Handle(500, "EditWikiPage", err)
  229. return
  230. }
  231. ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + newWikiPath)
  232. }
  233. // DeleteWikiPagePost delete wiki page
  234. func DeleteWikiPagePost(ctx *context.Context) {
  235. pageURL := ctx.Params(":page")
  236. if len(pageURL) == 0 {
  237. pageURL = "Home"
  238. }
  239. if err := ctx.Repo.Repository.DeleteWikiPage(ctx.User, pageURL); err != nil {
  240. ctx.Handle(500, "DeleteWikiPage", err)
  241. return
  242. }
  243. ctx.JSON(200, map[string]interface{}{
  244. "redirect": ctx.Repo.RepoLink + "/wiki/",
  245. })
  246. }