add path config option, which is used to determine the resulting URL

7f84e677975fa5c05bcc85b460f7dceddfc65559

Tucker McKnight <tucker.mcknight@gmail.com> | Sun Aug 31 2025

add path config option, which is used to determine the resulting URL
main.ts:15
Before
14
15
16
17


18
  // TODO: throw an error if reposConfiguration is undefined

  const reposData = await repos(reposConfiguration)

⁣
⁣
  eleventyConfig.addFilter("getFileName", (filePath) => {
    const pathParts = filePath.split("/")
After
14
15
16
17
18
19
20
  // TODO: throw an error if reposConfiguration is undefined

  const reposData = await repos(reposConfiguration)
  const reposPath = reposConfiguration.path || "/repos"
  eleventyConfig.addGlobalData("reposPath", reposPath)

  eleventyConfig.addFilter("getFileName", (filePath) => {
    const pathParts = filePath.split("/")
main.ts:38
Before
37
38
39
40
41
42
        const repoConfig = reposConfiguration.repos[repoName]
        if (repoConfig._type === "darcs") {
          for (let branch in repoConfig.branches) {
            const repoPath = eleventyConfig.dir.output + "/repos/" + eleventyConfig.getFilter("slugify")(repoName) + "/branches/" + branch
            const originalLocation = repoConfig.branches[branch].location
            // If it is there, do darcs pull
            if (fsImport.existsSync(repoPath + "/_darcs")) {
After
37
38
39
40
41
42
        const repoConfig = reposConfiguration.repos[repoName]
        if (repoConfig._type === "darcs") {
          for (let branch in repoConfig.branches) {
            const repoPath = eleventyConfig.dir.output + reposPath + "/" + eleventyConfig.getFilter("slugify")(repoName) + "/branches/" + branch
            const originalLocation = repoConfig.branches[branch].location
            // If it is there, do darcs pull
            if (fsImport.existsSync(repoPath + "/_darcs")) {
main.ts:49
Before
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
            }
          }
        } else if (repoConfig._type === "git") {
          const repoPath = eleventyConfig.dir.output + "/repos/" + eleventyConfig.getFilter("slugify")(repoName)
          const gitRepoName = eleventyConfig.getFilter("slugify")(repoName) + ".git"
          // If it is there, do git pull
          if (fsImport.existsSync(repoPath + ".git")) {
            // git repos are just in the repos folder, not in their subdir
            // create string of commands saying 'git fetch origin branch:branch' for each branch
            const fetchCommands = repoConfig.branchesToPull.map(branch => `git fetch origin ${branch}:${branch}`).join('; ')
            await exec(`(cd ${eleventyConfig.dir.output + "/repos/" + gitRepoName} && ${fetchCommands}; git update-server-info)`)
          } else {
            // If it is not there, do git clone
            const originalLocation = repoConfig.location
            await exec(`(cd ${eleventyConfig.dir.output + "/repos/"} && git clone ${originalLocation} ${gitRepoName} --bare)`)
            await exec(`(cd ${eleventyConfig.dir.output + "/repos/" + gitRepoName} && git update-server-info)`)
          }
        }
      }
After
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
            }
          }
        } else if (repoConfig._type === "git") {
          const repoPath = eleventyConfig.dir.output + reposPath + "/" + eleventyConfig.getFilter("slugify")(repoName)
          const gitRepoName = eleventyConfig.getFilter("slugify")(repoName) + ".git"
          // If it is there, do git pull
          if (fsImport.existsSync(repoPath + ".git")) {
            // git repos are just in the repos folder, not in their subdir
            // create string of commands saying 'git fetch origin branch:branch' for each branch
            const fetchCommands = repoConfig.branchesToPull.map(branch => `git fetch origin ${branch}:${branch}`).join('; ')
            await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/" + gitRepoName} && ${fetchCommands}; git update-server-info)`)
          } else {
            // If it is not there, do git clone
            const originalLocation = repoConfig.location
            await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/"} && git clone ${originalLocation} ${gitRepoName} --bare)`)
            await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/" + gitRepoName} && git update-server-info)`)
          }
        }
      }
main.ts:197
Before
196
197
198
199
200
201
    'repos/index.njk',
    topLayoutPartial + indexTemplate + bottomLayoutPartial,
    {
      permalink: "repos/index.html",
    }
  )
After
196
197
198
199
200
201
    'repos/index.njk',
    topLayoutPartial + indexTemplate + bottomLayoutPartial,
    {
      permalink: `${reposPath}/index.html`,
    }
  )
main.ts:216
Before
215
216
217
218
219
220
      permalink: (data) => {
        const repoName = data.branchInfo.repoName
        const branchName = data.branchInfo.branchName
        return `repos/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/list/`
      },
      eleventyComputed: {
        nav: {
After
215
216
217
218
219
220
      permalink: (data) => {
        const repoName = data.branchInfo.repoName
        const branchName = data.branchInfo.branchName
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/list/`
      },
      eleventyComputed: {
        nav: {
main.ts:244
Before
243
244
245
246
247
248
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
        return `repos/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/files/${eleventyConfig.getFilter("slugify")(data.fileInfo.file)}.html`
      },
      eleventyComputed: {
        nav: {
After
243
244
245
246
247
248
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/files/${eleventyConfig.getFilter("slugify")(data.fileInfo.file)}.html`
      },
      eleventyComputed: {
        nav: {
main.ts:270
Before
269
270
271
272
273
274
      permalink: (data) => {
        const repoName = data.branchInfo.repoName
        const branchName = data.branchInfo.branchName
        return `repos/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/files/`
      },
      eleventyComputed: {
        nav: {
After
269
270
271
272
273
274
      permalink: (data) => {
        const repoName = data.branchInfo.repoName
        const branchName = data.branchInfo.branchName
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/files/`
      },
      eleventyComputed: {
        nav: {
main.ts:296
Before
295
296
297
298
299
300
      permalink: (data) => {
        const repoName = data.branch.repoName
        const branchName = data.branch.branchName
        return `repos/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/`
      },
      eleventyComputed: {
        nav: {
After
295
296
297
298
299
300
      permalink: (data) => {
        const repoName = data.branch.repoName
        const branchName = data.branch.branchName
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branchName)}/`
      },
      eleventyComputed: {
        nav: {
partial_templates/main_top.njk:46
Before
45
46
47
48
49
50
            <div class="row d-flex justify-content-between pb-3">
              <div class="col-auto">
                <nav class="fs-4">
                  <a href="/">Repositories</a>{% if nav.repoName %}<span class="text-secondary mx-2">&gt;</span><a href="/repos/{{nav.repoName | slugify}}/branches/{{reposConfig.repos[nav.repoName].defaultBranch | slugify}}">{{nav.repoName}}</a>{% endif %}
                </nav>
              </div>
              <div class="col-auto d-flex align-items-center">
After
45
46
47
48
49
50
            <div class="row d-flex justify-content-between pb-3">
              <div class="col-auto">
                <nav class="fs-4">
                  <a href="/">Repositories</a>{% if nav.repoName %}<span class="text-secondary mx-2">&gt;</span><a href="{{reposPath}}/{{nav.repoName | slugify}}/branches/{{reposConfig.repos[nav.repoName].defaultBranch | slugify}}">{{nav.repoName}}</a>{% endif %}
                </nav>
              </div>
              <div class="col-auto d-flex align-items-center">
partial_templates/main_top.njk:68
Before
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
                <nav class="nav-tabs">
                  <ul class="nav">
                    <li class="nav-item">
                      <a class="nav-link {% if navTab == "landing" %}active{% endif %}" href="/repos/{{nav.repoName | slugify}}/branches/{{nav.branchName}}">Landing Page</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link {% if navTab == "files" %}active{% endif %}" href="/repos/{{nav.repoName | slugify}}/branches/{{nav.branchName}}/files">Files</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link {% if navTab == "patches" %}active{% endif %}" href="/repos/{{nav.repoName | slugify}}/branches/{{nav.branchName}}/patches/page1">Changes</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link {% if navTab == "branches" %}active{% endif %}" href="/repos/{{nav.repoName | slugify}}/branches/{{nav.branchName | slugify}}/list">Branches</a>
                    </li>
                  </ul>
                </nav>
After
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
                <nav class="nav-tabs">
                  <ul class="nav">
                    <li class="nav-item">
                      <a class="nav-link {% if navTab == "landing" %}active{% endif %}" href="{{reposPath}}/{{nav.repoName | slugify}}/branches/{{nav.branchName}}">Landing Page</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link {% if navTab == "files" %}active{% endif %}" href="{{reposPath}}/{{nav.repoName | slugify}}/branches/{{nav.branchName}}/files">Files</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link {% if navTab == "patches" %}active{% endif %}" href="{{reposPath}}/{{nav.repoName | slugify}}/branches/{{nav.branchName}}/patches/page1">Changes</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link {% if navTab == "branches" %}active{% endif %}" href="{{reposPath}}/{{nav.repoName | slugify}}/branches/{{nav.branchName | slugify}}/list">Branches</a>
                    </li>
                  </ul>
                </nav>
templates/branches.njk:2
Before
1
2
3
4
5
6
{% for branch in branches %}
  {% set description = reposConfig.repos[branch.repoName].branches[branch.branchName].description %}
  {% if branch.repoName == branchInfo.repoName %}
  <li><a href="/repos/{{branch.repoName | slugify}}/branches/{{branch.branchName | slugify}}">{{branch.branchName}}</a>{% if branch.branchName == branchInfo.branchName %} (current){% endif %}{% if description %} - {{ description }}{% endif %}</li>
  {% endif %}
{% endfor %}
</ul>
After
1
2
3
4
5
6
{% for branch in branches %}
  {% set description = reposConfig.repos[branch.repoName].branches[branch.branchName].description %}
  {% if branch.repoName == branchInfo.repoName %}
  <li><a href="{{reposPath}}/{{branch.repoName | slugify}}/branches/{{branch.branchName | slugify}}">{{branch.branchName}}</a>{% if branch.branchName == branchInfo.branchName %} (current){% endif %}{% if description %} - {{ description }}{% endif %}</li>
  {% endif %}
{% endfor %}
</ul>
templates/file.njk:9
Before
8
9
10
11
12
13
    {% else %}
    <i class="bi bi-file-earmark"></i>
    {% endif %}
    <a href="/repos/{{fileInfo.repoName | slugify}}/branches/{{fileInfo.branchName | slugify}}/files/{{dir.fullPath | slugify}}.html">{{fileInfo.file | getRelativePath(dir.name)}}</a>
  </li>
{% endfor %}
</ul>
After
8
9
10
11
12
13
    {% else %}
    <i class="bi bi-file-earmark"></i>
    {% endif %}
    <a href="{{reposPath}}/{{fileInfo.repoName | slugify}}/branches/{{fileInfo.branchName | slugify}}/files/{{dir.fullPath | slugify}}.html">{{fileInfo.file | getRelativePath(dir.name)}}</a>
  </li>
{% endfor %}
</ul>
templates/file.njk:34
Before
33
34
35
36
37
38
    {% set annotations = fileInfo.repoName | getFileLastTouchInfo(fileInfo.branchName, fileInfo.file) %}
    <code style="white-space: pre;"><pre class="language-text">
{%- for annotation in annotations -%}
<a href="/repos/{{fileInfo.repoName | slugify}}/branches/{{fileInfo.branchName | slugify}}/patches/{{annotation.sha}}">{{ (annotation.sha | truncate(6, true, '')) }}</a> {{ annotation.author }}
{% endfor -%}
    </pre></code>
  </div>
After
33
34
35
36
37
38
    {% set annotations = fileInfo.repoName | getFileLastTouchInfo(fileInfo.branchName, fileInfo.file) %}
    <code style="white-space: pre;"><pre class="language-text">
{%- for annotation in annotations -%}
<a href="{{reposPath}}/{{fileInfo.repoName | slugify}}/branches/{{fileInfo.branchName | slugify}}/patches/{{annotation.sha}}">{{ (annotation.sha | truncate(6, true, '')) }}</a> {{ annotation.author }}
{% endfor -%}
    </pre></code>
  </div>
templates/files.njk:9
Before
8
9
10
11
12
13
        {% else %}
        <i class="bi bi-file-earmark"></i>
        {% endif %}
        <a href="/repos/{{branchInfo.repoName | slugify}}/branches/{{branchInfo.branchName | slugify}}/files/{{file.fullPath | slugify}}.html">{{file.name}}</a>
      </li>
    {% endfor %}
    </ul>
After
8
9
10
11
12
13
        {% else %}
        <i class="bi bi-file-earmark"></i>
        {% endif %}
        <a href="{{reposPath}}/{{branchInfo.repoName | slugify}}/branches/{{branchInfo.branchName | slugify}}/files/{{file.fullPath | slugify}}.html">{{file.name}}</a>
      </li>
    {% endfor %}
    </ul>
templates/index.njk:1
Before
0
1
2
3
<ul>
{% for repoName, options in repos %}
  <li><a href="/repos/{{repoName | slugify}}/branches/{{reposConfig.repos[repoName].defaultBranch}}">{{repoName}}</a></li>
{% endfor %}
</ul>
After
0
1
2
3
<ul>
{% for repoName, options in repos %}
  <li><a href="{{reposPath}}/{{repoName | slugify}}/branches/{{reposConfig.repos[repoName].defaultBranch}}">{{repoName}}</a></li>
{% endfor %}
</ul>
templates/repo.njk:10
Before
9
10
11
12
13
14
15
16
17
18
19
20
            <h2 class="fs-6 my-0">Recent patches in {{branch.branchName}}</h2>
          </div>
          <div class="col-auto">
            <a href="/repos/{{ branch.repoName | slugify }}/branches/{{ branch.branchName | slugify }}/patches.xml" class="initialism">RSS<i class="bi bi-rss-fill ms-2" style="color: orange;"></i></a>
          </div>
        </div>
        {% for patch in repos[branch.repoName].branches[branch.branchName].patches | batch(3) | first %}
        <div class="card mt-2 mb-4">
          <div class="card-body">
            <a href="/repos/{{branch.repoName | slugify}}/branches/{{branch.branchName | slugify}}/patches/{{patch.hash}}" class="text-primary d-inline-block card-title fs-5">{{patch.name}}</a>
            <p class="card-subtitle fs-6 mb-2 text-body-secondary">{{patch.date}}</p>
            <p class="card-subtitle fs-6 mb-2 text-body-secondary">{{patch.author}}</p>
            <p class="card-text">{{patch.description | truncate(150)}}</p>
After
9
10
11
12
13
14
15
16
17
18
19
20
            <h2 class="fs-6 my-0">Recent patches in {{branch.branchName}}</h2>
          </div>
          <div class="col-auto">
            <a href="{{reposPath}}/{{ branch.repoName | slugify }}/branches/{{ branch.branchName | slugify }}/patches.xml" class="initialism">RSS<i class="bi bi-rss-fill ms-2" style="color: orange;"></i></a>
          </div>
        </div>
        {% for patch in repos[branch.repoName].branches[branch.branchName].patches | batch(3) | first %}
        <div class="card mt-2 mb-4">
          <div class="card-body">
            <a href="{{reposPath}}/{{branch.repoName | slugify}}/branches/{{branch.branchName | slugify}}/patches/{{patch.hash}}" class="text-primary d-inline-block card-title fs-5">{{patch.name}}</a>
            <p class="card-subtitle fs-6 mb-2 text-body-secondary">{{patch.date}}</p>
            <p class="card-subtitle fs-6 mb-2 text-body-secondary">{{patch.author}}</p>
            <p class="card-text">{{patch.description | truncate(150)}}</p>