Refactor some Str2html code (#29397)

This PR touches the most interesting part of the "template refactoring".

1. Unclear variable type. Especially for "web/feed/convert.go":
sometimes it uses text, sometimes it uses HTML.
2. Assign text content to "RenderedContent" field, for example: `
project.RenderedContent = project.Description` in web/org/projects.go
3. Assign rendered content to text field, for example: `r.Note =
rendered content` in web/repo/release.go
4. (possible) Incorrectly calling `{{Str2html
.PackageDescriptor.Metadata.ReleaseNotes}}` in
package/content/nuget.tmpl, I guess the name Str2html misleads
developers to use it to "render string to html", but it only sanitizes.
if ReleaseNotes really contains HTML, then this is not a problem.

(cherry picked from commit e71eb8930a5d0f60874b038c223498b41ad65592)

Conflicts:
	modules/templates/util_string.go
	trivial context conflict
This commit is contained in:
wxiaoguang 2024-03-01 15:11:51 +08:00 committed by Earl Warren
parent 97a0368c28
commit 68099f2f00
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
32 changed files with 90 additions and 61 deletions

View file

@ -8,6 +8,7 @@ package issues
import ( import (
"context" "context"
"fmt" "fmt"
"html/template"
"strconv" "strconv"
"unicode/utf8" "unicode/utf8"
@ -260,7 +261,7 @@ type Comment struct {
Line int64 // - previous line / + proposed line Line int64 // - previous line / + proposed line
TreePath string TreePath string
Content string `xorm:"LONGTEXT"` Content string `xorm:"LONGTEXT"`
RenderedContent string `xorm:"-"` RenderedContent template.HTML `xorm:"-"`
// Path represents the 4 lines of code cemented by this comment // Path represents the 4 lines of code cemented by this comment
Patch string `xorm:"-"` Patch string `xorm:"-"`

View file

@ -7,6 +7,7 @@ package issues
import ( import (
"context" "context"
"fmt" "fmt"
"html/template"
"regexp" "regexp"
"slices" "slices"
@ -105,7 +106,7 @@ type Issue struct {
OriginalAuthorID int64 `xorm:"index"` OriginalAuthorID int64 `xorm:"index"`
Title string `xorm:"name"` Title string `xorm:"name"`
Content string `xorm:"LONGTEXT"` Content string `xorm:"LONGTEXT"`
RenderedContent string `xorm:"-"` RenderedContent template.HTML `xorm:"-"`
Labels []*Label `xorm:"-"` Labels []*Label `xorm:"-"`
MilestoneID int64 `xorm:"INDEX"` MilestoneID int64 `xorm:"INDEX"`
Milestone *Milestone `xorm:"-"` Milestone *Milestone `xorm:"-"`

View file

@ -6,6 +6,7 @@ package issues
import ( import (
"context" "context"
"fmt" "fmt"
"html/template"
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -48,7 +49,7 @@ type Milestone struct {
Repo *repo_model.Repository `xorm:"-"` Repo *repo_model.Repository `xorm:"-"`
Name string Name string
Content string `xorm:"TEXT"` Content string `xorm:"TEXT"`
RenderedContent string `xorm:"-"` RenderedContent template.HTML `xorm:"-"`
IsClosed bool IsClosed bool
NumIssues int NumIssues int
NumClosedIssues int NumClosedIssues int

View file

@ -6,6 +6,7 @@ package project
import ( import (
"context" "context"
"fmt" "fmt"
"html/template"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
@ -100,7 +101,7 @@ type Project struct {
CardType CardType CardType CardType
Type Type Type Type
RenderedContent string `xorm:"-"` RenderedContent template.HTML `xorm:"-"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`

View file

@ -7,6 +7,7 @@ package repo
import ( import (
"context" "context"
"fmt" "fmt"
"html/template"
"net/url" "net/url"
"sort" "sort"
"strconv" "strconv"
@ -80,7 +81,7 @@ type Release struct {
NumCommits int64 NumCommits int64
NumCommitsBehind int64 `xorm:"-"` NumCommitsBehind int64 `xorm:"-"`
Note string `xorm:"TEXT"` Note string `xorm:"TEXT"`
RenderedNote string `xorm:"-"` RenderedNote template.HTML `xorm:"-"`
IsDraft bool `xorm:"NOT NULL DEFAULT false"` IsDraft bool `xorm:"NOT NULL DEFAULT false"`
IsPrerelease bool `xorm:"NOT NULL DEFAULT false"` IsPrerelease bool `xorm:"NOT NULL DEFAULT false"`
IsTag bool `xorm:"NOT NULL DEFAULT false"` // will be true only if the record is a tag and has no related releases IsTag bool `xorm:"NOT NULL DEFAULT false"` // will be true only if the record is a tag and has no related releases

View file

@ -388,7 +388,7 @@ func TestRender_ShortLinks(t *testing.T) {
}, },
}, input) }, input)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
buffer, err = markdown.RenderString(&markup.RenderContext{ buffer, err = markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext, Ctx: git.DefaultContext,
Links: markup.Links{ Links: markup.Links{
@ -398,7 +398,7 @@ func TestRender_ShortLinks(t *testing.T) {
IsWiki: true, IsWiki: true,
}, input) }, input)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
} }
mediatree := util.URLJoin(markup.TestRepoURL, "media", "master") mediatree := util.URLJoin(markup.TestRepoURL, "media", "master")
@ -501,7 +501,7 @@ func TestRender_RelativeImages(t *testing.T) {
Metas: localMetas, Metas: localMetas,
}, input) }, input)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
buffer, err = markdown.RenderString(&markup.RenderContext{ buffer, err = markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext, Ctx: git.DefaultContext,
Links: markup.Links{ Links: markup.Links{
@ -511,7 +511,7 @@ func TestRender_RelativeImages(t *testing.T) {
IsWiki: true, IsWiki: true,
}, input) }, input)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
} }
rawwiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw") rawwiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw")

View file

@ -6,6 +6,7 @@ package markdown
import ( import (
"fmt" "fmt"
"html/template"
"io" "io"
"strings" "strings"
"sync" "sync"
@ -266,12 +267,12 @@ func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error
} }
// RenderString renders Markdown string to HTML with all specific handling stuff and return string // RenderString renders Markdown string to HTML with all specific handling stuff and return string
func RenderString(ctx *markup.RenderContext, content string) (string, error) { func RenderString(ctx *markup.RenderContext, content string) (template.HTML, error) {
var buf strings.Builder var buf strings.Builder
if err := Render(ctx, strings.NewReader(content), &buf); err != nil { if err := Render(ctx, strings.NewReader(content), &buf); err != nil {
return "", err return "", err
} }
return buf.String(), nil return template.HTML(buf.String()), nil
} }
// RenderRaw renders Markdown to HTML without handling special links. // RenderRaw renders Markdown to HTML without handling special links.

View file

@ -5,6 +5,7 @@ package markdown_test
import ( import (
"context" "context"
"html/template"
"os" "os"
"strings" "strings"
"testing" "testing"
@ -59,7 +60,7 @@ func TestRender_StandardLinks(t *testing.T) {
}, },
}, input) }, input)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
buffer, err = markdown.RenderString(&markup.RenderContext{ buffer, err = markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext, Ctx: git.DefaultContext,
@ -69,7 +70,7 @@ func TestRender_StandardLinks(t *testing.T) {
IsWiki: true, IsWiki: true,
}, input) }, input)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
} }
googleRendered := `<p><a href="https://google.com/" rel="nofollow">https://google.com/</a></p>` googleRendered := `<p><a href="https://google.com/" rel="nofollow">https://google.com/</a></p>`
@ -94,7 +95,7 @@ func TestRender_Images(t *testing.T) {
}, },
}, input) }, input)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
} }
url := "../../.images/src/02/train.jpg" url := "../../.images/src/02/train.jpg"
@ -304,7 +305,7 @@ func TestTotal_RenderWiki(t *testing.T) {
IsWiki: true, IsWiki: true,
}, sameCases[i]) }, sameCases[i])
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, answers[i], line) assert.Equal(t, template.HTML(answers[i]), line)
} }
testCases := []string{ testCases := []string{
@ -329,7 +330,7 @@ func TestTotal_RenderWiki(t *testing.T) {
IsWiki: true, IsWiki: true,
}, testCases[i]) }, testCases[i])
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, testCases[i+1], line) assert.Equal(t, template.HTML(testCases[i+1]), line)
} }
} }
@ -349,7 +350,7 @@ func TestTotal_RenderString(t *testing.T) {
Metas: localMetas, Metas: localMetas,
}, sameCases[i]) }, sameCases[i])
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, answers[i], line) assert.Equal(t, template.HTML(answers[i]), line)
} }
testCases := []string{} testCases := []string{}
@ -362,7 +363,7 @@ func TestTotal_RenderString(t *testing.T) {
}, },
}, testCases[i]) }, testCases[i])
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, testCases[i+1], line) assert.Equal(t, template.HTML(testCases[i+1]), line)
} }
} }
@ -429,7 +430,7 @@ func TestRenderEmojiInLinks_Issue12331(t *testing.T) {
` `
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, testcase) res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, testcase)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, expected, res) assert.Equal(t, template.HTML(expected), res)
} }
func TestColorPreview(t *testing.T) { func TestColorPreview(t *testing.T) {
@ -463,7 +464,7 @@ func TestColorPreview(t *testing.T) {
for _, test := range positiveTests { for _, test := range positiveTests {
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase) res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase)
assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase) assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase)
} }
@ -542,7 +543,7 @@ func TestMathBlock(t *testing.T) {
for _, test := range testcases { for _, test := range testcases {
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase) res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase)
assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase) assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase)
} }
} }
@ -778,12 +779,12 @@ foo: bar
for _, test := range testcases { for _, test := range testcases {
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase) res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase)
assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase) assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase)
} }
} }
func TestRenderLinks(t *testing.T) { func TestRenderLinks(t *testing.T) {
input := ` space @mention-user input := ` space @mention-user${SPACE}${SPACE}
/just/a/path.bin /just/a/path.bin
https://example.com/file.bin https://example.com/file.bin
[local link](file.bin) [local link](file.bin)
@ -804,8 +805,9 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
mail@domain.com mail@domain.com
@mention-user test @mention-user test
#123 #123
space space${SPACE}${SPACE}
` `
input = strings.ReplaceAll(input, "${SPACE}", " ") // replace ${SPACE} with " ", to avoid some editor's auto-trimming
cases := []struct { cases := []struct {
Links markup.Links Links markup.Links
IsWiki bool IsWiki bool
@ -1168,7 +1170,7 @@ space</p>
for i, c := range cases { for i, c := range cases {
result, err := markdown.RenderString(&markup.RenderContext{Ctx: context.Background(), Links: c.Links, IsWiki: c.IsWiki}, input) result, err := markdown.RenderString(&markup.RenderContext{Ctx: context.Background(), Links: c.Links, IsWiki: c.IsWiki}, input)
assert.NoError(t, err, "Unexpected error in testcase: %v", i) assert.NoError(t, err, "Unexpected error in testcase: %v", i)
assert.Equal(t, c.Expected, result, "Unexpected result in testcase %v", i) assert.Equal(t, template.HTML(c.Expected), result, "Unexpected result in testcase %v", i)
} }
} }

View file

@ -208,7 +208,7 @@ func RenderMarkdownToHtml(ctx context.Context, input string) template.HTML { //n
if err != nil { if err != nil {
log.Error("RenderString: %v", err) log.Error("RenderString: %v", err)
} }
return template.HTML(output) return output
} }
func RenderLabels(ctx context.Context, labels []*issues_model.Label, repoLink string) template.HTML { func RenderLabels(ctx context.Context, labels []*issues_model.Label, repoLink string) template.HTML {

View file

@ -4,6 +4,7 @@
package templates package templates
import ( import (
"fmt"
"html/template" "html/template"
"strings" "strings"
@ -28,6 +29,19 @@ func (su *StringUtils) HasPrefix(s any, prefix string) bool {
return false return false
} }
func (su *StringUtils) ToString(v any) string {
switch v := v.(type) {
case string:
return v
case template.HTML:
return string(v)
case fmt.Stringer:
return v.String()
default:
return fmt.Sprint(v)
}
}
func (su *StringUtils) Contains(s, substr string) bool { func (su *StringUtils) Contains(s, substr string) bool {
return strings.Contains(s, substr) return strings.Contains(s, substr)
} }

View file

@ -51,7 +51,7 @@ func toReleaseLink(ctx *context.Context, act *activities_model.Action) string {
// renderMarkdown creates a minimal markdown render context from an action. // renderMarkdown creates a minimal markdown render context from an action.
// If rendering fails, the original markdown text is returned // If rendering fails, the original markdown text is returned
func renderMarkdown(ctx *context.Context, act *activities_model.Action, content string) string { func renderMarkdown(ctx *context.Context, act *activities_model.Action, content string) template.HTML {
markdownCtx := &markup.RenderContext{ markdownCtx := &markup.RenderContext{
Ctx: ctx, Ctx: ctx,
Links: markup.Links{ Links: markup.Links{
@ -65,7 +65,7 @@ func renderMarkdown(ctx *context.Context, act *activities_model.Action, content
} }
markdown, err := markdown.RenderString(markdownCtx, content) markdown, err := markdown.RenderString(markdownCtx, content)
if err != nil { if err != nil {
return content return templates.Str2html(content) // old code did so: use Str2html to render in tmpl
} }
return markdown return markdown
} }
@ -75,7 +75,11 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
for _, act := range actions { for _, act := range actions {
act.LoadActUser(ctx) act.LoadActUser(ctx)
var content, desc, title string // TODO: the code seems quite strange (maybe not right)
// sometimes it uses text content but sometimes it uses HTML content
// it should clearly defines which kind of content it should use for the feed items: plan text or rich HTML
var title, desc string
var content template.HTML
link := &feeds.Link{Href: act.GetCommentHTMLURL(ctx)} link := &feeds.Link{Href: act.GetCommentHTMLURL(ctx)}
@ -229,7 +233,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
desc = act.GetIssueTitle(ctx) desc = act.GetIssueTitle(ctx)
comment := act.GetIssueInfos()[1] comment := act.GetIssueInfos()[1]
if len(comment) != 0 { if len(comment) != 0 {
desc += "\n\n" + renderMarkdown(ctx, act, comment) desc += "\n\n" + string(renderMarkdown(ctx, act, comment))
} }
case activities_model.ActionMergePullRequest, activities_model.ActionAutoMergePullRequest: case activities_model.ActionMergePullRequest, activities_model.ActionAutoMergePullRequest:
desc = act.GetIssueInfos()[1] desc = act.GetIssueInfos()[1]
@ -240,7 +244,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
} }
} }
if len(content) == 0 { if len(content) == 0 {
content = desc content = templates.Str2html(desc)
} }
// It's a common practice for feed generators to use plain text titles. // It's a common practice for feed generators to use plain text titles.
@ -261,7 +265,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
}, },
Id: fmt.Sprintf("%v: %v", strconv.FormatInt(act.ID, 10), link.Href), Id: fmt.Sprintf("%v: %v", strconv.FormatInt(act.ID, 10), link.Href),
Created: act.CreatedUnix.AsTime(), Created: act.CreatedUnix.AsTime(),
Content: content, Content: string(content),
}) })
} }
return items, err return items, err
@ -290,7 +294,8 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, i
return nil, err return nil, err
} }
var title, content string var title string
var content template.HTML
if rel.IsTag { if rel.IsTag {
title = rel.TagName title = rel.TagName
@ -319,7 +324,7 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, i
Email: rel.Publisher.GetEmail(), Email: rel.Publisher.GetEmail(),
}, },
Id: fmt.Sprintf("%v: %v", strconv.FormatInt(rel.ID, 10), link.Href), Id: fmt.Sprintf("%v: %v", strconv.FormatInt(rel.ID, 10), link.Href),
Content: content, Content: string(content),
}) })
} }

View file

@ -58,7 +58,7 @@ func showUserFeed(ctx *context.Context, formatType string) {
feed := &feeds.Feed{ feed := &feeds.Feed{
Title: ctx.Locale.TrString("home.feed_of", ctx.ContextUser.DisplayName()), Title: ctx.Locale.TrString("home.feed_of", ctx.ContextUser.DisplayName()),
Link: &feeds.Link{Href: ctx.ContextUser.HTMLURL()}, Link: &feeds.Link{Href: ctx.ContextUser.HTMLURL()},
Description: ctxUserDescription, Description: string(ctxUserDescription),
Created: time.Now(), Created: time.Now(),
} }

View file

@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
shared_user "code.gitea.io/gitea/routers/web/shared/user" shared_user "code.gitea.io/gitea/routers/web/shared/user"
@ -104,7 +105,7 @@ func Projects(ctx *context.Context) {
} }
for _, project := range projects { for _, project := range projects {
project.RenderedContent = project.Description project.RenderedContent = templates.Str2html(project.Description) // FIXME: is it right? why not render?
} }
err = shared_user.LoadHeaderCount(ctx) err = shared_user.LoadHeaderCount(ctx)
@ -395,7 +396,7 @@ func ViewProject(ctx *context.Context) {
} }
} }
project.RenderedContent = project.Description project.RenderedContent = templates.Str2html(project.Description) // FIXME: is it right? why not render?
ctx.Data["LinkedPRs"] = linkedPrsMap ctx.Data["LinkedPRs"] = linkedPrsMap
ctx.Data["PageIsViewProjects"] = true ctx.Data["PageIsViewProjects"] = true
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx) ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)

View file

@ -42,6 +42,7 @@ import (
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/templates/vars" "code.gitea.io/gitea/modules/templates/vars"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -1769,7 +1770,7 @@ func ViewIssue(ctx *context.Context) {
// so "|" is used as delimeter to mark the new format // so "|" is used as delimeter to mark the new format
if comment.Content[0] != '|' { if comment.Content[0] != '|' {
// handle old time comments that have formatted text stored // handle old time comments that have formatted text stored
comment.RenderedContent = comment.Content comment.RenderedContent = templates.Str2html(comment.Content)
comment.Content = "" comment.Content = ""
} else { } else {
// else it's just a duration in seconds to pass on to the frontend // else it's just a duration in seconds to pass on to the frontend

View file

@ -113,7 +113,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
cacheUsers[r.PublisherID] = r.Publisher cacheUsers[r.PublisherID] = r.Publisher
} }
r.Note, err = markdown.RenderString(&markup.RenderContext{ r.RenderedNote, err = markdown.RenderString(&markup.RenderContext{
Links: markup.Links{ Links: markup.Links{
Base: ctx.Repo.RepoLink, Base: ctx.Repo.RepoLink,
}, },

View file

@ -22,7 +22,7 @@
{{.locale.Tr "mail.release.note"}}<br> {{.locale.Tr "mail.release.note"}}<br>
{{- if eq .Release.RenderedNote ""}} {{- if eq .Release.RenderedNote ""}}
{{else}} {{else}}
{{.Release.RenderedNote | Str2html}} {{.Release.RenderedNote}}
{{end -}} {{end -}}
</p> </p>
<br><br> <br><br>

View file

@ -18,7 +18,7 @@
{{end}} {{end}}
</span> </span>
</div> </div>
{{if .RenderedDescription}}<div class="render-content markup">{{.RenderedDescription | Str2html}}</div>{{end}} {{if .RenderedDescription}}<div class="render-content markup">{{.RenderedDescription}}</div>{{end}}
<div class="text light meta gt-mt-2"> <div class="text light meta gt-mt-2">
{{if .Org.Location}}<div class="flex-text-block">{{svg "octicon-location"}} <span>{{.Org.Location}}</span></div>{{end}} {{if .Org.Location}}<div class="flex-text-block">{{svg "octicon-location"}} <span>{{.Org.Location}}</span></div>{{end}}
{{if .Org.Website}}<div class="flex-text-block">{{svg "octicon-link"}} <a class="muted" target="_blank" rel="noopener noreferrer me" href="{{.Org.Website}}">{{.Org.Website}}</a></div>{{end}} {{if .Org.Website}}<div class="flex-text-block">{{svg "octicon-link"}} <a class="muted" target="_blank" rel="noopener noreferrer me" href="{{.Org.Website}}">{{.Org.Website}}</a></div>{{end}}

View file

@ -11,7 +11,7 @@
<div class="ui mobile reversed stackable grid"> <div class="ui mobile reversed stackable grid">
<div class="ui {{if .ShowMemberAndTeamTab}}eleven wide{{end}} column"> <div class="ui {{if .ShowMemberAndTeamTab}}eleven wide{{end}} column">
{{if .ProfileReadme}} {{if .ProfileReadme}}
<div id="readme_profile" class="markup">{{.ProfileReadme | Str2html}}</div> <div id="readme_profile" class="markup">{{.ProfileReadme}}</div>
{{end}} {{end}}
{{template "explore/repo_search" .}} {{template "explore/repo_search" .}}
{{template "explore/repo_list" .}} {{template "explore/repo_list" .}}

View file

@ -20,7 +20,7 @@
<h4 class="ui top attached header">{{ctx.Locale.Tr "packages.about"}}</h4> <h4 class="ui top attached header">{{ctx.Locale.Tr "packages.about"}}</h4>
<div class="ui attached segment"> <div class="ui attached segment">
{{if .PackageDescriptor.Metadata.Description}}{{.PackageDescriptor.Metadata.Description}}{{end}} {{if .PackageDescriptor.Metadata.Description}}{{.PackageDescriptor.Metadata.Description}}{{end}}
{{if .PackageDescriptor.Metadata.ReleaseNotes}}{{Str2html .PackageDescriptor.Metadata.ReleaseNotes}}{{end}} {{if .PackageDescriptor.Metadata.ReleaseNotes}}{{.PackageDescriptor.Metadata.ReleaseNotes}}{{end}}
</div> </div>
{{end}} {{end}}

View file

@ -75,7 +75,7 @@
</div> </div>
{{if .Description}} {{if .Description}}
<div class="content"> <div class="content">
{{.RenderedContent|Str2html}} {{.RenderedContent}}
</div> </div>
{{end}} {{end}}
</li> </li>

View file

@ -58,7 +58,7 @@
{{end}} {{end}}
</div> </div>
<div class="content">{{$.Project.RenderedContent|Str2html}}</div> <div class="content">{{$.Project.RenderedContent}}</div>
<div class="divider"></div> <div class="divider"></div>
</div> </div>

View file

@ -55,7 +55,7 @@
<div class="ui attached segment comment-body"> <div class="ui attached segment comment-body">
<div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}data-can-edit="true"{{end}}> <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
{{if .RenderedContent}} {{if .RenderedContent}}
{{.RenderedContent|Str2html}} {{.RenderedContent}}
{{else}} {{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span> <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}} {{end}}

View file

@ -22,7 +22,7 @@
</div> </div>
{{if .Milestone.RenderedContent}} {{if .Milestone.RenderedContent}}
<div class="markup content gt-mb-4"> <div class="markup content gt-mb-4">
{{.Milestone.RenderedContent|Str2html}} {{.Milestone.RenderedContent}}
</div> </div>
{{end}} {{end}}
<div class="gt-df gt-fc gt-gap-3"> <div class="gt-df gt-fc gt-gap-3">

View file

@ -82,7 +82,7 @@
</div> </div>
{{if .Content}} {{if .Content}}
<div class="markup content"> <div class="markup content">
{{.RenderedContent|Str2html}} {{.RenderedContent}}
</div> </div>
{{end}} {{end}}
</li> </li>

View file

@ -54,7 +54,7 @@
<div class="ui attached segment comment-body" role="article"> <div class="ui attached segment comment-body" role="article">
<div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission $.IsIssuePoster}}data-can-edit="true"{{end}}> <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission $.IsIssuePoster}}data-can-edit="true"{{end}}>
{{if .Issue.RenderedContent}} {{if .Issue.RenderedContent}}
{{.Issue.RenderedContent|Str2html}} {{.Issue.RenderedContent}}
{{else}} {{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span> <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}} {{end}}

View file

@ -8,7 +8,7 @@
<div class="gt-f1 gt-p-3"> <div class="gt-f1 gt-p-3">
<a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}"> <a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}">
{{if FilenameIsImage .Name}} {{if FilenameIsImage .Name}}
{{if not (StringUtils.Contains $.Content .UUID)}} {{if not (StringUtils.Contains (StringUtils.ToString $.Content) .UUID)}}
{{$hasThumbnails = true}} {{$hasThumbnails = true}}
{{end}} {{end}}
{{svg "octicon-file"}} {{svg "octicon-file"}}
@ -29,7 +29,7 @@
<div class="ui small thumbnails"> <div class="ui small thumbnails">
{{- range .Attachments -}} {{- range .Attachments -}}
{{if FilenameIsImage .Name}} {{if FilenameIsImage .Name}}
{{if not (StringUtils.Contains $.Content .UUID)}} {{if not (StringUtils.Contains (StringUtils.ToString $.Content) .UUID)}}
<a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}"> <a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}">
<img alt="{{.Name}}" src="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}"> <img alt="{{.Name}}" src="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}">
</a> </a>

View file

@ -61,7 +61,7 @@
<div class="ui attached segment comment-body" role="article"> <div class="ui attached segment comment-body" role="article">
<div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}> <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
{{if .RenderedContent}} {{if .RenderedContent}}
{{.RenderedContent|Str2html}} {{.RenderedContent}}
{{else}} {{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span> <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}} {{end}}
@ -436,7 +436,7 @@
<div class="ui attached segment comment-body"> <div class="ui attached segment comment-body">
<div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}> <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
{{if .RenderedContent}} {{if .RenderedContent}}
{{.RenderedContent|Str2html}} {{.RenderedContent}}
{{else}} {{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span> <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}} {{end}}
@ -635,7 +635,7 @@
<div class="ui attached segment"> <div class="ui attached segment">
<div class="render-content markup"> <div class="render-content markup">
{{if .RenderedContent}} {{if .RenderedContent}}
{{.RenderedContent|Str2html}} {{.RenderedContent}}
{{else}} {{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span> <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}} {{end}}

View file

@ -87,7 +87,7 @@
<div class="text comment-content"> <div class="text comment-content">
<div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}> <div class="render-content markup" {{if or $.Permission.IsAdmin $.HasIssuesOrPullsWritePermission (and $.IsSigned (eq $.SignedUserID .PosterID))}}data-can-edit="true"{{end}}>
{{if .RenderedContent}} {{if .RenderedContent}}
{{.RenderedContent|Str2html}} {{.RenderedContent}}
{{else}} {{else}}
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span> <span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
{{end}} {{end}}

View file

@ -58,7 +58,7 @@
{{end}} {{end}}
</p> </p>
<div class="markup desc"> <div class="markup desc">
{{Str2html $release.Note}} {{$release.RenderedNote}}
</div> </div>
<div class="divider"></div> <div class="divider"></div>
<details class="download" {{if eq $idx 0}}open{{end}}> <details class="download" {{if eq $idx 0}}open{{end}}>

View file

@ -70,7 +70,7 @@
{{end}} {{end}}
{{if $.RenderedDescription}} {{if $.RenderedDescription}}
<li> <li>
<div class="render-content markup">{{$.RenderedDescription|Str2html}}</div> <div class="render-content markup">{{$.RenderedDescription}}</div>
</li> </li>
{{end}} {{end}}
{{range .OpenIDs}} {{range .OpenIDs}}

View file

@ -141,7 +141,7 @@
</div> </div>
{{if .Content}} {{if .Content}}
<div class="markup content"> <div class="markup content">
{{.RenderedContent|Str2html}} {{.RenderedContent}}
</div> </div>
{{end}} {{end}}
</li> </li>

View file

@ -30,7 +30,7 @@
{{else if eq .TabName "followers"}} {{else if eq .TabName "followers"}}
{{template "repo/user_cards" .}} {{template "repo/user_cards" .}}
{{else if eq .TabName "overview"}} {{else if eq .TabName "overview"}}
<div id="readme_profile" class="markup">{{.ProfileReadme | Str2html}}</div> <div id="readme_profile" class="markup">{{.ProfileReadme}}</div>
{{else}} {{else}}
{{template "explore/repo_search" .}} {{template "explore/repo_search" .}}
{{template "explore/repo_list" .}} {{template "explore/repo_list" .}}