@@ -470,7 +470,7 @@ func runWeb(ctx *cli.Context) { | |||
}, func(ctx *middleware.Context) { | |||
ctx.Data["PageIsSettings"] = true | |||
}) | |||
}, reqSignIn, middleware.RepoAssignment(true), reqRepoAdmin, middleware.RepoRef()) | |||
}, reqSignIn, middleware.RepoAssignment(), reqRepoAdmin, middleware.RepoRef()) | |||
m.Group("/:username/:reponame", func() { | |||
m.Get("/action/:action", repo.Action) | |||
@@ -516,7 +516,7 @@ func runWeb(ctx *cli.Context) { | |||
m.Combo("/compare/*").Get(repo.CompareAndPullRequest). | |||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost) | |||
}, reqSignIn, middleware.RepoAssignment(true)) | |||
}, reqSignIn, middleware.RepoAssignment()) | |||
m.Group("/:username/:reponame", func() { | |||
m.Group("", func() { | |||
@@ -530,7 +530,17 @@ func runWeb(ctx *cli.Context) { | |||
}) | |||
m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue) | |||
m.Get("/branches", repo.Branches) | |||
// m.Get("/branches", repo.Branches) | |||
m.Group("/wiki", func() { | |||
m.Get("/?:page", repo.Wiki) | |||
m.Group("", func() { | |||
m.Get("/_new", repo.NewWiki) | |||
m.Get("/:page/_edit", repo.EditWiki) | |||
}, reqSignIn) | |||
}, middleware.RepoRef()) | |||
m.Get("/archive/*", repo.Download) | |||
m.Group("/pulls/:index", func() { | |||
@@ -550,13 +560,13 @@ func runWeb(ctx *cli.Context) { | |||
}, middleware.RepoRef()) | |||
m.Get("/compare/:before([a-z0-9]{40})...:after([a-z0-9]{40})", repo.CompareDiff) | |||
}, ignSignIn, middleware.RepoAssignment(true)) | |||
}, ignSignIn, middleware.RepoAssignment()) | |||
m.Group("/:username", func() { | |||
m.Group("/:reponame", func() { | |||
m.Get("", repo.Home) | |||
m.Get("\\.git$", repo.Home) | |||
}, ignSignIn, middleware.RepoAssignment(true, true), middleware.RepoRef()) | |||
}, ignSignIn, middleware.RepoAssignment(true), middleware.RepoRef()) | |||
m.Group("/:reponame", func() { | |||
m.Any("/*", ignSignInAndCsrf, repo.HTTP) | |||
@@ -535,6 +535,14 @@ milestones.deletion = Milestone Deletion | |||
milestones.deletion_desc = Delete this milestone will remove its information in all related issues. Do you want to continue? | |||
milestones.deletion_success = Milestone has been deleted successfully! | |||
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.new_page = Create New Page | |||
wiki.default_commit_message = Write a note about this update (optional). | |||
wiki.save_page = Save Page | |||
settings = Settings | |||
settings.options = Options | |||
settings.collaboration = Collaboration | |||
@@ -264,6 +264,14 @@ func (repo *Repository) RepoPath() (string, error) { | |||
return repo.repoPath(x) | |||
} | |||
func (repo *Repository) WikiPath() (string, error) { | |||
if err := repo.GetOwner(); err != nil { | |||
return "", err | |||
} | |||
return WikiPath(repo.Owner.Name, repo.Name), nil | |||
} | |||
func (repo *Repository) RepoLink() (string, error) { | |||
if err := repo.GetOwner(); err != nil { | |||
return "", err | |||
@@ -877,6 +885,11 @@ func RepoPath(userName, repoName string) string { | |||
return filepath.Join(UserPath(userName), strings.ToLower(repoName)+".git") | |||
} | |||
// WikiPath returns wiki data path by given user and repository name. | |||
func WikiPath(userName, repoName string) string { | |||
return filepath.Join(UserPath(userName), strings.ToLower(repoName)+".wiki.git") | |||
} | |||
// TransferOwnership transfers all corresponding setting from old user to new one. | |||
func TransferOwnership(u *User, newOwnerName string, repo *Repository) error { | |||
newOwner, err := GetUserByName(newOwnerName) | |||
@@ -223,7 +223,7 @@ func RetrieveBaseRepo(ctx *Context, repo *models.Repository) { | |||
} | |||
} | |||
func RepoAssignment(redirect bool, args ...bool) macaron.Handler { | |||
func RepoAssignment(args ...bool) macaron.Handler { | |||
return func(ctx *Context) { | |||
var ( | |||
displayBare bool // To display bare page if it is a bare repo. | |||
@@ -4,8 +4,8 @@ | |||
"files": { | |||
"\/css\/dropzone-4.2.0.css": { | |||
"fileType": 16, | |||
"ignore": 0, | |||
"ignoreWasSetByUser": 0, | |||
"ignore": 1, | |||
"ignoreWasSetByUser": 1, | |||
"inputAbbreviatedPath": "\/css\/dropzone-4.2.0.css", | |||
"outputAbbreviatedPath": "No Output Path", | |||
"outputPathIsOutsideProject": 0, | |||
@@ -92,6 +92,15 @@ | |||
"outputPathIsOutsideProject": 0, | |||
"outputPathIsSetByUser": 0 | |||
}, | |||
"\/css\/simplemde-1.8.1.min.css": { | |||
"fileType": 16, | |||
"ignore": 1, | |||
"ignoreWasSetByUser": 1, | |||
"inputAbbreviatedPath": "\/css\/simplemde-1.8.1.min.css", | |||
"outputAbbreviatedPath": "No Output Path", | |||
"outputPathIsOutsideProject": 0, | |||
"outputPathIsSetByUser": 0 | |||
}, | |||
"\/css\/themes\/default\/assets\/images\/flags.png": { | |||
"fileType": 32768, | |||
"ignore": 0, | |||
@@ -1758,6 +1758,11 @@ footer .container .links > *:first-child { | |||
line-height: 10px; | |||
white-space: nowrap; | |||
} | |||
.repository .navbar .ui.label { | |||
margin-top: -2px; | |||
margin-left: 7px; | |||
padding: 3px 5px; | |||
} | |||
.repository .owner.dropdown { | |||
min-width: 40% !important; | |||
} | |||
@@ -2513,6 +2518,19 @@ footer .container .links > *:first-child { | |||
.repository.forks .list .item .link { | |||
padding-top: 5px; | |||
} | |||
.repository.wiki.start .ui.segment { | |||
padding-top: 70px; | |||
padding-bottom: 100px; | |||
} | |||
.repository.wiki.start .ui.segment .mega-octicon { | |||
font-size: 48px; | |||
} | |||
.repository.wiki.new .CodeMirror .CodeMirror-code .cm-comment { | |||
background: inherit; | |||
} | |||
.repository.wiki.new .editor-preview { | |||
background-color: white; | |||
} | |||
.repository.settings.collaboration .collaborator.list { | |||
padding: 0; | |||
} | |||
@@ -445,6 +445,53 @@ function initRepository() { | |||
} | |||
} | |||
function initWiki() { | |||
if ($('.repository.wiki').length == 0) { | |||
return; | |||
} | |||
if ($('.repository.wiki.new').length > 0) { | |||
var $edit_area = $('#edit-area'); | |||
var simplemde = new SimpleMDE({ | |||
autoDownloadFontAwesome: false, | |||
element: $edit_area[0], | |||
previewRender: function (plainText, preview) { // Async method | |||
setTimeout(function () { | |||
if ($('.editor-preview-active').length == 0) { | |||
return; | |||
} | |||
$.post($edit_area.data('url'), { | |||
"_csrf": csrf, | |||
"mode": "gfm", | |||
"context": $edit_area.data('context'), | |||
"text": plainText | |||
}, | |||
function (data) { | |||
preview.innerHTML = '<div class="markdown">' + data + '</div>'; | |||
emojify.run($('.editor-preview')[0]); | |||
} | |||
); | |||
}, 0); | |||
return "Loading..."; | |||
}, | |||
renderingConfig: { | |||
singleLineBreaks: false | |||
}, | |||
spellChecker: false, | |||
tabSize: 4, | |||
toolbar: ["bold", "italic", "strikethrough", "|", | |||
"heading", "heading-1", "heading-2", "heading-3", "|", | |||
"code", "quote", "|", | |||
"unordered-list", "ordered-list", "|", | |||
"link", "image", "horizontal-rule", "|", | |||
"preview", "fullscreen"] | |||
}) | |||
} | |||
} | |||
function initOrganization() { | |||
if ($('.organization').length == 0) { | |||
return; | |||
@@ -835,6 +882,7 @@ $(document).ready(function () { | |||
initCommentForm(); | |||
initInstall(); | |||
initRepository(); | |||
initWiki(); | |||
initOrganization(); | |||
initUser(); | |||
initWebhook(); | |||
@@ -32,6 +32,14 @@ | |||
} | |||
} | |||
.navbar { | |||
.ui.label { | |||
margin-top: -2px; | |||
margin-left: 7px; | |||
padding: 3px 5px; | |||
} | |||
} | |||
.owner.dropdown { | |||
min-width: 40% !important; | |||
} | |||
@@ -939,6 +947,31 @@ | |||
} | |||
} | |||
&.wiki { | |||
&.start { | |||
.ui.segment { | |||
padding-top: 70px; | |||
padding-bottom: 100px; | |||
.mega-octicon { | |||
font-size: 48px; | |||
} | |||
} | |||
} | |||
&.new { | |||
.CodeMirror { | |||
.CodeMirror-code .cm-comment { | |||
background: inherit; | |||
} | |||
} | |||
.editor-preview { | |||
background-color: white; | |||
} | |||
} | |||
} | |||
&.settings { | |||
&.collaboration { | |||
.collaborator.list { | |||
@@ -5,12 +5,9 @@ | |||
package v1 | |||
import ( | |||
"strings" | |||
"github.com/gogits/gogs/modules/auth/apiv1" | |||
"github.com/gogits/gogs/modules/base" | |||
"github.com/gogits/gogs/modules/middleware" | |||
"github.com/gogits/gogs/modules/setting" | |||
) | |||
// Render an arbitrary Markdown document. | |||
@@ -27,8 +24,7 @@ func Markdown(ctx *middleware.Context, form apiv1.MarkdownForm) { | |||
switch form.Mode { | |||
case "gfm": | |||
ctx.Write(base.RenderMarkdown([]byte(form.Text), | |||
setting.AppUrl+strings.TrimPrefix(form.Context, "/"))) | |||
ctx.Write(base.RenderMarkdown([]byte(form.Text), form.Context)) | |||
default: | |||
ctx.Write(base.RenderRawMarkdown([]byte(form.Text), "")) | |||
} | |||
@@ -29,6 +29,7 @@ const ( | |||
func Home(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Repo.Repository.Name | |||
ctx.Data["PageIsViewCode"] = true | |||
ctx.Data["RequireHighlightJS"] = true | |||
branchName := ctx.Repo.BranchName | |||
@@ -52,8 +53,6 @@ func Home(ctx *middleware.Context) { | |||
treeLink += "/" + treename | |||
} | |||
ctx.Data["IsRepoToolbarSource"] = true | |||
isViewBranch := ctx.Repo.IsBranch | |||
ctx.Data["IsViewBranch"] = isViewBranch | |||
@@ -0,0 +1,49 @@ | |||
// Copyright 2015 The Gogs Authors. All rights reserved. | |||
// Use of this source code is governed by a MIT-style | |||
// license that can be found in the LICENSE file. | |||
package repo | |||
import ( | |||
"github.com/Unknwon/com" | |||
"github.com/gogits/gogs/models" | |||
"github.com/gogits/gogs/modules/base" | |||
"github.com/gogits/gogs/modules/middleware" | |||
) | |||
const ( | |||
WIKI_START base.TplName = "repo/wiki/start" | |||
WIKI_VIEW base.TplName = "repo/wiki/view" | |||
WIKI_NEW base.TplName = "repo/wiki/new" | |||
) | |||
func Wiki(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.wiki") | |||
ctx.Data["PageIsWiki"] = true | |||
wikiPath := models.WikiPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) | |||
if !com.IsDir(wikiPath) { | |||
ctx.HTML(200, WIKI_START) | |||
return | |||
} | |||
ctx.HTML(200, WIKI_VIEW) | |||
} | |||
func NewWiki(ctx *middleware.Context) { | |||
ctx.Data["Title"] = ctx.Tr("repo.wiki.new_page") | |||
ctx.Data["PageIsWiki"] = true | |||
ctx.Data["RequireSimpleMDE"] = true | |||
wikiPath := models.WikiPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) | |||
if !com.IsDir(wikiPath) { | |||
ctx.Data["title"] = "Home" | |||
} | |||
ctx.HTML(200, WIKI_NEW) | |||
} | |||
func EditWiki(ctx *middleware.Context) { | |||
ctx.PlainText(200, []byte(ctx.Params(":page"))) | |||
} |
@@ -19,6 +19,11 @@ | |||
<script src="{{AppSubUrl}}/js/jquery-1.11.3.min.js"></script> | |||
<link rel="stylesheet" href="{{AppSubUrl}}/css/font-awesome-4.4.0.min.css"> | |||
{{if .RequireSimpleMDE}} | |||
<link rel="stylesheet" href="{{AppSubUrl}}/css/simplemde-1.8.1.min.css"> | |||
<script src="{{AppSubUrl}}/js/libs/simplemde-1.8.1.min.js"></script> | |||
{{end}} | |||
<!-- Stylesheet --> | |||
<link rel="stylesheet" href="{{AppSubUrl}}/css/semantic-2.1.6.min.css"> | |||
<link rel="stylesheet" href="{{AppSubUrl}}/css/gogs.css?v={{MD5 AppVer}}"> | |||
@@ -1,7 +1,7 @@ | |||
<div class="field"> | |||
<div class="ui top attached tabular menu" data-write="write" data-preview="preview"> | |||
<a class="active item" data-tab="write">{{.i18n.Tr "repo.release.write"}}</a> | |||
<a class="item" data-tab="preview" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "repo.release.preview"}}</a> | |||
<a class="item" data-tab="preview" data-url="{{AppSubUrl}}/api/v1/markdown" data-context="{{.RepoLink}}">{{.i18n.Tr "repo.release.preview"}}</a> | |||
</div> | |||
<div class="ui bottom attached active tab segment" data-tab="write"> | |||
<textarea id="content" name="content" tabindex="4"></textarea> | |||
@@ -1,16 +1,22 @@ | |||
{{if not .IsBareRepo}} | |||
<div class="ui {{if .IsRepositoryAdmin}}five{{else}}four{{end}} item menu"> | |||
<div class="ui secondary pointing menu navbar"> | |||
<a class="{{if .PageIsViewCode}}active{{end}} item" href="{{.RepoLink}}"> | |||
<i class="icon octicon octicon-code"></i> {{.i18n.Tr "repo.code"}} | |||
</a> | |||
<a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues"> | |||
<i class="icon octicon octicon-issue-opened"></i> {{.i18n.Tr "repo.issues"}} <span class="ui blue label">{{.Repository.NumOpenIssues}}</span> | |||
<i class="icon octicon octicon-issue-opened"></i> {{.i18n.Tr "repo.issues"}} <span class="ui blue small label">{{.Repository.NumOpenIssues}}</span> | |||
</a> | |||
<a class="{{if .PageIsPullList}}active{{end}} item" href="{{.RepoLink}}/pulls"> | |||
<i class="icon octicon octicon-git-pull-request"></i> {{.i18n.Tr "repo.pulls"}} <span class="ui blue label">{{.Repository.NumOpenPulls}}</span> | |||
<i class="icon octicon octicon-git-pull-request"></i> {{.i18n.Tr "repo.pulls"}} <span class="ui blue small label">{{.Repository.NumOpenPulls}}</span> | |||
</a> | |||
<a class="{{if .PageIsCommits}}active{{end}} item" href="{{.RepoLink}}/commits/{{EscapePound .BranchName}}"> | |||
<i class="icon octicon octicon-history"></i> {{.i18n.Tr "repo.commits"}} <span class="ui blue label">{{.CommitsCount}}</span> | |||
<i class="icon octicon octicon-history"></i> {{.i18n.Tr "repo.commits"}} <span class="ui blue small label">{{.CommitsCount}}</span> | |||
</a> | |||
<a class="{{if .PageIsReleaseList}}active{{end}} item" href="{{.RepoLink}}/releases"> | |||
<i class="icon octicon octicon-tag"></i> {{.i18n.Tr "repo.releases"}} <span class="ui blue label">{{.Repository.NumTags}}</span> | |||
<i class="icon octicon octicon-tag"></i> {{.i18n.Tr "repo.releases"}} <span class="ui blue small label">{{.Repository.NumTags}}</span> | |||
</a> | |||
<a class="{{if .PageIsWiki}}active{{end}} item" href="{{.RepoLink}}/wiki"> | |||
<i class="icon octicon octicon-book"></i> {{.i18n.Tr "repo.wiki"}} | |||
</a> | |||
{{if .IsRepositoryAdmin}} | |||
<a class="{{if .PageIsSettings}}active{{end}} item" href="{{.RepoLink}}/settings"> | |||
@@ -0,0 +1,27 @@ | |||
{{template "base/head" .}} | |||
<div class="repository wiki new"> | |||
{{template "repo/header" .}} | |||
<div class="ui container"> | |||
{{template "repo/sidebar" .}} | |||
<div class="ui header"> | |||
{{.i18n.Tr "repo.wiki.new_page"}} | |||
</div> | |||
<form class="ui form" action="{{.Link}}" method="post"> | |||
<div class="field"> | |||
<input name="title" value="{{.title}}" autofocus> | |||
</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> | |||
</div> | |||
<div class="field"> | |||
<input name="message" placeholder="{{.i18n.Tr "repo.wiki.default_commit_message"}}"> | |||
</div> | |||
<div class="text right"> | |||
<button class="ui green button"> | |||
{{.i18n.Tr "repo.wiki.save_page"}} | |||
</button> | |||
</div> | |||
</form> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} |
@@ -0,0 +1,16 @@ | |||
{{template "base/head" .}} | |||
<div class="repository wiki start"> | |||
{{template "repo/header" .}} | |||
<div class="ui container"> | |||
{{template "repo/sidebar" .}} | |||
<div class="ui center segment"> | |||
<span class="mega-octicon octicon-book"></span> | |||
<h2>{{.i18n.Tr "repo.wiki.welcome"}}</h2> | |||
<p>{{.i18n.Tr "repo.wiki.welcome_desc"}}</p> | |||
{{if .IsSigned}} | |||
<a class="ui green button" href="{{.RepoLink}}/wiki/_new">{{.i18n.Tr "repo.wiki.create_first_page"}}</a> | |||
{{end}} | |||
</div> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} |