
Little game of Spot the Difference for you. On the left we see Gitea’s default activity feed. You’ll notice it’s absolutely littered with that user’s profile picture, but it’s not obvious at a glance that all this work happened across several repos.
The look on the right is what we’ll be trying to achieve. For me and my org, where we have many small projects, this is much better! Read on if you agree.
The template file
Gitea is open source and quite customisable. Sadly, there doesn’t seem to be a setting for what we’re after, but much of Gitea’s markup lives in template files that can be overridden by putting a file in the same relative location under <gitea dir>/custom/templates/
.
To find the file we need to override, we might look for something distinctive in the page source and just search for that in Gitea’s public repository. For our purposes, id="activity-feed"
leads us to /templates/user/dashboard/feeds.tmpl. Currently, it ships like this:
<div id="activity-feed" class="flex-list">
{{range .Feeds}}
<div class="flex-item">
<div class="flex-item-leading">
{{ctx.AvatarUtils.AvatarByAction .}}
</div>
<div class="flex-item-main tw-gap-2">
<div>
{{if gt .ActUser.ID 0}}
<a href="{{AppSubUrl}}/{{(.GetActUserName ctx) | PathEscape}}" title="{{.GetActDisplayNameTitle ctx}}">{{.GetActDisplayName ctx}}</a>
{{else}}
{{.ShortActUserName ctx}}
{{end}}
<!-- … -->
(You’ll be glad to hear that I won’t go into this templating language – I don’t even know what it is. In fact, you can probably figure out the rest from here, but indulge me as I inflate this to a short blog post.)
As we can see, every item in the list leads with {{ctx.AvatarUtils.AvatarByAction .}}
. This renders the <img>
with the user’s profile picture with default width
and height
attributes. This is where we would like to see the repo’s avatar instead, so that’s what we’re going to replace.
Since there is no template for just rendering the avatar, we have to override the entire feeds.tmpl
file, so let’s copy it to <gitea dir>/custom/templates/user/dashboard/feeds.tmpl
. Just create the missing directories. If we restart Gitea now, it will use that file instead of the built-in template.
Moving the user avatar out of the way
Before we replace it with the repo avatar, we’ll move the user avatar into that <a>
element further down, which currently only shows the user’s name and links to their profile.
To fit into the line of text and match the all other small avatars, it needs to be scaled down to 16px. Thankfully we can just add the image size as the next argument. We end up with this code inside the link:
{{ctx.AvatarUtils.AvatarByAction . 16}} {{.GetActDisplayName ctx}}
Outputting the repo avatar
Moving on to the repo avatar, it gets slightly less convenient. There is a template that renders repo avatars, which currently looks like this:
{{$avatarLink := (.RelAvatarLink ctx)}}
{{if $avatarLink}}
<img class="ui avatar tw-align-middle" src="{{$avatarLink}}" width="24" height="24" alt aria-hidden="true">
{{else if $.IsMirror}}
{{svg "octicon-mirror" 24}}
{{else if $.IsFork}}
{{svg "octicon-repo-forked" 24}}
{{else}}
{{svg "octicon-repo" 24}}
{{end}}
Unfortunately it’s hardcoded to 24px, so we’ll just copy the whole thing over and make our modifications.
The important bit is in the first line, where we need to fix the path to the repo, since the original template assumes its context to be the repo itself, while we’re inside an activity feed item (Action
). Some guesswork (or a peek further down in the template file) tells us that Action
s have a Repo
property we can use.
We end up with our feeds.tmpl
looking like this:
<div id="activity-feed" class="flex-list">
{{range .Feeds}}
<div class="flex-item">
<div class="flex-item-leading">
{{$repoAvatarLink := (.Repo.RelAvatarLink ctx)}}
{{if $repoAvatarLink}}
<img class="ui avatar tw-align-middle" src="{{$repoAvatarLink}}" width="40" height="40" alt aria-hidden="true">
{{else if $.IsMirror}}
{{svg "octicon-mirror" 40}}
{{else if $.IsFork}}
{{svg "octicon-repo-forked" 40}}
{{else}}
{{svg "octicon-repo" 40}}
{{end}}
</div>
<div class="flex-item-main tw-gap-2">
<div>
{{if gt .ActUser.ID 0}}
<a href="{{AppSubUrl}}/{{(.GetActUserName ctx) | PathEscape}}" title="{{.GetActDisplayNameTitle ctx}}">{{ctx.AvatarUtils.AvatarByAction . 16}} {{.GetActDisplayName ctx}}</a>
{{else}}
{{.ShortActUserName ctx}}
{{end}}
<!-- … -->
Personally I’ve set the image size to 40px, which, as you’ll have noticed in the image at the top, is slightly bigger than the original user avatars.
We can now restart Gitea and check out the new look.
Concerns
I have not had to update Gitea since making this customisation. Naturally, if Gitea makes changes to the original feeds.tmpl
, we won’t get them. Changes to functions and properties we’re calling may also cause breakage. Such is the nature of customisation, and we’ll have to cross that bridge when we get to it, but it’s only cosmetics and if anything happens we can easily go back to the official look by just removing the custom template file.
Todos for later
Perhaps make the repo avatar link to its page?
Cheers.