mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-29 11:48:56 +03:00
wiki: finish edit
This commit is contained in:
parent
392f3ee210
commit
e42fcb033d
14 changed files with 262 additions and 152 deletions
|
@ -378,6 +378,7 @@ func runWeb(ctx *cli.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
reqRepoAdmin := middleware.RequireRepoAdmin()
|
reqRepoAdmin := middleware.RequireRepoAdmin()
|
||||||
|
reqRepoPusher := middleware.RequireRepoPusher()
|
||||||
|
|
||||||
// ***** START: Organization *****
|
// ***** START: Organization *****
|
||||||
m.Group("/org", func() {
|
m.Group("/org", func() {
|
||||||
|
@ -534,13 +535,14 @@ func runWeb(ctx *cli.Context) {
|
||||||
|
|
||||||
m.Group("/wiki", func() {
|
m.Group("/wiki", func() {
|
||||||
m.Get("/?:page", repo.Wiki)
|
m.Get("/?:page", repo.Wiki)
|
||||||
m.Get("/_list", repo.WikiList)
|
m.Get("/_pages", repo.WikiPages)
|
||||||
|
|
||||||
m.Group("", func() {
|
m.Group("", func() {
|
||||||
m.Combo("/_new").Get(repo.NewWiki).
|
m.Combo("/_new").Get(repo.NewWiki).
|
||||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost)
|
Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost)
|
||||||
m.Get("/:page/_edit", repo.EditWiki)
|
m.Combo("/:page/_edit").Get(repo.EditWiki).
|
||||||
}, reqSignIn)
|
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
|
||||||
|
}, reqSignIn, reqRepoPusher)
|
||||||
}, middleware.RepoRef())
|
}, middleware.RepoRef())
|
||||||
|
|
||||||
m.Get("/archive/*", repo.Download)
|
m.Get("/archive/*", repo.Download)
|
||||||
|
|
|
@ -539,10 +539,15 @@ wiki = Wiki
|
||||||
wiki.welcome = Welcome to Wiki!
|
wiki.welcome = Welcome to Wiki!
|
||||||
wiki.welcome_desc = Wiki is the place where you would like to document your project together and make it better.
|
wiki.welcome_desc = Wiki is the place where you would like to document your project together and make it better.
|
||||||
wiki.create_first_page = Create the first page
|
wiki.create_first_page = Create the first page
|
||||||
|
wiki.page = Page
|
||||||
|
wiki.filter_page = Filter page
|
||||||
wiki.new_page = Create New Page
|
wiki.new_page = Create New Page
|
||||||
wiki.default_commit_message = Write a note about this update (optional).
|
wiki.default_commit_message = Write a note about this update (optional).
|
||||||
wiki.save_page = Save Page
|
wiki.save_page = Save Page
|
||||||
wiki.last_commit_info = %s edited this page %s
|
wiki.last_commit_info = %s edited this page %s
|
||||||
|
wiki.edit_page_button = Edit
|
||||||
|
wiki.new_page_button = New Page
|
||||||
|
wiki.page_already_exists = Wiki page with same name already exists.
|
||||||
|
|
||||||
settings = Settings
|
settings = Settings
|
||||||
settings.options = Options
|
settings.options = Options
|
||||||
|
|
|
@ -107,6 +107,26 @@ func (err ErrUserHasOrgs) Error() string {
|
||||||
return fmt.Sprintf("user still has membership of organizations [uid: %d]", err.UID)
|
return fmt.Sprintf("user still has membership of organizations [uid: %d]", err.UID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// __ __.__ __ .__
|
||||||
|
// / \ / \__| | _|__|
|
||||||
|
// \ \/\/ / | |/ / |
|
||||||
|
// \ /| | <| |
|
||||||
|
// \__/\ / |__|__|_ \__|
|
||||||
|
// \/ \/
|
||||||
|
|
||||||
|
type ErrWikiAlreadyExist struct {
|
||||||
|
Title string
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsErrWikiAlreadyExist(err error) bool {
|
||||||
|
_, ok := err.(ErrWikiAlreadyExist)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrWikiAlreadyExist) Error() string {
|
||||||
|
return fmt.Sprintf("wiki page already exists [title: %s]", err.Title)
|
||||||
|
}
|
||||||
|
|
||||||
// __________ ___. .__ .__ ____ __.
|
// __________ ___. .__ .__ ____ __.
|
||||||
// \______ \__ _\_ |__ | | |__| ____ | |/ _|____ ___.__.
|
// \______ \__ _\_ |__ | | |__| ____ | |/ _|____ ___.__.
|
||||||
// | ___/ | \ __ \| | | |/ ___\ | <_/ __ < | |
|
// | ___/ | \ __ \| | | |/ ___\ | <_/ __ < | |
|
||||||
|
|
|
@ -252,7 +252,7 @@ func (pr *PullRequest) testPatch() (err error) {
|
||||||
|
|
||||||
// Checkout base branch.
|
// Checkout base branch.
|
||||||
_, stderr, err := process.ExecDir(-1, pr.BaseRepo.LocalCopyPath(),
|
_, stderr, err := process.ExecDir(-1, pr.BaseRepo.LocalCopyPath(),
|
||||||
fmt.Sprintf("PullRequest.Merge(git checkout): %s", pr.BaseRepo.ID),
|
fmt.Sprintf("PullRequest.Merge(git checkout): %v", pr.BaseRepo.ID),
|
||||||
"git", "checkout", pr.BaseBranch)
|
"git", "checkout", pr.BaseBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("git checkout: %s", stderr)
|
return fmt.Errorf("git checkout: %s", stderr)
|
||||||
|
|
|
@ -7,6 +7,7 @@ package models
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -108,8 +109,8 @@ func (repo *Repository) UpdateLocalWiki() error {
|
||||||
return updateLocalCopy(repo.WikiPath(), repo.LocalWikiPath())
|
return updateLocalCopy(repo.WikiPath(), repo.LocalWikiPath())
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddWikiPage adds new page to repository wiki.
|
// updateWikiPage adds new page to repository wiki.
|
||||||
func (repo *Repository) AddWikiPage(doer *User, title, content, message string) (err error) {
|
func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
|
||||||
wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
|
wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
|
||||||
defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID))
|
defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID))
|
||||||
|
|
||||||
|
@ -133,8 +134,18 @@ func (repo *Repository) AddWikiPage(doer *User, title, content, message string)
|
||||||
return fmt.Errorf("UpdateLocalWiki: %v", err)
|
return fmt.Errorf("UpdateLocalWiki: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
title = strings.Replace(title, "/", " ", -1)
|
title = ToWikiPageName(strings.Replace(title, "/", " ", -1))
|
||||||
filename := path.Join(localPath, title+".md")
|
filename := path.Join(localPath, title+".md")
|
||||||
|
|
||||||
|
// If not a new file, show perform update not create.
|
||||||
|
if isNew {
|
||||||
|
if com.IsExist(filename) {
|
||||||
|
return ErrWikiAlreadyExist{filename}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
os.Remove(path.Join(localPath, oldTitle+".md"))
|
||||||
|
}
|
||||||
|
|
||||||
if err = ioutil.WriteFile(filename, []byte(content), 0666); err != nil {
|
if err = ioutil.WriteFile(filename, []byte(content), 0666); err != nil {
|
||||||
return fmt.Errorf("WriteFile: %v", err)
|
return fmt.Errorf("WriteFile: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -152,3 +163,11 @@ func (repo *Repository) AddWikiPage(doer *User, title, content, message string)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *Repository) AddWikiPage(doer *User, title, content, message string) error {
|
||||||
|
return repo.updateWikiPage(doer, "", title, content, message, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *Repository) EditWikiPage(doer *User, oldTitle, title, content, message string) error {
|
||||||
|
return repo.updateWikiPage(doer, oldTitle, title, content, message, false)
|
||||||
|
}
|
||||||
|
|
|
@ -246,9 +246,10 @@ func (f *EditReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
|
||||||
// \/ \/
|
// \/ \/
|
||||||
|
|
||||||
type NewWikiForm struct {
|
type NewWikiForm struct {
|
||||||
Title string `binding:"Required"`
|
OldTitle string
|
||||||
Content string `binding:"Required"`
|
Title string `binding:"Required"`
|
||||||
Message string
|
Content string `binding:"Required"`
|
||||||
|
Message string
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: use code generation to generate this method.
|
// FIXME: use code generation to generate this method.
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -59,7 +59,7 @@ type Context struct {
|
||||||
IsSigned bool
|
IsSigned bool
|
||||||
IsBasicAuth bool
|
IsBasicAuth bool
|
||||||
|
|
||||||
Repo RepoContext
|
Repo *RepoContext
|
||||||
|
|
||||||
Org struct {
|
Org struct {
|
||||||
IsOwner bool
|
IsOwner bool
|
||||||
|
@ -73,17 +73,22 @@ type Context struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsOwner returns true if current user is the owner of repository.
|
// IsOwner returns true if current user is the owner of repository.
|
||||||
func (r RepoContext) IsOwner() bool {
|
func (r *RepoContext) IsOwner() bool {
|
||||||
return r.AccessMode >= models.ACCESS_MODE_OWNER
|
return r.AccessMode >= models.ACCESS_MODE_OWNER
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAdmin returns true if current user has admin or higher access of repository.
|
// IsAdmin returns true if current user has admin or higher access of repository.
|
||||||
func (r RepoContext) IsAdmin() bool {
|
func (r *RepoContext) IsAdmin() bool {
|
||||||
return r.AccessMode >= models.ACCESS_MODE_ADMIN
|
return r.AccessMode >= models.ACCESS_MODE_ADMIN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsPusher returns true if current user has write or higher access of repository.
|
||||||
|
func (r *RepoContext) IsPusher() bool {
|
||||||
|
return r.AccessMode >= models.ACCESS_MODE_WRITE
|
||||||
|
}
|
||||||
|
|
||||||
// Return if the current user has read access for this repository
|
// Return if the current user has read access for this repository
|
||||||
func (r RepoContext) HasAccess() bool {
|
func (r *RepoContext) HasAccess() bool {
|
||||||
return r.AccessMode >= models.ACCESS_MODE_READ
|
return r.AccessMode >= models.ACCESS_MODE_READ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -225,6 +224,8 @@ func RetrieveBaseRepo(ctx *Context, repo *models.Repository) {
|
||||||
|
|
||||||
func RepoAssignment(args ...bool) macaron.Handler {
|
func RepoAssignment(args ...bool) macaron.Handler {
|
||||||
return func(ctx *Context) {
|
return func(ctx *Context) {
|
||||||
|
ctx.Repo = &RepoContext{}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
displayBare bool // To display bare page if it is a bare repo.
|
displayBare bool // To display bare page if it is a bare repo.
|
||||||
)
|
)
|
||||||
|
@ -335,6 +336,7 @@ func RepoAssignment(args ...bool) macaron.Handler {
|
||||||
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
||||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
|
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
|
||||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
||||||
|
ctx.Data["IsRepositoryPusher"] = ctx.Repo.IsPusher()
|
||||||
|
|
||||||
ctx.Data["DisableSSH"] = setting.DisableSSH
|
ctx.Data["DisableSSH"] = setting.DisableSSH
|
||||||
ctx.Repo.CloneLink, err = repo.CloneLink()
|
ctx.Repo.CloneLink, err = repo.CloneLink()
|
||||||
|
@ -397,11 +399,15 @@ func RepoAssignment(args ...bool) macaron.Handler {
|
||||||
func RequireRepoAdmin() macaron.Handler {
|
func RequireRepoAdmin() macaron.Handler {
|
||||||
return func(ctx *Context) {
|
return func(ctx *Context) {
|
||||||
if !ctx.Repo.IsAdmin() {
|
if !ctx.Repo.IsAdmin() {
|
||||||
if !ctx.IsSigned {
|
ctx.Handle(404, ctx.Req.RequestURI, nil)
|
||||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
|
return
|
||||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
}
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RequireRepoPusher() macaron.Handler {
|
||||||
|
return func(ctx *Context) {
|
||||||
|
if !ctx.Repo.IsPusher() {
|
||||||
ctx.Handle(404, ctx.Req.RequestURI, nil)
|
ctx.Handle(404, ctx.Req.RequestURI, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,11 @@ function initRepository() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wiki
|
||||||
|
if ($('.repository.wiki.view').length > 0) {
|
||||||
|
initFilterSearchDropdown('.choose.page .dropdown');
|
||||||
|
}
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
if ($('.repository.settings.options').length > 0) {
|
if ($('.repository.settings.options').length > 0) {
|
||||||
$('#repo_name').keyup(function () {
|
$('#repo_name').keyup(function () {
|
||||||
|
@ -314,23 +319,23 @@ function initRepository() {
|
||||||
$('#edit-title').click(editTitleToggle);
|
$('#edit-title').click(editTitleToggle);
|
||||||
$('#cancel-edit-title').click(editTitleToggle);
|
$('#cancel-edit-title').click(editTitleToggle);
|
||||||
$('#save-edit-title').click(editTitleToggle).
|
$('#save-edit-title').click(editTitleToggle).
|
||||||
click(function () {
|
click(function () {
|
||||||
if ($edit_input.val().length == 0 ||
|
if ($edit_input.val().length == 0 ||
|
||||||
$edit_input.val() == $issue_title.text()) {
|
$edit_input.val() == $issue_title.text()) {
|
||||||
$edit_input.val($issue_title.text());
|
$edit_input.val($issue_title.text());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.post($(this).data('update-url'), {
|
$.post($(this).data('update-url'), {
|
||||||
"_csrf": csrf,
|
"_csrf": csrf,
|
||||||
"title": $edit_input.val()
|
"title": $edit_input.val()
|
||||||
},
|
},
|
||||||
function (data) {
|
function (data) {
|
||||||
$edit_input.val(data.title);
|
$edit_input.val(data.title);
|
||||||
$issue_title.text(data.title);
|
$issue_title.text(data.title);
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Edit issue or comment content
|
// Edit issue or comment content
|
||||||
$('.edit-content').click(function () {
|
$('.edit-content').click(function () {
|
||||||
|
@ -729,9 +734,9 @@ $(document).ready(function () {
|
||||||
// Show exact time
|
// Show exact time
|
||||||
$('.time-since').each(function () {
|
$('.time-since').each(function () {
|
||||||
$(this).addClass('poping up').
|
$(this).addClass('poping up').
|
||||||
attr('data-content', $(this).attr('title')).
|
attr('data-content', $(this).attr('title')).
|
||||||
attr('data-variation', 'inverted tiny').
|
attr('data-variation', 'inverted tiny').
|
||||||
attr('title', '');
|
attr('title', '');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Semantic UI modules.
|
// Semantic UI modules.
|
||||||
|
|
|
@ -6,6 +6,7 @@ package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gogits/git-shell"
|
"github.com/gogits/git-shell"
|
||||||
|
|
||||||
|
@ -21,6 +22,81 @@ const (
|
||||||
WIKI_NEW base.TplName = "repo/wiki/new"
|
WIKI_NEW base.TplName = "repo/wiki/new"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PageMeta struct {
|
||||||
|
Name string
|
||||||
|
URL string
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderWikiPage(ctx *middleware.Context, isViewPage bool) (*git.Repository, string) {
|
||||||
|
wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, "OpenRepository", err)
|
||||||
|
return nil, ""
|
||||||
|
}
|
||||||
|
commit, err := wikiRepo.GetCommitOfBranch("master")
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, "GetCommitOfBranch", err)
|
||||||
|
return nil, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get page list.
|
||||||
|
if isViewPage {
|
||||||
|
entries, err := commit.ListEntries()
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, "ListEntries", err)
|
||||||
|
return nil, ""
|
||||||
|
}
|
||||||
|
pages := make([]PageMeta, len(entries))
|
||||||
|
for i := range entries {
|
||||||
|
name := strings.TrimSuffix(entries[i].Name(), ".md")
|
||||||
|
pages[i] = PageMeta{
|
||||||
|
Name: name,
|
||||||
|
URL: models.ToWikiPageURL(name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.Data["Pages"] = pages
|
||||||
|
}
|
||||||
|
|
||||||
|
pageURL := ctx.Params(":page")
|
||||||
|
if len(pageURL) == 0 {
|
||||||
|
pageURL = "Home"
|
||||||
|
}
|
||||||
|
ctx.Data["PageURL"] = pageURL
|
||||||
|
|
||||||
|
pageName := models.ToWikiPageName(pageURL)
|
||||||
|
ctx.Data["old_title"] = pageName
|
||||||
|
ctx.Data["Title"] = pageName
|
||||||
|
ctx.Data["title"] = pageName
|
||||||
|
ctx.Data["RequireHighlightJS"] = true
|
||||||
|
|
||||||
|
blob, err := commit.GetBlobByPath(pageName + ".md")
|
||||||
|
if err != nil {
|
||||||
|
if git.IsErrNotExist(err) {
|
||||||
|
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
|
||||||
|
} else {
|
||||||
|
ctx.Handle(500, "GetBlobByPath", err)
|
||||||
|
}
|
||||||
|
return nil, ""
|
||||||
|
}
|
||||||
|
r, err := blob.Data()
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, "Data", err)
|
||||||
|
return nil, ""
|
||||||
|
}
|
||||||
|
data, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, "ReadAll", err)
|
||||||
|
return nil, ""
|
||||||
|
}
|
||||||
|
if isViewPage {
|
||||||
|
ctx.Data["content"] = string(base.RenderMarkdown(data, ctx.Repo.RepoLink))
|
||||||
|
} else {
|
||||||
|
ctx.Data["content"] = string(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return wikiRepo, pageName
|
||||||
|
}
|
||||||
|
|
||||||
func Wiki(ctx *middleware.Context) {
|
func Wiki(ctx *middleware.Context) {
|
||||||
ctx.Data["PageIsWiki"] = true
|
ctx.Data["PageIsWiki"] = true
|
||||||
|
|
||||||
|
@ -30,47 +106,13 @@ func Wiki(ctx *middleware.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
|
wikiRepo, pageName := renderWikiPage(ctx, true)
|
||||||
if err != nil {
|
if ctx.Written() {
|
||||||
ctx.Handle(500, "OpenRepository", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
commit, err := wikiRepo.GetCommitOfBranch("master")
|
|
||||||
if err != nil {
|
|
||||||
ctx.Handle(500, "GetCommitOfBranch", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
page := models.ToWikiPageName(ctx.Params(":page"))
|
|
||||||
if len(page) == 0 {
|
|
||||||
page = "Home"
|
|
||||||
}
|
|
||||||
ctx.Data["Title"] = page
|
|
||||||
ctx.Data["RequireHighlightJS"] = true
|
|
||||||
|
|
||||||
blob, err := commit.GetBlobByPath(page + ".md")
|
|
||||||
if err != nil {
|
|
||||||
if git.IsErrNotExist(err) {
|
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_list")
|
|
||||||
} else {
|
|
||||||
ctx.Handle(500, "GetBlobByPath", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r, err := blob.Data()
|
|
||||||
if err != nil {
|
|
||||||
ctx.Handle(500, "Data", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
ctx.Handle(500, "ReadAll", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Content"] = string(base.RenderMarkdown(data, ctx.Repo.RepoLink))
|
|
||||||
|
|
||||||
// Get last change information.
|
// Get last change information.
|
||||||
lastCommit, err := wikiRepo.GetCommitByPath(page + ".md")
|
lastCommit, err := wikiRepo.GetCommitByPath(pageName + ".md")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "GetCommitByPath", err)
|
ctx.Handle(500, "GetCommitByPath", err)
|
||||||
return
|
return
|
||||||
|
@ -80,7 +122,7 @@ func Wiki(ctx *middleware.Context) {
|
||||||
ctx.HTML(200, WIKI_VIEW)
|
ctx.HTML(200, WIKI_VIEW)
|
||||||
}
|
}
|
||||||
|
|
||||||
func WikiList(ctx *middleware.Context) {
|
func WikiPages(ctx *middleware.Context) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +149,12 @@ func NewWikiPost(ctx *middleware.Context, form auth.NewWikiForm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ctx.Repo.Repository.AddWikiPage(ctx.User, form.Title, form.Content, form.Message); err != nil {
|
if err := ctx.Repo.Repository.AddWikiPage(ctx.User, form.Title, form.Content, form.Message); err != nil {
|
||||||
ctx.Handle(500, "AddWikiPage", err)
|
if models.IsErrWikiAlreadyExist(err) {
|
||||||
|
ctx.Data["Err_Title"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("repo.wiki.page_already_exists"), WIKI_NEW, &form)
|
||||||
|
} else {
|
||||||
|
ctx.Handle(500, "AddWikiPage", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,5 +162,37 @@ func NewWikiPost(ctx *middleware.Context, form auth.NewWikiForm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditWiki(ctx *middleware.Context) {
|
func EditWiki(ctx *middleware.Context) {
|
||||||
ctx.PlainText(200, []byte(ctx.Params(":page")))
|
ctx.Data["PageIsWiki"] = true
|
||||||
|
ctx.Data["PageIsWikiEdit"] = true
|
||||||
|
ctx.Data["RequireSimpleMDE"] = true
|
||||||
|
|
||||||
|
if !ctx.Repo.Repository.HasWiki() {
|
||||||
|
ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
renderWikiPage(ctx, false)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.HTML(200, WIKI_NEW)
|
||||||
|
}
|
||||||
|
|
||||||
|
func EditWikiPost(ctx *middleware.Context, form auth.NewWikiForm) {
|
||||||
|
ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page")
|
||||||
|
ctx.Data["PageIsWiki"] = true
|
||||||
|
ctx.Data["RequireSimpleMDE"] = true
|
||||||
|
|
||||||
|
if ctx.HasError() {
|
||||||
|
ctx.HTML(200, WIKI_NEW)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ctx.Repo.Repository.EditWikiPage(ctx.User, form.OldTitle, form.Title, form.Content, form.Message); err != nil {
|
||||||
|
ctx.Handle(500, "EditWikiPage", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/" + models.ToWikiPageURL(form.Title))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
<div id="body-nav" class="repo-nav">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-7">
|
|
||||||
<h3 class="name"><i class="fa fa-book fa-lg"></i><a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a> / <a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Repository.Name}}">{{.Repository.Name}}</a> {{if .Repository.IsPrivate}}<span class="label label-default">Private</span>{{else if .Repository.IsMirror}}<span class="label label-default">Mirror</span>{{end}}</h3>
|
|
||||||
<p class="desc">{{.Repository.DescriptionHtml}}{{if .Repository.Website}} <a href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5 actions text-right clone-group-btn">
|
|
||||||
{{if not .IsBareRepo}}
|
|
||||||
<div class="btn-group" id="repo-clone">
|
|
||||||
<a class="btn btn-default" href="{{.RepoLink}}/archive/{{.BranchName}}/{{.Repository.Name}}.zip"><i class="fa fa-download fa-lg fa-m"></i></a>
|
|
||||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu clone-group-btn dropdown-menu-right no-propagation">
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="btn btn-default" data-link="{{.CloneLink.SSH}}" type="button">SSH</button>
|
|
||||||
<button class="btn btn-default" data-link="{{.CloneLink.HTTPS}}" type="button">HTTPS</button>
|
|
||||||
</span>
|
|
||||||
<input type="text" class="form-control clone-group-url" value="" readonly id="repo-clone-ipt"/>
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="btn btn-default" type="button" data-toggle="tooltip" title="copy to clipboard" data-placement="top" data-init="copy" data-copy-val="val" data-copy-from="#repo-clone-ipt"><i class="fa fa-copy"></i></button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p class="help-block text-center">Need help cloning? Visit <a target="_blank" href="https://help.github.com/articles/fork-a-repo">Help</a>!</p>
|
|
||||||
<hr/>
|
|
||||||
<div class="clone-zip text-center">
|
|
||||||
<a class="btn btn-success btn-lg" href="{{.RepoLink}}/archive/{{.BranchName}}/{{.Repository.Name}}.zip" rel="nofollow"><i class="fa fa-suitcase"></i>Download ZIP</a>
|
|
||||||
<a class="btn btn-success btn-lg" href="{{.RepoLink}}/archive/{{.BranchName}}/{{.Repository.Name}}.tar.gz" rel="nofollow"><i class="fa fa-suitcase"></i>Download TAR.GZ</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{if .IsSigned}}
|
|
||||||
<div class="btn-group {{if .IsRepositoryWatching}}watching{{else}}no-watching{{end}}" id="repo-watching" data-watch="{{AppSubUrl}}/{{.Owner.Name}}/{{.Repository.Name}}/action/watch" data-unwatch="{{AppSubUrl}}/{{.Owner.Name}}/{{.Repository.Name}}/action/unwatch">
|
|
||||||
{{if .IsRepositoryWatching}}
|
|
||||||
<button type="button" class="btn btn-default"><i class="fa fa-eye fa-lg fa-m"></i></button>
|
|
||||||
{{else}}
|
|
||||||
<button type="button" class="btn btn-default"><i class="fa fa-eye-slash fa-lg fa-m"></i></button>
|
|
||||||
{{end}}
|
|
||||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu dropdown-menu-right">
|
|
||||||
<div class="dropdown-item text-left to-unwatch">
|
|
||||||
<h4 role="presentation" class="dropdown-header {{if not .IsRepositoryWatching}}text-primary{{end}}">Not Watching</h4>
|
|
||||||
<p class="description">You only receive notifications for conversations in which you participate or are @mentioned.</p>
|
|
||||||
<p class="divider"></p>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-item text-left to-watch">
|
|
||||||
<h4 role="presentation" class="dropdown-header {{if .IsRepositoryWatching}}text-primary{{end}}">Watching</h4>
|
|
||||||
<p class="description">You receive notifications for all conversations in this repository.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
<!-- <div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="top" title="Star"><i class="fa fa-star"></i> {{.Repository.NumStars}}</button>
|
|
||||||
</div> -->
|
|
||||||
{{end}}
|
|
||||||
<!-- <div class="btn-group">
|
|
||||||
<a type="button" {{if not .IsRepositoryOwner}}href="{{AppSubUrl}}/{{.Username}}/{{.Reponame}}/fork"{{end}} class="btn btn-default" data-toggle="tooltip" data-placement="top" title="Fork"><i class="fa fa-code-fork fa-lg"></i> {{.Repository.NumForks}}</a>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -3,16 +3,23 @@
|
||||||
{{template "repo/header" .}}
|
{{template "repo/header" .}}
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
{{template "repo/sidebar" .}}
|
{{template "repo/sidebar" .}}
|
||||||
|
{{template "base/alert" .}}
|
||||||
<div class="ui header">
|
<div class="ui header">
|
||||||
{{.i18n.Tr "repo.wiki.new_page"}}
|
{{.i18n.Tr "repo.wiki.new_page"}}
|
||||||
|
{{if .PageIsWikiEdit}}
|
||||||
|
<div class="ui right">
|
||||||
|
<a class="ui green small button" href="{{.RepoLink}}/wiki/_new">{{.i18n.Tr "repo.wiki.new_page_button"}}</a>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<form class="ui form" action="{{.Link}}" method="post">
|
<form class="ui form" action="{{.Link}}" method="post">
|
||||||
{{.CsrfTokenHtml}}
|
{{.CsrfTokenHtml}}
|
||||||
<div class="field">
|
<input type="hidden" name="old_title" value="{{.old_title}}">
|
||||||
|
<div class="field {{if .Err_Title}}error{{end}}">
|
||||||
<input name="title" value="{{.title}}" autofocus required>
|
<input name="title" value="{{.title}}" autofocus required>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<textarea id="edit-area" name="content" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "repo.wiki.welcome"}}</textarea required>
|
<textarea id="edit-area" name="content" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}">{{if .PageIsWikiEdit}}{{.content}}{{else}}{{.i18n.Tr "repo.wiki.welcome"}}{{end}}</textarea required>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input name="message" placeholder="{{.i18n.Tr "repo.wiki.default_commit_message"}}">
|
<input name="message" placeholder="{{.i18n.Tr "repo.wiki.default_commit_message"}}">
|
||||||
|
|
|
@ -3,15 +3,43 @@
|
||||||
{{template "repo/header" .}}
|
{{template "repo/header" .}}
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
{{template "repo/sidebar" .}}
|
{{template "repo/sidebar" .}}
|
||||||
|
<div class="choose page">
|
||||||
|
<div class="ui floating filter dropdown" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}">
|
||||||
|
<div class="ui basic small button">
|
||||||
|
<span class="text">
|
||||||
|
{{.i18n.Tr "repo.wiki.page"}}:
|
||||||
|
<strong>{{.title}}</strong>
|
||||||
|
</span>
|
||||||
|
<i class="dropdown icon"></i>
|
||||||
|
</div>
|
||||||
|
<div class="menu">
|
||||||
|
<div class="ui icon search input">
|
||||||
|
<i class="filter icon"></i>
|
||||||
|
<input name="search" placeholder="{{.i18n.Tr "repo.wiki.filter_page"}}...">
|
||||||
|
</div>
|
||||||
|
<div class="scrolling menu" {{if .IsTag}}style="display: none"{{end}}>
|
||||||
|
{{range .Pages}}
|
||||||
|
<div class="item {{if eq $.Title .Name}}selected{{end}}" data-url="{{$.RepoLink}}/wiki/{{.URL}}">{{.Name}}</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="ui dividing header">
|
<div class="ui dividing header">
|
||||||
{{.Title}}
|
{{.title}}
|
||||||
|
{{if .IsRepositoryPusher}}
|
||||||
|
<div class="ui right">
|
||||||
|
<a class="ui small button" href="{{.RepoLink}}/wiki/{{.PageURL}}/_edit">{{.i18n.Tr "repo.wiki.edit_page_button"}}</a>
|
||||||
|
<a class="ui green small button" href="{{.RepoLink}}/wiki/_new">{{.i18n.Tr "repo.wiki.new_page_button"}}</a>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
<div class="ui sub header">
|
<div class="ui sub header">
|
||||||
{{$timeSince := TimeSince .Author.When $.Lang}}
|
{{$timeSince := TimeSince .Author.When $.Lang}}
|
||||||
{{.i18n.Tr "repo.wiki.last_commit_info" .Author.Name $timeSince | Safe}}
|
{{.i18n.Tr "repo.wiki.last_commit_info" .Author.Name $timeSince | Safe}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui segment markdown">
|
<div class="ui segment markdown">
|
||||||
{{.Content | Str2html}}
|
{{.content | Str2html}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue