Sorting values obtained github

Hello all! First post here - I appreciate this community and all the knowledge you’ve put time and effort into. Many solutions I’ve found just looking through here. Thank you!

I’m writing a project showcase or a gallery of projects that are obtained via github links. Images are created by rewriting the github link to a graphql link which gives me an image that I can use as a list of cards. All that is working fine.

My front page looks like this - - which is neat.

But what would be cool is if I could sort those projects based on the last commit date that I obtain using get.json() from latest to the oldest. I’m not able to find information on how to do that - I am familiar with how to sort using the built-in front matter - but so far this been problematic.

I’m looking for any suggestions on how I could to wit:
go through my site pages for projects. Query the github repo from the user defined githublink field I have and then get the last commit date and then display all the projects in order.

I suppose i could do a loop of the front matter variables and put them into a list and then sort it and then do another list to display it?

I appreciate your time and effort on helping me. Thank you!

The sort function is what you are looking for. For example,

[{"name": "foo", "updated_at": "2023-11-14"},{"name": "bar", "updated_at": "2023-11-13"}]
{{ with getJSON "" }}
  {{ sort . "updated_at" | warnf "%v" }}
  {{ sort . "updated_at" "desc" | warnf "%v" }}
{{ end }}
WARN  [map[name:bar updated_at:2023-11-13] map[name:foo updated_at:2023-11-14]]
WARN  [map[name:foo updated_at:2023-11-14] map[name:bar updated_at:2023-11-13]]
1 Like

First of all - thank you for taking the time to answer my question. Very much appreciated. I have a follow up question.

Where would this code go?

First loop:
read githublink

Second loop:
whle read output of sort
display item with css

Is that the correct method?

You should 1) fetch all the data, 2) and then sort it, finally render/loop it.

I don’t know if there is a GitHub API for querying multiple repos, but you can fetch repo one by one.

{{ $repoNames := slice "hugomods/search" "hugomods/images" }}
{{ $repos := slice }}
{{ range $repoNames }}
  {{ with getJSON (printf "" .) }}
    {{ $repos = $repos | append . }}
  {{ end }}
{{ end }}
  {{ range sort $repos "updated_at" "desc" }}
    <li>{{ .full_name }}</li>
  {{ end }}
1 Like

Oh excellent! Thank you so much - that makes it much clearer. I’ll need to add one more loop to replace that first line to iterate though projects and get their github link. Interestingly with this - the md files I create are more like ‘track this project’ rather than actual content. I’ll report back on what I did. Thank you @razon ! If you have a ko-fi link or some other thing that I can show my appreciation - let me know!

I’ll need to add one more loop to replace that first line to iterate though projects and get their github link

The GitHub link field is html_url. You can find the response schema on Repositories - GitHub Docs.

  {{ range sort $repos "updated_at" "desc" }}
     <a href="{{ .html_url }}">{{ .full_name }}</a>
  {{ end }}

If you’re going to use this approach, I suggest set up a GitHub token for APIs, otherwise you may encounter rate limit issues.

{{ $opts := dict "Authorization" (printf "Bearer %s" (getenv "GITHUB_TOKEN")) }}
{{ $data := getJSON "" $opts }}

The code snippet reads the GitHub token from env vars, since the it is sensitive.

You need to append the GITHUB_TOKEN to security.funcs.getenv as well, read more on Hugo's security model | Hugo

1 Like

Thanks for this. I’m having some trouble with the sorting portion. Specifically this part.

{{ range sort $repos "updated_at" "desc" }}

How does it know that ‘updated_at’ is in the github json context vs say “.fullname” I understand that the “.” refers to the json object.

Here is what I have:

  {{ $repos := slice }}
    {{ $headers := (dict "Authorization" .Site.Params.githubToken) }}
    {{ $header := "Authorization:Bearer " }}
    {{ $token := .Site.Params.githubToken }}
    {{ $authHeader := printf "%s%s " $header $token }}
    {{ range (where .Site.RegularPages "Section" "projects").Reverse }}
      {{ $s := .Params.githublink }}
      {{ $gh_repo_query_url := replaceRE `(` "" $s }}
      {{ with getJSON $gh_repo_query_url $headers }}
        {{ $repos = $repos | append . }}
      {{ end }}
    {{ end }}

    {{ $gh_sorted_by_activity := sort $repos "updated_at"  "desc"}}
    {{ print $gh_sorted_by_activity }}
    {{ return $gh_sorted_by_activity }}

Then in my index html:

<div class="projectgrid-recent-container">
  {{ range partial "return-recent-github-projects.html" . }}
	<div class="projectgrid-recent-items">
    {{ $cur_github_url := .html_url }}
    {{ $repo_image := replaceRE `(` "" $cur_github_url }}
    <a href="{{ $cur_github_url }}"> <img src={{ $repo_image }}> </img> </a>
  {{ end }}

The CSS just makes a grid and puts everything with a open graph image. I can paste that if it is relevant - but the display of the projects work just fine so it might not be relevant.

The output comes out not in sorted order - the first one is 3 weeks since the last update, 2 weeks, then 1 day, and then 5 weeks. So something is off here but I’m not sure what I need to debug here.

Since it sort by the field returned by GitHub, you can print the updated_at to check if it work as expected, if the updated_at is not the date field you want, you may need to change it with the right field.

You can use other APIs for fetching the right date you need if there isn’t in current API, e.g.

Latest commit date on specified branch: Branches - GitHub Docs
Latest release date: Releases - GitHub Docs