wiki: finish edit

This commit is contained in:
Unknwon 2015-11-27 01:50:38 -05:00
parent 392f3ee210
commit e42fcb033d
14 changed files with 262 additions and 152 deletions

View file

@ -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)

View file

@ -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

View file

@ -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)
}
// __________ ___. .__ .__ ____ __. // __________ ___. .__ .__ ____ __.
// \______ \__ _\_ |__ | | |__| ____ | |/ _|____ ___.__. // \______ \__ _\_ |__ | | |__| ____ | |/ _|____ ___.__.
// | ___/ | \ __ \| | | |/ ___\ | <_/ __ < | | // | ___/ | \ __ \| | | |/ ___\ | <_/ __ < | |

View file

@ -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)

View file

@ -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)
}

View file

@ -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

View file

@ -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
} }

View file

@ -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
} }

View file

@ -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.

View file

@ -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))
} }

View file

@ -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>&nbsp;{{.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>&nbsp;{{.Repository.NumForks}}</a>
</div> -->
</div>
</div>
</div>
</div>

View file

@ -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"}}">

View file

@ -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>