mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-25 08:59:31 -05:00
parent
76d4b9288b
commit
e538ff2770
25 changed files with 248 additions and 94 deletions
|
@ -5,7 +5,7 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra
|
|||
|
||||
![](public/img/gogs-large-resize.png)
|
||||
|
||||
##### Current version: 0.7.29 Beta
|
||||
##### Current version: 0.7.30 Beta
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
|
|
@ -421,7 +421,7 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Get("/action/:action", repo.Action)
|
||||
|
||||
m.Group("/issues", func() {
|
||||
m.Combo("/new").Get(middleware.RepoRef(), repo.NewIssue).
|
||||
m.Combo("/new", repo.MustEnableIssues).Get(middleware.RepoRef(), repo.NewIssue).
|
||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
|
||||
|
||||
m.Combo("/:index/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
|
||||
|
@ -459,7 +459,7 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Post("/delete", repo.DeleteRelease)
|
||||
}, reqRepoAdmin, middleware.RepoRef())
|
||||
|
||||
m.Combo("/compare/*").Get(repo.CompareAndPullRequest).
|
||||
m.Combo("/compare/*", repo.MustEnablePulls).Get(repo.CompareAndPullRequest).
|
||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost)
|
||||
}, reqSignIn, middleware.RepoAssignment())
|
||||
|
||||
|
@ -484,7 +484,7 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Combo("/:page/_edit").Get(repo.EditWiki).
|
||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
|
||||
}, reqSignIn, reqRepoPusher)
|
||||
}, middleware.RepoRef())
|
||||
}, repo.MustEnableWiki, middleware.RepoRef())
|
||||
|
||||
m.Get("/archive/*", repo.Download)
|
||||
|
||||
|
@ -492,7 +492,7 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Get("/commits", repo.ViewPullCommits)
|
||||
m.Get("/files", repo.ViewPullFiles)
|
||||
m.Post("/merge", reqRepoAdmin, repo.MergePullRequest)
|
||||
})
|
||||
}, repo.MustEnablePulls)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Get("/src/*", repo.Home)
|
||||
|
|
|
@ -558,10 +558,17 @@ settings.collaboration = Collaboration
|
|||
settings.hooks = Webhooks
|
||||
settings.githooks = Git Hooks
|
||||
settings.basic_settings = Basic Settings
|
||||
settings.danger_zone = Danger Zone
|
||||
settings.site = Official Site
|
||||
settings.update_settings = Update Settings
|
||||
settings.change_reponame_prompt = This change will affect how links relate to the repository.
|
||||
settings.advanced_settings = Advanced Settings
|
||||
settings.wiki_desc = Enable wiki to allow people write documents
|
||||
settings.issues_desc = Enable builtin lightweight issue tracker
|
||||
settings.use_external_issue_tracker = Use external issue tracker
|
||||
settings.tracker_url_format = External Issue Tracker URL Format
|
||||
settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
|
||||
settings.pulls_desc = Enable pull requests to accept public contributions
|
||||
settings.danger_zone = Danger Zone
|
||||
settings.transfer = Transfer Ownership
|
||||
settings.transfer_desc = Transfer this repository to another user or to an organization in which you have admin rights.
|
||||
settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
|
||||
|
|
|
@ -33,7 +33,6 @@ Directory `/var/gogs` keeps Git repositories and Gogs data:
|
|||
|-- conf
|
||||
|-- data
|
||||
|-- log
|
||||
|-- templates
|
||||
|
||||
### Volume with data container
|
||||
|
||||
|
|
2
gogs.go
2
gogs.go
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.7.29.1204 Beta"
|
||||
const APP_VER = "0.7.30.1204 Beta"
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
|
|
@ -161,6 +161,14 @@ type Repository struct {
|
|||
IsMirror bool
|
||||
*Mirror `xorm:"-"`
|
||||
|
||||
// Advanced settings
|
||||
EnableWiki bool `xorm:"NOT NULL DEFAULT true"`
|
||||
EnableIssues bool `xorm:"NOT NULL DEFAULT true"`
|
||||
EnableExternalTracker bool
|
||||
ExternalTrackerFormat string
|
||||
ExternalMetas map[string]string `xorm:"-"`
|
||||
EnablePulls bool `xorm:"NOT NULL DEFAULT true"`
|
||||
|
||||
IsFork bool `xorm:"NOT NULL DEFAULT false"`
|
||||
ForkID int64
|
||||
BaseRepo *Repository `xorm:"-"`
|
||||
|
@ -214,6 +222,20 @@ func (repo *Repository) MustOwner() *User {
|
|||
return repo.mustOwner(x)
|
||||
}
|
||||
|
||||
// ComposeMetas composes a map of metas for rendering external issue tracker URL.
|
||||
func (repo *Repository) ComposeMetas() map[string]string {
|
||||
if !repo.EnableExternalTracker {
|
||||
return nil
|
||||
} else if repo.ExternalMetas == nil {
|
||||
repo.ExternalMetas = map[string]string{
|
||||
"format": repo.ExternalTrackerFormat,
|
||||
"user": repo.MustOwner().Name,
|
||||
"repo": repo.Name,
|
||||
}
|
||||
}
|
||||
return repo.ExternalMetas
|
||||
}
|
||||
|
||||
// GetAssignees returns all users that have write access of repository.
|
||||
func (repo *Repository) GetAssignees() (_ []*User, err error) {
|
||||
if err = repo.GetOwner(); err != nil {
|
||||
|
|
|
@ -87,6 +87,13 @@ type RepoSettingForm struct {
|
|||
Branch string
|
||||
Interval int
|
||||
Private bool
|
||||
|
||||
// Advanced settings
|
||||
EnableWiki bool
|
||||
EnableIssues bool
|
||||
EnableExternalTracker bool
|
||||
TrackerURLFormat string
|
||||
EnablePulls bool
|
||||
}
|
||||
|
||||
func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
|
|
|
@ -137,50 +137,6 @@ var (
|
|||
sha1CurrentPattern = regexp.MustCompile(`\b[0-9a-f]{40}\b`)
|
||||
)
|
||||
|
||||
func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
|
||||
ms := MentionPattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
m = bytes.TrimSpace(m)
|
||||
rawBytes = bytes.Replace(rawBytes, m,
|
||||
[]byte(fmt.Sprintf(`<a href="%s/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
|
||||
}
|
||||
|
||||
ms = commitPattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
m = bytes.TrimSpace(m)
|
||||
i := strings.Index(string(m), "commit/")
|
||||
j := strings.Index(string(m), "#")
|
||||
if j == -1 {
|
||||
j = len(m)
|
||||
}
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
|
||||
` <code><a href="%s">%s</a></code>`, m, ShortSha(string(m[i+7:j])))), -1)
|
||||
}
|
||||
ms = issueFullPattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
m = bytes.TrimSpace(m)
|
||||
i := strings.Index(string(m), "issues/")
|
||||
j := strings.Index(string(m), "#")
|
||||
if j == -1 {
|
||||
j = len(m)
|
||||
}
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
|
||||
` <a href="%s">#%s</a>`, m, ShortSha(string(m[i+7:j])))), -1)
|
||||
}
|
||||
rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix)
|
||||
rawBytes = RenderSha1CurrentPattern(rawBytes, urlPrefix)
|
||||
return rawBytes
|
||||
}
|
||||
|
||||
func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
|
||||
ms := sha1CurrentPattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
|
||||
`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, ShortSha(string(m)))), -1)
|
||||
}
|
||||
return rawBytes
|
||||
}
|
||||
|
||||
func cutoutVerbosePrefix(prefix string) string {
|
||||
count := 0
|
||||
for i := 0; i < len(prefix); i++ {
|
||||
|
@ -194,7 +150,7 @@ func cutoutVerbosePrefix(prefix string) string {
|
|||
return prefix
|
||||
}
|
||||
|
||||
func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string) []byte {
|
||||
func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
|
||||
urlPrefix = cutoutVerbosePrefix(urlPrefix)
|
||||
ms := issueIndexPattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
|
@ -204,24 +160,45 @@ func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string) []byte {
|
|||
space = " "
|
||||
m2 = m2[1:]
|
||||
}
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`%s<a href="%s/issues/%s">%s</a>`,
|
||||
space, urlPrefix, m2[1:], m2)), 1)
|
||||
if metas == nil {
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`%s<a href="%s/issues/%s">%s</a>`,
|
||||
space, urlPrefix, m2[1:], m2)), 1)
|
||||
} else {
|
||||
// Support for external issue tracker
|
||||
metas["index"] = string(m2[1:])
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`%s<a href="%s">%s</a>`,
|
||||
space, com.Expand(metas["format"], metas), m2)), 1)
|
||||
}
|
||||
}
|
||||
return rawBytes
|
||||
}
|
||||
|
||||
func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
|
||||
ms := MentionPattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
m = bytes.TrimSpace(m)
|
||||
rawBytes = bytes.Replace(rawBytes, m,
|
||||
[]byte(fmt.Sprintf(`<a href="%s/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
|
||||
}
|
||||
|
||||
rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix, metas)
|
||||
rawBytes = RenderSha1CurrentPattern(rawBytes, urlPrefix)
|
||||
return rawBytes
|
||||
}
|
||||
|
||||
func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
|
||||
ms := sha1CurrentPattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
|
||||
`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, ShortSha(string(m)))), -1)
|
||||
}
|
||||
return rawBytes
|
||||
}
|
||||
|
||||
func RenderRawMarkdown(body []byte, urlPrefix string) []byte {
|
||||
htmlFlags := 0
|
||||
// htmlFlags |= blackfriday.HTML_USE_XHTML
|
||||
// htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
|
||||
// htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS
|
||||
// htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES
|
||||
// htmlFlags |= blackfriday.HTML_SKIP_HTML
|
||||
htmlFlags |= blackfriday.HTML_SKIP_STYLE
|
||||
// htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
|
||||
// htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE
|
||||
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
|
||||
// htmlFlags |= blackfriday.HTML_COMPLETE_PAGE
|
||||
renderer := &CustomRender{
|
||||
Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""),
|
||||
urlPrefix: urlPrefix,
|
||||
|
@ -252,9 +229,36 @@ var (
|
|||
|
||||
var noEndTags = []string{"img", "input", "br", "hr"}
|
||||
|
||||
// PreProcessMarkdown renders full links of commits, issues and pulls to shorter version.
|
||||
func PreProcessMarkdown(rawHTML []byte, urlPrefix string) []byte {
|
||||
ms := commitPattern.FindAll(rawHTML, -1)
|
||||
for _, m := range ms {
|
||||
m = bytes.TrimSpace(m)
|
||||
i := strings.Index(string(m), "commit/")
|
||||
j := strings.Index(string(m), "#")
|
||||
if j == -1 {
|
||||
j = len(m)
|
||||
}
|
||||
rawHTML = bytes.Replace(rawHTML, m, []byte(fmt.Sprintf(
|
||||
` <code><a href="%s">%s</a></code>`, m, ShortSha(string(m[i+7:j])))), -1)
|
||||
}
|
||||
ms = issueFullPattern.FindAll(rawHTML, -1)
|
||||
for _, m := range ms {
|
||||
m = bytes.TrimSpace(m)
|
||||
i := strings.Index(string(m), "issues/")
|
||||
j := strings.Index(string(m), "#")
|
||||
if j == -1 {
|
||||
j = len(m)
|
||||
}
|
||||
rawHTML = bytes.Replace(rawHTML, m, []byte(fmt.Sprintf(
|
||||
` <a href="%s">#%s</a>`, m, ShortSha(string(m[i+7:j])))), -1)
|
||||
}
|
||||
return rawHTML
|
||||
}
|
||||
|
||||
// PostProcessMarkdown treats different types of HTML differently,
|
||||
// and only renders special links for plain text blocks.
|
||||
func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
|
||||
func PostProcessMarkdown(rawHtml []byte, urlPrefix string, metas map[string]string) []byte {
|
||||
startTags := make([]string, 0, 5)
|
||||
var buf bytes.Buffer
|
||||
tokenizer := html.NewTokenizer(bytes.NewReader(rawHtml))
|
||||
|
@ -264,7 +268,7 @@ OUTER_LOOP:
|
|||
token := tokenizer.Token()
|
||||
switch token.Type {
|
||||
case html.TextToken:
|
||||
buf.Write(RenderSpecialLink([]byte(token.String()), urlPrefix))
|
||||
buf.Write(RenderSpecialLink([]byte(token.String()), urlPrefix, metas))
|
||||
|
||||
case html.StartTagToken:
|
||||
buf.WriteString(token.String())
|
||||
|
@ -322,13 +326,14 @@ OUTER_LOOP:
|
|||
return rawHtml
|
||||
}
|
||||
|
||||
func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
|
||||
result := RenderRawMarkdown(rawBytes, urlPrefix)
|
||||
result = PostProcessMarkdown(result, urlPrefix)
|
||||
func RenderMarkdown(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
|
||||
result := PreProcessMarkdown(rawBytes, urlPrefix)
|
||||
result = RenderRawMarkdown(result, urlPrefix)
|
||||
result = PostProcessMarkdown(result, urlPrefix, metas)
|
||||
result = Sanitizer.SanitizeBytes(result)
|
||||
return result
|
||||
}
|
||||
|
||||
func RenderMarkdownString(raw, urlPrefix string) string {
|
||||
return string(RenderMarkdown([]byte(raw), urlPrefix))
|
||||
func RenderMarkdownString(raw, urlPrefix string, metas map[string]string) string {
|
||||
return string(RenderMarkdown([]byte(raw), urlPrefix, metas))
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -125,7 +125,7 @@ func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *
|
|||
|
||||
subject := fmt.Sprintf("[%s] %s (#%d)", repo.Name, issue.Name, issue.Index)
|
||||
content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.",
|
||||
base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name),
|
||||
base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name, repo.ComposeMetas()),
|
||||
setting.AppUrl, owner.Name, repo.Name, issue.Index)
|
||||
msg := NewMessage(tos, subject, content)
|
||||
msg.Info = fmt.Sprintf("Subject: %s, issue notify", subject)
|
||||
|
@ -148,7 +148,7 @@ func SendIssueMentionMail(r macaron.Render, u, owner *models.User,
|
|||
data["IssueLink"] = fmt.Sprintf("%s/%s/issues/%d", owner.Name, repo.Name, issue.Index)
|
||||
data["Subject"] = subject
|
||||
data["ActUserName"] = u.DisplayName()
|
||||
data["Content"] = string(base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name))
|
||||
data["Content"] = string(base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name, repo.ComposeMetas()))
|
||||
|
||||
body, err := r.HTMLString(string(NOTIFY_MENTION), data)
|
||||
if err != nil {
|
||||
|
|
|
@ -165,6 +165,7 @@ func RepoAssignment(args ...bool) macaron.Handler {
|
|||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
|
||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
||||
ctx.Data["IsRepositoryPusher"] = ctx.Repo.IsPusher()
|
||||
ctx.Data["CanPullRequest"] = ctx.Repo.IsAdmin() && repo.BaseRepo != nil && repo.BaseRepo.EnablePulls
|
||||
|
||||
ctx.Data["DisableSSH"] = setting.DisableSSH
|
||||
ctx.Data["CloneLink"] = repo.CloneLink()
|
||||
|
|
|
@ -183,9 +183,9 @@ func ReplaceLeft(s, old, new string) string {
|
|||
}
|
||||
|
||||
// RenderCommitMessage renders commit message with XSS-safe and special links.
|
||||
func RenderCommitMessage(msg, urlPrefix string) template.HTML {
|
||||
func RenderCommitMessage(msg, urlPrefix string, metas map[string]string) template.HTML {
|
||||
cleanMsg := template.HTMLEscapeString(msg)
|
||||
fullMessage := string(base.RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix))
|
||||
fullMessage := string(base.RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix, metas))
|
||||
msgLines := strings.Split(strings.TrimSpace(fullMessage), "\n")
|
||||
for i := range msgLines {
|
||||
msgLines[i] = ReplaceLeft(msgLines[i], " ", " ")
|
||||
|
|
|
@ -911,6 +911,9 @@ pre.raw {
|
|||
.ui .form .fake {
|
||||
display: none !important;
|
||||
}
|
||||
.ui .form .sub.field {
|
||||
margin-left: 25px;
|
||||
}
|
||||
.ui .sha.label {
|
||||
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
|
||||
font-size: 13px;
|
||||
|
|
|
@ -217,6 +217,10 @@ pre {
|
|||
.fake {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.sub.field {
|
||||
margin-left: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
.sha.label {
|
||||
|
|
|
@ -25,7 +25,7 @@ func Markdown(ctx *middleware.Context, form api.MarkdownOption) {
|
|||
|
||||
switch form.Mode {
|
||||
case "gfm":
|
||||
ctx.Write(base.RenderMarkdown([]byte(form.Text), form.Context))
|
||||
ctx.Write(base.RenderMarkdown([]byte(form.Text), form.Context, nil))
|
||||
default:
|
||||
ctx.Write(base.RenderRawMarkdown([]byte(form.Text), ""))
|
||||
}
|
||||
|
|
|
@ -41,6 +41,18 @@ var (
|
|||
ErrTooManyFiles = errors.New("Maximum number of files to upload exceeded")
|
||||
)
|
||||
|
||||
func MustEnableIssues(ctx *middleware.Context) {
|
||||
if !ctx.Repo.Repository.EnableIssues {
|
||||
ctx.Handle(404, "MustEnableIssues", nil)
|
||||
}
|
||||
}
|
||||
|
||||
func MustEnablePulls(ctx *middleware.Context) {
|
||||
if !ctx.Repo.Repository.EnablePulls {
|
||||
ctx.Handle(404, "MustEnablePulls", nil)
|
||||
}
|
||||
}
|
||||
|
||||
func RetrieveLabels(ctx *middleware.Context) {
|
||||
labels, err := models.GetLabelsByRepoID(ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
|
@ -60,7 +72,12 @@ func Issues(ctx *middleware.Context) {
|
|||
ctx.Data["Title"] = ctx.Tr("repo.pulls")
|
||||
ctx.Data["PageIsPullList"] = true
|
||||
ctx.Data["HasForkedRepo"] = ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)
|
||||
|
||||
} else {
|
||||
MustEnableIssues(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
ctx.Data["Title"] = ctx.Tr("repo.issues")
|
||||
ctx.Data["PageIsIssueList"] = true
|
||||
}
|
||||
|
@ -496,6 +513,10 @@ func ViewIssue(ctx *middleware.Context) {
|
|||
ctx.Data["PageIsPullConversation"] = true
|
||||
ctx.Data["HasForkedRepo"] = ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)
|
||||
} else {
|
||||
MustEnableIssues(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
ctx.Data["PageIsIssueList"] = true
|
||||
}
|
||||
|
||||
|
@ -503,7 +524,8 @@ func ViewIssue(ctx *middleware.Context) {
|
|||
ctx.Handle(500, "GetPoster", err)
|
||||
return
|
||||
}
|
||||
issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink))
|
||||
issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink,
|
||||
ctx.Repo.Repository.ComposeMetas()))
|
||||
|
||||
repo := ctx.Repo.Repository
|
||||
|
||||
|
@ -570,7 +592,8 @@ func ViewIssue(ctx *middleware.Context) {
|
|||
// Render comments.
|
||||
for _, comment = range issue.Comments {
|
||||
if comment.Type == models.COMMENT_TYPE_COMMENT {
|
||||
comment.RenderedContent = string(base.RenderMarkdown([]byte(comment.Content), ctx.Repo.RepoLink))
|
||||
comment.RenderedContent = string(base.RenderMarkdown([]byte(comment.Content), ctx.Repo.RepoLink,
|
||||
ctx.Repo.Repository.ComposeMetas()))
|
||||
|
||||
// Check tag.
|
||||
tag, ok = marked[comment.PosterID]
|
||||
|
@ -656,7 +679,7 @@ func UpdateIssueContent(ctx *middleware.Context) {
|
|||
}
|
||||
|
||||
ctx.JSON(200, map[string]interface{}{
|
||||
"content": string(base.RenderMarkdown([]byte(issue.Content), ctx.Query("context"))),
|
||||
"content": string(base.RenderMarkdown([]byte(issue.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -893,7 +916,7 @@ func UpdateCommentContent(ctx *middleware.Context) {
|
|||
}
|
||||
|
||||
ctx.JSON(200, map[string]interface{}{
|
||||
"content": string(base.RenderMarkdown([]byte(comment.Content), ctx.Query("context"))),
|
||||
"content": string(base.RenderMarkdown([]byte(comment.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -991,7 +1014,7 @@ func Milestones(ctx *middleware.Context) {
|
|||
return
|
||||
}
|
||||
for _, m := range miles {
|
||||
m.RenderedContent = string(base.RenderMarkdown([]byte(m.Content), ctx.Repo.RepoLink))
|
||||
m.RenderedContent = string(base.RenderMarkdown([]byte(m.Content), ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas()))
|
||||
m.CalOpenIssues()
|
||||
}
|
||||
ctx.Data["Milestones"] = miles
|
||||
|
|
|
@ -69,7 +69,7 @@ func Releases(ctx *middleware.Context) {
|
|||
rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
|
||||
}
|
||||
|
||||
rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink)
|
||||
rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
|
||||
tags[i] = rel
|
||||
rels[j] = nil // Mark as used.
|
||||
break
|
||||
|
@ -129,7 +129,7 @@ func Releases(ctx *middleware.Context) {
|
|||
rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
|
||||
}
|
||||
|
||||
rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink)
|
||||
rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
|
||||
tags = append(tags, rel)
|
||||
}
|
||||
models.SortReleases(tags)
|
||||
|
|
|
@ -104,7 +104,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
|||
ctx.Handle(500, "UpdateRepository", err)
|
||||
return
|
||||
}
|
||||
log.Trace("Repository updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
log.Trace("Repository basic settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
|
||||
if isNameChanged {
|
||||
if err := models.RenameRepoAction(ctx.User, oldRepoName, repo); err != nil {
|
||||
|
@ -123,7 +123,24 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
|||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||
ctx.Redirect(fmt.Sprintf("%s/%s/%s/settings", setting.AppSubUrl, ctx.Repo.Owner.Name, repo.Name))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
|
||||
case "advanced":
|
||||
repo.EnableWiki = form.EnableWiki
|
||||
repo.EnableIssues = form.EnableIssues
|
||||
repo.EnableExternalTracker = form.EnableExternalTracker
|
||||
repo.ExternalTrackerFormat = form.TrackerURLFormat
|
||||
repo.EnablePulls = form.EnablePulls
|
||||
|
||||
if err := models.UpdateRepository(repo, false); err != nil {
|
||||
ctx.Handle(500, "UpdateRepository", err)
|
||||
return
|
||||
}
|
||||
log.Trace("Repository advanced settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
|
||||
|
||||
case "transfer":
|
||||
if repo.Name != form.RepoName {
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
|
||||
|
|
|
@ -108,7 +108,7 @@ func Home(ctx *middleware.Context) {
|
|||
readmeExist := base.IsMarkdownFile(blob.Name()) || base.IsReadmeFile(blob.Name())
|
||||
ctx.Data["ReadmeExist"] = readmeExist
|
||||
if readmeExist {
|
||||
ctx.Data["FileContent"] = string(base.RenderMarkdown(buf, path.Dir(treeLink)))
|
||||
ctx.Data["FileContent"] = string(base.RenderMarkdown(buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
|
||||
} else {
|
||||
if err, content := template.ToUtf8WithErr(buf); err != nil {
|
||||
if err != nil {
|
||||
|
@ -201,7 +201,7 @@ func Home(ctx *middleware.Context) {
|
|||
buf = append(buf, d...)
|
||||
switch {
|
||||
case base.IsMarkdownFile(readmeFile.Name()):
|
||||
buf = base.RenderMarkdown(buf, treeLink)
|
||||
buf = base.RenderMarkdown(buf, treeLink, ctx.Repo.Repository.ComposeMetas())
|
||||
default:
|
||||
buf = bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1)
|
||||
}
|
||||
|
|
|
@ -24,6 +24,12 @@ const (
|
|||
WIKI_PAGES base.TplName = "repo/wiki/pages"
|
||||
)
|
||||
|
||||
func MustEnableWiki(ctx *middleware.Context) {
|
||||
if !ctx.Repo.Repository.EnableWiki {
|
||||
ctx.Handle(404, "MustEnableWiki", nil)
|
||||
}
|
||||
}
|
||||
|
||||
type PageMeta struct {
|
||||
Name string
|
||||
URL string
|
||||
|
@ -94,7 +100,7 @@ func renderWikiPage(ctx *middleware.Context, isViewPage bool) (*git.Repository,
|
|||
return nil, ""
|
||||
}
|
||||
if isViewPage {
|
||||
ctx.Data["content"] = string(base.RenderMarkdown(data, ctx.Repo.RepoLink))
|
||||
ctx.Data["content"] = string(base.RenderMarkdown(data, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas()))
|
||||
} else {
|
||||
ctx.Data["content"] = string(data)
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.7.29.1204 Beta
|
||||
0.7.30.1204 Beta
|
|
@ -37,7 +37,7 @@
|
|||
</td>
|
||||
<td class="message collapsing">
|
||||
<a rel="nofollow" class="ui sha label" href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{.ID}}">{{ShortSha .ID.String}}</a>
|
||||
{{RenderCommitMessage .Summary $.RepoLink}}
|
||||
{{RenderCommitMessage .Summary $.RepoLink $.Repository.ComposeMetas}}
|
||||
</td>
|
||||
<td class="grey text right aligned">{{TimeSince .Author.When $.Lang}}</td>
|
||||
</tr>
|
||||
|
|
|
@ -51,21 +51,27 @@
|
|||
<a class="{{if .PageIsViewCode}}active{{end}} item" href="{{.RepoLink}}">
|
||||
<i class="icon octicon octicon-code"></i> {{.i18n.Tr "repo.code"}}
|
||||
</a>
|
||||
{{if .Repository.EnableIssues}}
|
||||
<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 {{if not .Repository.NumOpenIssues}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenIssues}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .Repository.EnablePulls}}
|
||||
<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 {{if not .Repository.NumOpenPulls}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenPulls}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
<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 {{if not .CommitsCount}}gray{{else}}blue{{end}} 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 {{if not .Repository.NumTags}}gray{{else}}blue{{end}} small label">{{.Repository.NumTags}}</span>
|
||||
</a>
|
||||
{{if .Repository.EnableWiki}}
|
||||
<a class="{{if .PageIsWiki}}active{{end}} item" href="{{.RepoLink}}/wiki">
|
||||
<i class="icon octicon octicon-book"></i> {{.i18n.Tr "repo.wiki"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .IsRepositoryAdmin}}
|
||||
<div class="right menu">
|
||||
<a class="{{if .PageIsSettings}}active{{end}} item" href="{{.RepoLink}}/settings">
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>
|
||||
</p>
|
||||
<div class="ui secondary menu">
|
||||
{{if and .IsRepositoryAdmin .Repository.BaseRepo}}
|
||||
{{if .CanPullRequest}}
|
||||
<div class="fitted item">
|
||||
{{ $baseRepo := .Repository.BaseRepo}}
|
||||
<a href="{{AppSubUrl}}/{{$baseRepo.Owner.Name}}/{{$baseRepo.Name}}/compare/{{$.BaseDefaultBranch}}...{{$.Owner.Name}}:{{$.BranchName}}">
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
<input id="website" name="website" type="url" value="{{.Repository.Website}}">
|
||||
</div>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
{{if not .Repository.IsBare}}
|
||||
<div class="required inline field">
|
||||
<label>{{.i18n.Tr "repo.default_branch"}}</label>
|
||||
|
@ -57,13 +56,68 @@
|
|||
<input id="interval" name="interval" type="number" value="{{.MirrorInterval}}">
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
|
||||
<div class="ui divider"></div>
|
||||
<div class="field">
|
||||
<button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "repo.settings.advanced_settings"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<input type="hidden" name="action" value="advanced">
|
||||
|
||||
<div class="inline field">
|
||||
<label>{{.i18n.Tr "repo.wiki"}}</label>
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_wiki" type="checkbox" {{if .Repository.EnableWiki}}checked{{end}}>
|
||||
<label>{{.i18n.Tr "repo.settings.wiki_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<div class="inline field">
|
||||
<label>{{.i18n.Tr "repo.issues"}}</label>
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_issues" type="checkbox" {{if .Repository.EnableIssues}}checked{{end}}>
|
||||
<label>{{.i18n.Tr "repo.settings.issues_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_external_tracker" type="checkbox" {{if .Repository.EnableExternalTracker}}checked{{end}}>
|
||||
<label>{{.i18n.Tr "repo.settings.use_external_issue_tracker"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="tracker_url_format">{{.i18n.Tr "repo.settings.tracker_url_format"}}</label>
|
||||
<input id="tracker_url_format" name="tracker_url_format" value="{{.Repository.ExternalTrackerFormat}}" placeholder="e.g. https://github.com/{user}/{repo}/issues/{index}">
|
||||
<p class="help">{{.i18n.Tr "repo.settings.tracker_url_format_desc" | Str2html}}</p>
|
||||
</div>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<div class="inline field">
|
||||
<label>{{.i18n.Tr "repo.pulls"}}</label>
|
||||
<div class="ui checkbox">
|
||||
<input name="enable_pulls" type="checkbox" {{if .Repository.EnablePulls}}checked{{end}}>
|
||||
<label>{{.i18n.Tr "repo.settings.pulls_desc"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
<div class="field">
|
||||
<button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached warning header">
|
||||
{{.i18n.Tr "repo.settings.danger_zone"}}
|
||||
</h4>
|
||||
|
|
Loading…
Reference in a new issue