| @@ -378,6 +378,7 @@ func runWeb(ctx *cli.Context) { | |||
| } | |||
| reqRepoAdmin := middleware.RequireRepoAdmin() | |||
| reqRepoPusher := middleware.RequireRepoPusher() | |||
| // ***** START: Organization ***** | |||
| m.Group("/org", func() { | |||
| @@ -534,13 +535,14 @@ func runWeb(ctx *cli.Context) { | |||
| m.Group("/wiki", func() { | |||
| m.Get("/?:page", repo.Wiki) | |||
| m.Get("/_list", repo.WikiList) | |||
| m.Get("/_pages", repo.WikiPages) | |||
| m.Group("", func() { | |||
| m.Combo("/_new").Get(repo.NewWiki). | |||
| Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost) | |||
| m.Get("/:page/_edit", repo.EditWiki) | |||
| }, reqSignIn) | |||
| m.Combo("/:page/_edit").Get(repo.EditWiki). | |||
| Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost) | |||
| }, reqSignIn, reqRepoPusher) | |||
| }, middleware.RepoRef()) | |||
| m.Get("/archive/*", repo.Download) | |||
| @@ -539,10 +539,15 @@ wiki = 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.create_first_page = Create the first page | |||
| wiki.page = Page | |||
| wiki.filter_page = Filter page | |||
| wiki.new_page = Create New Page | |||
| wiki.default_commit_message = Write a note about this update (optional). | |||
| wiki.save_page = Save Page | |||
| 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.options = Options | |||
| @@ -107,6 +107,26 @@ func (err ErrUserHasOrgs) Error() string { | |||
| 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. | |||
| _, 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) | |||
| if err != nil { | |||
| return fmt.Errorf("git checkout: %s", stderr) | |||
| @@ -7,6 +7,7 @@ package models | |||
| import ( | |||
| "fmt" | |||
| "io/ioutil" | |||
| "os" | |||
| "path" | |||
| "path/filepath" | |||
| "strings" | |||
| @@ -108,8 +109,8 @@ func (repo *Repository) UpdateLocalWiki() error { | |||
| return updateLocalCopy(repo.WikiPath(), repo.LocalWikiPath()) | |||
| } | |||
| // AddWikiPage adds new page to repository wiki. | |||
| func (repo *Repository) AddWikiPage(doer *User, title, content, message string) (err error) { | |||
| // updateWikiPage adds new page to repository wiki. | |||
| func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) { | |||
| wikiWorkingPool.CheckIn(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) | |||
| } | |||
| title = strings.Replace(title, "/", " ", -1) | |||
| title = ToWikiPageName(strings.Replace(title, "/", " ", -1)) | |||
| 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 { | |||
| return fmt.Errorf("WriteFile: %v", err) | |||
| } | |||
| @@ -152,3 +163,11 @@ func (repo *Repository) AddWikiPage(doer *User, title, content, message string) | |||
| 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 { | |||
| Title string `binding:"Required"` | |||
| Content string `binding:"Required"` | |||
| Message string | |||
| OldTitle string | |||
| Title string `binding:"Required"` | |||
| Content string `binding:"Required"` | |||
| Message string | |||
| } | |||
| // FIXME: use code generation to generate this method. | |||
| @@ -59,7 +59,7 @@ type Context struct { | |||
| IsSigned bool | |||
| IsBasicAuth bool | |||
| Repo RepoContext | |||
| Repo *RepoContext | |||
| Org struct { | |||
| IsOwner bool | |||
| @@ -73,17 +73,22 @@ type Context struct { | |||
| } | |||
| // 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 | |||
| } | |||
| // 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 | |||
| } | |||
| // 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 | |||
| func (r RepoContext) HasAccess() bool { | |||
| func (r *RepoContext) HasAccess() bool { | |||
| return r.AccessMode >= models.ACCESS_MODE_READ | |||
| } | |||
| @@ -6,7 +6,6 @@ package middleware | |||
| import ( | |||
| "fmt" | |||
| "net/url" | |||
| "path" | |||
| "strings" | |||
| @@ -225,6 +224,8 @@ func RetrieveBaseRepo(ctx *Context, repo *models.Repository) { | |||
| func RepoAssignment(args ...bool) macaron.Handler { | |||
| return func(ctx *Context) { | |||
| ctx.Repo = &RepoContext{} | |||
| var ( | |||
| 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["IsRepositoryOwner"] = ctx.Repo.IsOwner() | |||
| ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin() | |||
| ctx.Data["IsRepositoryPusher"] = ctx.Repo.IsPusher() | |||
| ctx.Data["DisableSSH"] = setting.DisableSSH | |||
| ctx.Repo.CloneLink, err = repo.CloneLink() | |||
| @@ -397,11 +399,15 @@ func RepoAssignment(args ...bool) macaron.Handler { | |||
| func RequireRepoAdmin() macaron.Handler { | |||
| return func(ctx *Context) { | |||
| if !ctx.Repo.IsAdmin() { | |||
| if !ctx.IsSigned { | |||
| ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl) | |||
| ctx.Redirect(setting.AppSubUrl + "/user/login") | |||
| return | |||
| } | |||
| ctx.Handle(404, ctx.Req.RequestURI, nil) | |||
| return | |||
| } | |||
| } | |||
| } | |||
| func RequireRepoPusher() macaron.Handler { | |||
| return func(ctx *Context) { | |||
| if !ctx.Repo.IsPusher() { | |||
| ctx.Handle(404, ctx.Req.RequestURI, nil) | |||
| return | |||
| } | |||
| @@ -231,6 +231,11 @@ function initRepository() { | |||
| }); | |||
| } | |||
| // Wiki | |||
| if ($('.repository.wiki.view').length > 0) { | |||
| initFilterSearchDropdown('.choose.page .dropdown'); | |||
| } | |||
| // Options | |||
| if ($('.repository.settings.options').length > 0) { | |||
| $('#repo_name').keyup(function () { | |||
| @@ -314,23 +319,23 @@ function initRepository() { | |||
| $('#edit-title').click(editTitleToggle); | |||
| $('#cancel-edit-title').click(editTitleToggle); | |||
| $('#save-edit-title').click(editTitleToggle). | |||
| click(function () { | |||
| if ($edit_input.val().length == 0 || | |||
| $edit_input.val() == $issue_title.text()) { | |||
| $edit_input.val($issue_title.text()); | |||
| return false; | |||
| } | |||
| click(function () { | |||
| if ($edit_input.val().length == 0 || | |||
| $edit_input.val() == $issue_title.text()) { | |||
| $edit_input.val($issue_title.text()); | |||
| return false; | |||
| } | |||
| $.post($(this).data('update-url'), { | |||
| "_csrf": csrf, | |||
| "title": $edit_input.val() | |||
| }, | |||
| function (data) { | |||
| $edit_input.val(data.title); | |||
| $issue_title.text(data.title); | |||
| }); | |||
| return false; | |||
| }); | |||
| $.post($(this).data('update-url'), { | |||
| "_csrf": csrf, | |||
| "title": $edit_input.val() | |||
| }, | |||
| function (data) { | |||
| $edit_input.val(data.title); | |||
| $issue_title.text(data.title); | |||
| }); | |||
| return false; | |||
| }); | |||
| // Edit issue or comment content | |||
| $('.edit-content').click(function () { | |||
| @@ -729,9 +734,9 @@ $(document).ready(function () { | |||
| // Show exact time | |||
| $('.time-since').each(function () { | |||
| $(this).addClass('poping up'). | |||
| attr('data-content', $(this).attr('title')). | |||
| attr('data-variation', 'inverted tiny'). | |||
| attr('title', ''); | |||
| attr('data-content', $(this).attr('title')). | |||
| attr('data-variation', 'inverted tiny'). | |||
| attr('title', ''); | |||
| }); | |||
| // Semantic UI modules. | |||
| @@ -6,6 +6,7 @@ package repo | |||
| import ( | |||
| "io/ioutil" | |||
| "strings" | |||
| "github.com/gogits/git-shell" | |||
| @@ -21,56 +22,97 @@ const ( | |||
| WIKI_NEW base.TplName = "repo/wiki/new" | |||
| ) | |||
| func Wiki(ctx *middleware.Context) { | |||
| ctx.Data["PageIsWiki"] = true | |||
| if !ctx.Repo.Repository.HasWiki() { | |||
| ctx.Data["Title"] = ctx.Tr("repo.wiki") | |||
| ctx.HTML(200, WIKI_START) | |||
| return | |||
| } | |||
| 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 | |||
| return nil, "" | |||
| } | |||
| commit, err := wikiRepo.GetCommitOfBranch("master") | |||
| if err != nil { | |||
| ctx.Handle(500, "GetCommitOfBranch", err) | |||
| return | |||
| 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 | |||
| } | |||
| page := models.ToWikiPageName(ctx.Params(":page")) | |||
| if len(page) == 0 { | |||
| page = "Home" | |||
| pageURL := ctx.Params(":page") | |||
| if len(pageURL) == 0 { | |||
| pageURL = "Home" | |||
| } | |||
| ctx.Data["Title"] = page | |||
| 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(page + ".md") | |||
| blob, err := commit.GetBlobByPath(pageName + ".md") | |||
| if err != nil { | |||
| if git.IsErrNotExist(err) { | |||
| ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_list") | |||
| ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages") | |||
| } else { | |||
| ctx.Handle(500, "GetBlobByPath", err) | |||
| } | |||
| return | |||
| return nil, "" | |||
| } | |||
| r, err := blob.Data() | |||
| if err != nil { | |||
| ctx.Handle(500, "Data", err) | |||
| return | |||
| 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) { | |||
| ctx.Data["PageIsWiki"] = true | |||
| if !ctx.Repo.Repository.HasWiki() { | |||
| ctx.Data["Title"] = ctx.Tr("repo.wiki") | |||
| ctx.HTML(200, WIKI_START) | |||
| return | |||
| } | |||
| wikiRepo, pageName := renderWikiPage(ctx, true) | |||
| if ctx.Written() { | |||
| return | |||
| } | |||
| ctx.Data["Content"] = string(base.RenderMarkdown(data, ctx.Repo.RepoLink)) | |||
| // Get last change information. | |||
| lastCommit, err := wikiRepo.GetCommitByPath(page + ".md") | |||
| lastCommit, err := wikiRepo.GetCommitByPath(pageName + ".md") | |||
| if err != nil { | |||
| ctx.Handle(500, "GetCommitByPath", err) | |||
| return | |||
| @@ -80,7 +122,7 @@ func Wiki(ctx *middleware.Context) { | |||
| 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 { | |||
| 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 | |||
| } | |||
| @@ -115,5 +162,37 @@ func NewWikiPost(ctx *middleware.Context, form auth.NewWikiForm) { | |||
| } | |||
| 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" .}} | |||
| <div class="ui container"> | |||
| {{template "repo/sidebar" .}} | |||
| {{template "base/alert" .}} | |||
| <div class="ui header"> | |||
| {{.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> | |||
| <form class="ui form" action="{{.Link}}" method="post"> | |||
| {{.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> | |||
| </div> | |||
| <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 class="field"> | |||
| <input name="message" placeholder="{{.i18n.Tr "repo.wiki.default_commit_message"}}"> | |||
| @@ -3,15 +3,43 @@ | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| {{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"> | |||
| {{.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"> | |||
| {{$timeSince := TimeSince .Author.When $.Lang}} | |||
| {{.i18n.Tr "repo.wiki.last_commit_info" .Author.Name $timeSince | Safe}} | |||
| </div> | |||
| </div> | |||
| <div class="ui segment markdown"> | |||
| {{.Content | Str2html}} | |||
| {{.content | Str2html}} | |||
| </div> | |||
| </div> | |||
| </div> | |||