return ctx
}
+func NewTemplateContextForWeb(ctx *Context) TemplateContext {
+ tmplCtx := NewTemplateContext(ctx)
+ tmplCtx["Locale"] = ctx.Base.Locale
+ tmplCtx["AvatarUtils"] = templates.NewAvatarUtils(ctx)
+ return tmplCtx
+}
+
+func NewWebContext(base *Base, render Render, session session.Store) *Context {
+ ctx := &Context{
+ Base: base,
+ Render: render,
+ Session: session,
+
+ Cache: mc.GetCache(),
+ Link: setting.AppSubURL + strings.TrimSuffix(base.Req.URL.EscapedPath(), "/"),
+ Repo: &Repository{PullRequest: &PullRequest{}},
+ Org: &Organization{},
+ }
+ ctx.TemplateContext = NewTemplateContextForWeb(ctx)
+ ctx.Flash = &middleware.Flash{DataStore: ctx, Values: url.Values{}}
+ return ctx
+}
+
// Contexter initializes a classic context for a request.
func Contexter() func(next http.Handler) http.Handler {
rnd := templates.HTMLRenderer()
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
base, baseCleanUp := NewBaseContext(resp, req)
- ctx := &Context{
- Base: base,
- Cache: mc.GetCache(),
- Link: setting.AppSubURL + strings.TrimSuffix(req.URL.EscapedPath(), "/"),
- Render: rnd,
- Session: session.GetSession(req),
- Repo: &Repository{PullRequest: &PullRequest{}},
- Org: &Organization{},
- }
defer baseCleanUp()
-
- // TODO: "install.go" also shares the same logic, which should be refactored to a general function
- ctx.TemplateContext = NewTemplateContext(ctx)
- ctx.TemplateContext["Locale"] = ctx.Locale
- ctx.TemplateContext["AvatarUtils"] = templates.NewAvatarUtils(ctx)
+ ctx := NewWebContext(base, rnd, session.GetSession(req))
ctx.Data.MergeFrom(middleware.CommonTemplateContextData())
ctx.Data["Context"] = ctx // TODO: use "ctx" in template and remove this
}
}
- // prepare an empty Flash message for current request
- ctx.Flash = &middleware.Flash{DataStore: ctx, Values: url.Values{}}
+ // if there are new messages in the ctx.Flash, write them into cookie
ctx.Resp.Before(func(resp ResponseWriter) {
if val := ctx.Flash.Encode(); val != "" {
middleware.SetSiteCookie(ctx.Resp, CookieNameFlash, val, 0)
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
base, baseCleanUp := NewBaseContext(resp, req)
- ctx := &Context{
- Base: base,
- Render: renderer, // it is still needed when rendering 500 page in a package handler
- }
defer baseCleanUp()
+ // it is still needed when rendering 500 page in a package handler
+ ctx := NewWebContext(base, renderer, nil)
ctx.Base.AppendContextValue(WebContextKey, ctx)
next.ServeHTTP(ctx.Resp, ctx.Req)
})
resp := httptest.NewRecorder()
req := mockRequest(t, reqPath)
base, baseCleanUp := context.NewBaseContext(resp, req)
+ _ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
base.Data = middleware.GetContextData(req.Context())
base.Locale = &translation.MockLocale{}
- ctx := &context.Context{
- Base: base,
- Render: &mockRender{},
- Flash: &middleware.Flash{Values: url.Values{}},
- }
- _ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
+
+ ctx := context.NewWebContext(base, &MockRender{}, nil)
+ ctx.Flash = &middleware.Flash{Values: url.Values{}}
chiCtx := chi.NewRouteContext()
ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
assert.NoError(t, err)
}
-type mockRender struct{}
+type MockRender struct{}
-func (tr *mockRender) TemplateLookup(tmpl string, _ gocontext.Context) (templates.TemplateExecutor, error) {
+func (tr *MockRender) TemplateLookup(tmpl string, _ gocontext.Context) (templates.TemplateExecutor, error) {
return nil, nil
}
-func (tr *mockRender) HTML(w io.Writer, status int, _ string, _ any, _ gocontext.Context) error {
+func (tr *MockRender) HTML(w io.Writer, status int, _ string, _ any, _ gocontext.Context) error {
if resp, ok := w.(http.ResponseWriter); ok {
resp.WriteHeader(status)
}
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
base, baseCleanUp := context.NewBaseContext(resp, req)
- ctx := &context.Context{
- Base: base,
- Flash: &middleware.Flash{},
- Render: rnd,
- Session: session.GetSession(req),
- }
defer baseCleanUp()
- ctx.TemplateContext = context.NewTemplateContext(ctx)
- ctx.TemplateContext["Locale"] = ctx.Locale
-
+ ctx := context.NewWebContext(base, rnd, session.GetSession(req))
ctx.AppendContextValue(context.WebContextKey, ctx)
ctx.Data.MergeFrom(middleware.CommonTemplateContextData())
ctx.Data.MergeFrom(middleware.ContextData{
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
- ctx.Data["Actors"] = repo.MakeSelfOnTop(ctx, actors)
+ ctx.Data["Actors"] = repo.MakeSelfOnTop(ctx.Doer, actors)
ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx)
"sort"
"code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/context"
)
-func MakeSelfOnTop(ctx *context.Context, users []*user.User) []*user.User {
- if ctx.Doer != nil {
+func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User {
+ if doer != nil {
sort.Slice(users, func(i, j int) bool {
if users[i].ID == users[j].ID {
return false
}
- return users[i].ID == ctx.Doer.ID // if users[i] is self, put it before others, so less=true
+ return users[i].ID == doer.ID // if users[i] is self, put it before others, so less=true
})
}
return users
"testing"
"code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/context"
"github.com/stretchr/testify/assert"
)
func TestMakeSelfOnTop(t *testing.T) {
- users := MakeSelfOnTop(&context.Context{}, []*user.User{{ID: 2}, {ID: 1}})
+ users := MakeSelfOnTop(nil, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 2, users[0].ID)
- users = MakeSelfOnTop(&context.Context{Doer: &user.User{ID: 1}}, []*user.User{{ID: 2}, {ID: 1}})
+ users = MakeSelfOnTop(&user.User{ID: 1}, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 1, users[0].ID)
- users = MakeSelfOnTop(&context.Context{Doer: &user.User{ID: 2}}, []*user.User{{ID: 2}, {ID: 1}})
+ users = MakeSelfOnTop(&user.User{ID: 2}, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 2, users[0].ID)
}
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
handleTeamMentions(ctx)
if ctx.Written() {
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
handleTeamMentions(ctx)
}
}
}
- posters = MakeSelfOnTop(ctx, posters)
+ posters = MakeSelfOnTop(ctx.Doer, posters)
resp := &userSearchResponse{}
resp.Results = make([]*userSearchInfo, len(posters))
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
handleTeamMentions(ctx)
if ctx.Written() {
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
upload.AddUploadContext(ctx, "release")
ctx.ServerError("GetRepoAssignees", err)
return
}
- ctx.Data["Assignees"] = MakeSelfOnTop(ctx, assigneeUsers)
+ ctx.Data["Assignees"] = MakeSelfOnTop(ctx.Doer, assigneeUsers)
ctx.HTML(http.StatusOK, tplReleaseNew)
}
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/models/user"
gitea_context "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
)
assert.NoError(t, err)
base, baseCleanUp := gitea_context.NewBaseContext(httptest.NewRecorder(), req)
defer baseCleanUp()
- giteaCtx := &gitea_context.Context{Base: base}
+ giteaCtx := gitea_context.NewWebContext(base, &test.MockRender{}, nil)
assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPublic))
assert.False(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPrivate))