Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2018 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package repo
  6. import (
  7. "fmt"
  8. "io/ioutil"
  9. "net/url"
  10. "path/filepath"
  11. "strings"
  12. "code.gitea.io/gitea/models"
  13. "code.gitea.io/gitea/modules/auth"
  14. "code.gitea.io/gitea/modules/base"
  15. "code.gitea.io/gitea/modules/context"
  16. "code.gitea.io/gitea/modules/git"
  17. "code.gitea.io/gitea/modules/log"
  18. "code.gitea.io/gitea/modules/markup"
  19. "code.gitea.io/gitea/modules/markup/markdown"
  20. "code.gitea.io/gitea/modules/timeutil"
  21. "code.gitea.io/gitea/modules/util"
  22. wiki_service "code.gitea.io/gitea/services/wiki"
  23. )
  24. const (
  25. tplWikiStart base.TplName = "repo/wiki/start"
  26. tplWikiView base.TplName = "repo/wiki/view"
  27. tplWikiRevision base.TplName = "repo/wiki/revision"
  28. tplWikiNew base.TplName = "repo/wiki/new"
  29. tplWikiPages base.TplName = "repo/wiki/pages"
  30. )
  31. // MustEnableWiki check if wiki is enabled, if external then redirect
  32. func MustEnableWiki(ctx *context.Context) {
  33. if !ctx.Repo.CanRead(models.UnitTypeWiki) &&
  34. !ctx.Repo.CanRead(models.UnitTypeExternalWiki) {
  35. if log.IsTrace() {
  36. log.Trace("Permission Denied: User %-v cannot read %-v or %-v of repo %-v\n"+
  37. "User in repo has Permissions: %-+v",
  38. ctx.User,
  39. models.UnitTypeWiki,
  40. models.UnitTypeExternalWiki,
  41. ctx.Repo.Repository,
  42. ctx.Repo.Permission)
  43. }
  44. ctx.NotFound("MustEnableWiki", nil)
  45. return
  46. }
  47. unit, err := ctx.Repo.Repository.GetUnit(models.UnitTypeExternalWiki)
  48. if err == nil {
  49. ctx.Redirect(unit.ExternalWikiConfig().ExternalWikiURL)
  50. return
  51. }
  52. }
  53. // PageMeta wiki page meta information
  54. type PageMeta struct {
  55. Name string
  56. SubURL string
  57. UpdatedUnix timeutil.TimeStamp
  58. }
  59. // findEntryForFile finds the tree entry for a target filepath.
  60. func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) {
  61. entry, err := commit.GetTreeEntryByPath(target)
  62. if err != nil && !git.IsErrNotExist(err) {
  63. return nil, err
  64. }
  65. if entry != nil {
  66. return entry, nil
  67. }
  68. // Then the unescaped, shortest alternative
  69. var unescapedTarget string
  70. if unescapedTarget, err = url.QueryUnescape(target); err != nil {
  71. return nil, err
  72. }
  73. return commit.GetTreeEntryByPath(unescapedTarget)
  74. }
  75. func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
  76. wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
  77. if err != nil {
  78. ctx.ServerError("OpenRepository", err)
  79. return nil, nil, err
  80. }
  81. commit, err := wikiRepo.GetBranchCommit("master")
  82. if err != nil {
  83. return wikiRepo, nil, err
  84. }
  85. return wikiRepo, commit, nil
  86. }
  87. // wikiContentsByEntry returns the contents of the wiki page referenced by the
  88. // given tree entry. Writes to ctx if an error occurs.
  89. func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
  90. reader, err := entry.Blob().DataAsync()
  91. if err != nil {
  92. ctx.ServerError("Blob.Data", err)
  93. return nil
  94. }
  95. defer reader.Close()
  96. content, err := ioutil.ReadAll(reader)
  97. if err != nil {
  98. ctx.ServerError("ReadAll", err)
  99. return nil
  100. }
  101. return content
  102. }
  103. // wikiContentsByName returns the contents of a wiki page, along with a boolean
  104. // indicating whether the page exists. Writes to ctx if an error occurs.
  105. func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName string) ([]byte, *git.TreeEntry, string, bool) {
  106. pageFilename := wiki_service.NameToFilename(wikiName)
  107. entry, err := findEntryForFile(commit, pageFilename)
  108. if err != nil && !git.IsErrNotExist(err) {
  109. ctx.ServerError("findEntryForFile", err)
  110. return nil, nil, "", false
  111. } else if entry == nil {
  112. return nil, nil, "", true
  113. }
  114. return wikiContentsByEntry(ctx, entry), entry, pageFilename, false
  115. }
  116. func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
  117. wikiRepo, commit, err := findWikiRepoCommit(ctx)
  118. if err != nil {
  119. if !git.IsErrNotExist(err) {
  120. ctx.ServerError("GetBranchCommit", err)
  121. }
  122. return nil, nil
  123. }
  124. // Get page list.
  125. entries, err := commit.ListEntries()
  126. if err != nil {
  127. if wikiRepo != nil {
  128. wikiRepo.Close()
  129. }
  130. ctx.ServerError("ListEntries", err)
  131. return nil, nil
  132. }
  133. pages := make([]PageMeta, 0, len(entries))
  134. for _, entry := range entries {
  135. if !entry.IsRegular() {
  136. continue
  137. }
  138. wikiName, err := wiki_service.FilenameToName(entry.Name())
  139. if err != nil {
  140. if models.IsErrWikiInvalidFileName(err) {
  141. continue
  142. }
  143. if wikiRepo != nil {
  144. wikiRepo.Close()
  145. }
  146. ctx.ServerError("WikiFilenameToName", err)
  147. return nil, nil
  148. } else if wikiName == "_Sidebar" || wikiName == "_Footer" {
  149. continue
  150. }
  151. pages = append(pages, PageMeta{
  152. Name: wikiName,
  153. SubURL: wiki_service.NameToSubURL(wikiName),
  154. })
  155. }
  156. ctx.Data["Pages"] = pages
  157. // get requested pagename
  158. pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
  159. if len(pageName) == 0 {
  160. pageName = "Home"
  161. }
  162. ctx.Data["PageURL"] = wiki_service.NameToSubURL(pageName)
  163. ctx.Data["old_title"] = pageName
  164. ctx.Data["Title"] = pageName
  165. ctx.Data["title"] = pageName
  166. ctx.Data["RequireHighlightJS"] = true
  167. //lookup filename in wiki - get filecontent, gitTree entry , real filename
  168. data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
  169. if noEntry {
  170. ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
  171. }
  172. if entry == nil || ctx.Written() {
  173. if wikiRepo != nil {
  174. wikiRepo.Close()
  175. }
  176. return nil, nil
  177. }
  178. sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
  179. if ctx.Written() {
  180. if wikiRepo != nil {
  181. wikiRepo.Close()
  182. }
  183. return nil, nil
  184. }
  185. footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
  186. if ctx.Written() {
  187. if wikiRepo != nil {
  188. wikiRepo.Close()
  189. }
  190. return nil, nil
  191. }
  192. metas := ctx.Repo.Repository.ComposeDocumentMetas()
  193. ctx.Data["content"] = markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
  194. ctx.Data["sidebarPresent"] = sidebarContent != nil
  195. ctx.Data["sidebarContent"] = markdown.RenderWiki(sidebarContent, ctx.Repo.RepoLink, metas)
  196. ctx.Data["footerPresent"] = footerContent != nil
  197. ctx.Data["footerContent"] = markdown.RenderWiki(footerContent, ctx.Repo.RepoLink, metas)
  198. // get commit count - wiki revisions
  199. commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
  200. ctx.Data["CommitCount"] = commitsCount
  201. return wikiRepo, entry
  202. }
  203. func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
  204. wikiRepo, commit, err := findWikiRepoCommit(ctx)
  205. if err != nil {
  206. if wikiRepo != nil {
  207. wikiRepo.Close()
  208. }
  209. if !git.IsErrNotExist(err) {
  210. ctx.ServerError("GetBranchCommit", err)
  211. }
  212. return nil, nil
  213. }
  214. // get requested pagename
  215. pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
  216. if len(pageName) == 0 {
  217. pageName = "Home"
  218. }
  219. ctx.Data["PageURL"] = wiki_service.NameToSubURL(pageName)
  220. ctx.Data["old_title"] = pageName
  221. ctx.Data["Title"] = pageName
  222. ctx.Data["title"] = pageName
  223. ctx.Data["RequireHighlightJS"] = true
  224. ctx.Data["Username"] = ctx.Repo.Owner.Name
  225. ctx.Data["Reponame"] = ctx.Repo.Repository.Name
  226. //lookup filename in wiki - get filecontent, gitTree entry , real filename
  227. data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
  228. if noEntry {
  229. ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
  230. }
  231. if entry == nil || ctx.Written() {
  232. if wikiRepo != nil {
  233. wikiRepo.Close()
  234. }
  235. return nil, nil
  236. }
  237. ctx.Data["content"] = string(data)
  238. ctx.Data["sidebarPresent"] = false
  239. ctx.Data["sidebarContent"] = ""
  240. ctx.Data["footerPresent"] = false
  241. ctx.Data["footerContent"] = ""
  242. // get commit count - wiki revisions
  243. commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
  244. ctx.Data["CommitCount"] = commitsCount
  245. // get page
  246. page := ctx.QueryInt("page")
  247. if page <= 1 {
  248. page = 1
  249. }
  250. // get Commit Count
  251. commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page)
  252. if err != nil {
  253. if wikiRepo != nil {
  254. wikiRepo.Close()
  255. }
  256. ctx.ServerError("CommitsByFileAndRangeNoFollow", err)
  257. return nil, nil
  258. }
  259. commitsHistory = models.ValidateCommitsWithEmails(commitsHistory)
  260. commitsHistory = models.ParseCommitsWithSignature(commitsHistory, ctx.Repo.Repository)
  261. ctx.Data["Commits"] = commitsHistory
  262. pager := context.NewPagination(int(commitsCount), git.CommitsRangeSize, page, 5)
  263. pager.SetDefaultParams(ctx)
  264. ctx.Data["Page"] = pager
  265. return wikiRepo, entry
  266. }
  267. func renderEditPage(ctx *context.Context) {
  268. wikiRepo, commit, err := findWikiRepoCommit(ctx)
  269. if err != nil {
  270. if wikiRepo != nil {
  271. wikiRepo.Close()
  272. }
  273. if !git.IsErrNotExist(err) {
  274. ctx.ServerError("GetBranchCommit", err)
  275. }
  276. return
  277. }
  278. defer func() {
  279. if wikiRepo != nil {
  280. wikiRepo.Close()
  281. }
  282. }()
  283. // get requested pagename
  284. pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
  285. if len(pageName) == 0 {
  286. pageName = "Home"
  287. }
  288. ctx.Data["PageURL"] = wiki_service.NameToSubURL(pageName)
  289. ctx.Data["old_title"] = pageName
  290. ctx.Data["Title"] = pageName
  291. ctx.Data["title"] = pageName
  292. ctx.Data["RequireHighlightJS"] = true
  293. //lookup filename in wiki - get filecontent, gitTree entry , real filename
  294. data, entry, _, noEntry := wikiContentsByName(ctx, commit, pageName)
  295. if noEntry {
  296. ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
  297. }
  298. if entry == nil || ctx.Written() {
  299. return
  300. }
  301. ctx.Data["content"] = string(data)
  302. ctx.Data["sidebarPresent"] = false
  303. ctx.Data["sidebarContent"] = ""
  304. ctx.Data["footerPresent"] = false
  305. ctx.Data["footerContent"] = ""
  306. }
  307. // Wiki renders single wiki page
  308. func Wiki(ctx *context.Context) {
  309. ctx.Data["PageIsWiki"] = true
  310. ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki) && !ctx.Repo.Repository.IsArchived
  311. if !ctx.Repo.Repository.HasWiki() {
  312. ctx.Data["Title"] = ctx.Tr("repo.wiki")
  313. ctx.HTML(200, tplWikiStart)
  314. return
  315. }
  316. wikiRepo, entry := renderViewPage(ctx)
  317. if ctx.Written() {
  318. if wikiRepo != nil {
  319. wikiRepo.Close()
  320. }
  321. return
  322. }
  323. defer func() {
  324. if wikiRepo != nil {
  325. wikiRepo.Close()
  326. }
  327. }()
  328. if entry == nil {
  329. ctx.Data["Title"] = ctx.Tr("repo.wiki")
  330. ctx.HTML(200, tplWikiStart)
  331. return
  332. }
  333. wikiPath := entry.Name()
  334. if markup.Type(wikiPath) != markdown.MarkupName {
  335. ext := strings.ToUpper(filepath.Ext(wikiPath))
  336. ctx.Data["FormatWarning"] = fmt.Sprintf("%s rendering is not supported at the moment. Rendered as Markdown.", ext)
  337. }
  338. // Get last change information.
  339. lastCommit, err := wikiRepo.GetCommitByPath(wikiPath)
  340. if err != nil {
  341. ctx.ServerError("GetCommitByPath", err)
  342. return
  343. }
  344. ctx.Data["Author"] = lastCommit.Author
  345. ctx.HTML(200, tplWikiView)
  346. }
  347. // WikiRevision renders file revision list of wiki page
  348. func WikiRevision(ctx *context.Context) {
  349. ctx.Data["PageIsWiki"] = true
  350. ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki) && !ctx.Repo.Repository.IsArchived
  351. if !ctx.Repo.Repository.HasWiki() {
  352. ctx.Data["Title"] = ctx.Tr("repo.wiki")
  353. ctx.HTML(200, tplWikiStart)
  354. return
  355. }
  356. wikiRepo, entry := renderRevisionPage(ctx)
  357. if ctx.Written() {
  358. if wikiRepo != nil {
  359. wikiRepo.Close()
  360. }
  361. return
  362. }
  363. defer func() {
  364. if wikiRepo != nil {
  365. wikiRepo.Close()
  366. }
  367. }()
  368. if entry == nil {
  369. ctx.Data["Title"] = ctx.Tr("repo.wiki")
  370. ctx.HTML(200, tplWikiStart)
  371. return
  372. }
  373. // Get last change information.
  374. wikiPath := entry.Name()
  375. lastCommit, err := wikiRepo.GetCommitByPath(wikiPath)
  376. if err != nil {
  377. ctx.ServerError("GetCommitByPath", err)
  378. return
  379. }
  380. ctx.Data["Author"] = lastCommit.Author
  381. ctx.HTML(200, tplWikiRevision)
  382. }
  383. // WikiPages render wiki pages list page
  384. func WikiPages(ctx *context.Context) {
  385. if !ctx.Repo.Repository.HasWiki() {
  386. ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
  387. return
  388. }
  389. ctx.Data["Title"] = ctx.Tr("repo.wiki.pages")
  390. ctx.Data["PageIsWiki"] = true
  391. ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki) && !ctx.Repo.Repository.IsArchived
  392. wikiRepo, commit, err := findWikiRepoCommit(ctx)
  393. if err != nil {
  394. if wikiRepo != nil {
  395. wikiRepo.Close()
  396. }
  397. return
  398. }
  399. entries, err := commit.ListEntries()
  400. if err != nil {
  401. if wikiRepo != nil {
  402. wikiRepo.Close()
  403. }
  404. ctx.ServerError("ListEntries", err)
  405. return
  406. }
  407. pages := make([]PageMeta, 0, len(entries))
  408. for _, entry := range entries {
  409. if !entry.IsRegular() {
  410. continue
  411. }
  412. c, err := wikiRepo.GetCommitByPath(entry.Name())
  413. if err != nil {
  414. if wikiRepo != nil {
  415. wikiRepo.Close()
  416. }
  417. ctx.ServerError("GetCommit", err)
  418. return
  419. }
  420. wikiName, err := wiki_service.FilenameToName(entry.Name())
  421. if err != nil {
  422. if models.IsErrWikiInvalidFileName(err) {
  423. continue
  424. }
  425. if wikiRepo != nil {
  426. wikiRepo.Close()
  427. }
  428. ctx.ServerError("WikiFilenameToName", err)
  429. return
  430. }
  431. pages = append(pages, PageMeta{
  432. Name: wikiName,
  433. SubURL: wiki_service.NameToSubURL(wikiName),
  434. UpdatedUnix: timeutil.TimeStamp(c.Author.When.Unix()),
  435. })
  436. }
  437. ctx.Data["Pages"] = pages
  438. defer func() {
  439. if wikiRepo != nil {
  440. wikiRepo.Close()
  441. }
  442. }()
  443. ctx.HTML(200, tplWikiPages)
  444. }
  445. // WikiRaw outputs raw blob requested by user (image for example)
  446. func WikiRaw(ctx *context.Context) {
  447. wikiRepo, commit, err := findWikiRepoCommit(ctx)
  448. if err != nil {
  449. if wikiRepo != nil {
  450. return
  451. }
  452. }
  453. providedPath := ctx.Params("*")
  454. var entry *git.TreeEntry
  455. if commit != nil {
  456. // Try to find a file with that name
  457. entry, err = findEntryForFile(commit, providedPath)
  458. if err != nil && !git.IsErrNotExist(err) {
  459. ctx.ServerError("findFile", err)
  460. return
  461. }
  462. if entry == nil {
  463. // Try to find a wiki page with that name
  464. if strings.HasSuffix(providedPath, ".md") {
  465. providedPath = providedPath[:len(providedPath)-3]
  466. }
  467. wikiPath := wiki_service.NameToFilename(providedPath)
  468. entry, err = findEntryForFile(commit, wikiPath)
  469. if err != nil && !git.IsErrNotExist(err) {
  470. ctx.ServerError("findFile", err)
  471. return
  472. }
  473. }
  474. }
  475. if entry != nil {
  476. if err = ServeBlob(ctx, entry.Blob()); err != nil {
  477. ctx.ServerError("ServeBlob", err)
  478. }
  479. return
  480. }
  481. ctx.NotFound("findEntryForFile", nil)
  482. }
  483. // NewWiki render wiki create page
  484. func NewWiki(ctx *context.Context) {
  485. ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
  486. ctx.Data["PageIsWiki"] = true
  487. ctx.Data["RequireSimpleMDE"] = true
  488. if !ctx.Repo.Repository.HasWiki() {
  489. ctx.Data["title"] = "Home"
  490. }
  491. ctx.HTML(200, tplWikiNew)
  492. }
  493. // NewWikiPost response for wiki create request
  494. func NewWikiPost(ctx *context.Context, form auth.NewWikiForm) {
  495. ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
  496. ctx.Data["PageIsWiki"] = true
  497. ctx.Data["RequireSimpleMDE"] = true
  498. if ctx.HasError() {
  499. ctx.HTML(200, tplWikiNew)
  500. return
  501. }
  502. if util.IsEmptyString(form.Title) {
  503. ctx.RenderWithErr(ctx.Tr("repo.issues.new.title_empty"), tplWikiNew, form)
  504. return
  505. }
  506. wikiName := wiki_service.NormalizeWikiName(form.Title)
  507. if len(form.Message) == 0 {
  508. form.Message = ctx.Tr("repo.editor.add", form.Title)
  509. }
  510. if err := wiki_service.AddWikiPage(ctx.User, ctx.Repo.Repository, wikiName, form.Content, form.Message); err != nil {
  511. if models.IsErrWikiReservedName(err) {
  512. ctx.Data["Err_Title"] = true
  513. ctx.RenderWithErr(ctx.Tr("repo.wiki.reserved_page", wikiName), tplWikiNew, &form)
  514. } else if models.IsErrWikiAlreadyExist(err) {
  515. ctx.Data["Err_Title"] = true
  516. ctx.RenderWithErr(ctx.Tr("repo.wiki.page_already_exists"), tplWikiNew, &form)
  517. } else {
  518. ctx.ServerError("AddWikiPage", err)
  519. }
  520. return
  521. }
  522. ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + wiki_service.NameToSubURL(wikiName))
  523. }
  524. // EditWiki render wiki modify page
  525. func EditWiki(ctx *context.Context) {
  526. ctx.Data["PageIsWiki"] = true
  527. ctx.Data["PageIsWikiEdit"] = true
  528. ctx.Data["RequireSimpleMDE"] = true
  529. if !ctx.Repo.Repository.HasWiki() {
  530. ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
  531. return
  532. }
  533. renderEditPage(ctx)
  534. if ctx.Written() {
  535. return
  536. }
  537. ctx.HTML(200, tplWikiNew)
  538. }
  539. // EditWikiPost response for wiki modify request
  540. func EditWikiPost(ctx *context.Context, form auth.NewWikiForm) {
  541. ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
  542. ctx.Data["PageIsWiki"] = true
  543. ctx.Data["RequireSimpleMDE"] = true
  544. if ctx.HasError() {
  545. ctx.HTML(200, tplWikiNew)
  546. return
  547. }
  548. oldWikiName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
  549. newWikiName := wiki_service.NormalizeWikiName(form.Title)
  550. if len(form.Message) == 0 {
  551. form.Message = ctx.Tr("repo.editor.update", form.Title)
  552. }
  553. if err := wiki_service.EditWikiPage(ctx.User, ctx.Repo.Repository, oldWikiName, newWikiName, form.Content, form.Message); err != nil {
  554. ctx.ServerError("EditWikiPage", err)
  555. return
  556. }
  557. ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + wiki_service.NameToSubURL(newWikiName))
  558. }
  559. // DeleteWikiPagePost delete wiki page
  560. func DeleteWikiPagePost(ctx *context.Context) {
  561. wikiName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
  562. if len(wikiName) == 0 {
  563. wikiName = "Home"
  564. }
  565. if err := wiki_service.DeleteWikiPage(ctx.User, ctx.Repo.Repository, wikiName); err != nil {
  566. ctx.ServerError("DeleteWikiPage", err)
  567. return
  568. }
  569. ctx.JSON(200, map[string]interface{}{
  570. "redirect": ctx.Repo.RepoLink + "/wiki/",
  571. })
  572. }