Repository navigation
Update to al-folio v1.1 (v0 → v1 gem architecture migration) - #50
Merged
Merged
Conversation
Since a lot of our users don't have a coding background and given recently development with AI agents, I decided to try to add support for specialized agents in our repository. They were created following [agents.md](https://agents.md/) "specifications" and are currently 2: - `customize-agent` - to help new users with access to GitHub Copilot customize their site - `docs-agent` - to help us keep the documentation always updated with the latest changes in our code I don't really know how useful they'll actually be, but I think most of our users might actually benefit from the `customize-agent`, so it is worth a shot. <img width="852" height="1043" alt="image" src="https://github.com/user-attachments/assets/e8390f1a-cec3-42a8-b01e-26d658ea78e8" /> Edit: also added a link to a [Code Wiki to our repository](https://codewiki.google/github.com/alshedivat/al-folio) and [DeepWiki](https://deepwiki.com/alshedivat/al-folio). This allows any user to chat online with AIs (Gemini and Devin) about our repository. --------- Signed-off-by: George Araújo <george.gcac@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Resolve alshedivat#3370 Resolve alshedivat#3380 Based on the [comment](alshedivat#3370 (comment)) of @MarkusThill, I created a bugfix that solved the issue on my website. Hope that fixes it in general; thus the PR :) However, I'm not an expert for scss .. so handle with care :)
…lshedivat#3391) Fixes alshedivat#3386 (the part about the wrong months; the other part (layouting of bibtex) is fixed in alshedivat#3387) ## Summary - Fixes incorrect month shown for bibliography entries that do not specify a `month` in BibTeX. - Ensures `month`/`year` do not persist between entries in `_layouts/bib.liquid`. ## Root Cause - In Liquid, captured variables persist across iterations if not reinitialized. - `entrymonth` and `entryyear` were only set when `entry.month`/`entry.year` existed, causing values from a previous entry to leak into the next one when those fields were missing. ## Changes - Reinitialize date-related variables per entry before conditional captures: ## Behavior - Before: Entries without a `month` could display the previous entry's month. - After: Entries without a `month` display only the `year`; entries with a `month` display the correct month and year. <img width="1956" height="918" alt="image" src="https://github.com/user-attachments/assets/7a9682e7-55ab-43b7-8f82-f638d14ce08e" />
Fix alshedivat#3164 Signed-off-by: George Araújo <george.gcac@gmail.com>
…hedivat#3417) Based on discussion alshedivat#3393. --------- Signed-off-by: George Araújo <george.gcac@gmail.com>
Currently, images generated by Imagemagick do not respect the orientation of the source image. By adding the auto-orient flag, the images are the correct orientation. Before <img width="920" height="562" alt="image" src="https://github.com/user-attachments/assets/73f59d7f-b6c5-468a-9023-0f0457a53a3c" /> After <img width="947" height="621" alt="image" src="https://github.com/user-attachments/assets/2f24de99-2e84-4052-8d0f-945acdad81e4" />
Closes alshedivat#3402 --------- Signed-off-by: George Araújo <george.gcac@gmail.com>
Signed-off-by: George Araújo <george.gcac@gmail.com>
This PR fixes a recurring typo in multiple Liquid templates where the Bootstrap class `cl-sm` is used instead of `col-sm`. Because of this typo, the `col-sm` styling was not being applied. All instances have been corrected.
…at#3422) ## Description This PR makes the URLs for external services used on the repository page configurable in `_config.yml`. This allows users to self-host these services for better reliability, privacy, and customization. ## Changes - Added `external_services` configuration section in `_config.yml` with: - `github_readme_stats_url` (default: `https://github-readme-stats.vercel.app`) - `github_profile_trophy_url` (default: `https://github-profile-trophy.vercel.app`) - Updated repository template files to use configurable URLs: - `_includes/repository/repo_user.liquid` - `_includes/repository/repo.liquid` - `_includes/repository/repo_trophies.liquid` - Added documentation in `CUSTOMIZE.md` explaining: - Why self-hosting is recommended (default services may have availability issues) - How to configure custom service URLs - Links to the service repositories for deployment instructions ## Resolves Resolves alshedivat#3388 - This makes it possible to configure self-hosted versions of these services, giving users full control over the external services used for displaying GitHub statistics and trophies. ## Testing - Verified that default configuration still works with original service URLs - Confirmed that URLs are properly interpolated in all template files - Documentation clearly explains the configuration options
Removed a link to sam-bieberich.github.io from the README.
Hi! I'd like to add my academic website to the User community section. **Website:** https://j1yoo.github.io/ This PR adds a single star link to the Academics row in the User community table. Thank you for creating and maintaining this beautiful theme! Co-authored-by: Jaewon Yoo <jwyoo4@gmail.com>
add `dimensions, eprint` and `pmid` to the filtered keywords
Adds a HAL button in the same spirit as the arXiv button. - add HAL button to `_layouts/bib.liquid` - add `hal` to the filtered keywords in `_config.yml` - add `hal` to the documentation in `CUSTOMIZE.md`
Improved section based on comments from alshedivat#2369. Signed-off-by: George Araújo <george.gcac@gmail.com>
Adding my personal website for the al-folio community :) Thanks for creating such a cool template!
…lshedivat#3435) Signed-off-by: George Araújo <george.gcac@gmail.com>
Signed-off-by: George Araújo <george.gcac@gmail.com>
Signed-off-by: George Araújo <george.gcac@gmail.com>
Signed-off-by: George Araújo <george.gcac@gmail.com>
Signed-off-by: George Araújo <george.gcac@gmail.com>
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.19.3 to 1.19.4. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/sparklemotion/nokogiri/releases">nokogiri's releases</a>.</em></p> <blockquote> <h2>v1.19.4 / 2026-06-18</h2> <h3>Security</h3> <ul> <li>[CRuby] (Low) Fixed a possible invalid memory read when <code>XML::Node#initialize_copy_with_args</code> is called with an argument that is not a <code>Node</code>. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-g9g8-vgvw-g3vf">GHSA-g9g8-vgvw-g3vf</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free when an <code>XML::XPathContext</code> is used after its source document has been garbage collected. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-p67v-3w7g-wjg7">GHSA-p67v-3w7g-wjg7</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free during XInclude processing via <code>Node#do_xinclude</code>. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wfpw-mmfh-qq69">GHSA-wfpw-mmfh-qq69</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free when <code>Document#root=</code> is assigned a non-element node. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wjv4-x9w8-wm3h">GHSA-wjv4-x9w8-wm3h</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free when setting an attribute value via <code>XML::Attr#value=</code> or <code>#content=</code>. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-phwj-rprq-35pp">GHSA-phwj-rprq-35pp</a> for more information.</li> <li>[CRuby] (Low) Fixed a null pointer dereference when methods are called on uninitialized wrapper objects (e.g. via <code>allocate</code>); these now raise instead of crashing the process. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-9cv2-cfxc-v4v2">GHSA-9cv2-cfxc-v4v2</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free when <code>Document#encoding=</code> raises an exception. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5v8h-3h3q-446p">GHSA-5v8h-3h3q-446p</a> for more information.</li> <li>[CRuby] (Medium) Fixed an out-of-bounds read in <code>XML::NodeSet#[]</code> (alias <code>#slice</code>) when given a large negative index. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5prr-v3j2-97mh">GHSA-5prr-v3j2-97mh</a> for more information.</li> <li>[JRuby] (Low) <code>XML::Schema</code> now enforces the <code>NONET</code> parse option, which Nokogiri enables by default. It was not enforced on JRuby, so a schema parsed with default options could still fetch external resources over the network, potentially enabling SSRF or XXE attacks and bypassing the mitigation for CVE-2020-26247. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-8678-w3jw-xfc2">GHSA-8678-w3jw-xfc2</a> for more information.</li> </ul> <!-- raw HTML omitted --> <pre><code>1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f nokogiri-1.19.4-aarch64-linux-gnu.gem 35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af nokogiri-1.19.4-aarch64-linux-musl.gem a301313e38bb065d68239e79734bcd6f56fb6efaacebde29e9abf2a4735340ca nokogiri-1.19.4-arm-linux-gnu.gem 588923c101bcfa78869734d247d25b598674323e7f22474fc468f6e5647311eb nokogiri-1.19.4-arm-linux-musl.gem a46db9853286e6597b36ebc6953817d15acf3a299583eb3f89fdc6f91dd63527 nokogiri-1.19.4-arm64-darwin.gem ce04b9e268c9626852231a48b49128ed52034f1ccb39484a6da3875491cd709e nokogiri-1.19.4-java.gem 051da97b8eccfdb5444fed40246a35e10d7298b9efe759b4cd25455ea04c587e nokogiri-1.19.4-x64-mingw-ucrt.gem 7fd17057d3e1f00e9954a74b3cd76595d3d4a5ef233b7ed9599047c204f70551 nokogiri-1.19.4-x86_64-darwin.gem 379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a nokogiri-1.19.4-x86_64-linux-gnu.gem 17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b nokogiri-1.19.4-x86_64-linux-musl.gem 50c951611c92bca05c51411aef45f1cbc50f2821c4802758c5c6d34696533ab5 nokogiri-1.19.4.gem </code></pre> <!-- raw HTML omitted --> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md">nokogiri's changelog</a>.</em></p> <blockquote> <h2>v1.19.4 / 2026-06-18</h2> <h3>Security</h3> <ul> <li>[CRuby] (Low) Fixed a possible invalid memory read when <code>XML::Node#initialize_copy_with_args</code> is called with an argument that is not a <code>Node</code>. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-g9g8-vgvw-g3vf">GHSA-g9g8-vgvw-g3vf</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free when an <code>XML::XPathContext</code> is used after its source document has been garbage collected. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-p67v-3w7g-wjg7">GHSA-p67v-3w7g-wjg7</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free during XInclude processing via <code>Node#do_xinclude</code>. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wfpw-mmfh-qq69">GHSA-wfpw-mmfh-qq69</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free when <code>Document#root=</code> is assigned a non-element node. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wjv4-x9w8-wm3h">GHSA-wjv4-x9w8-wm3h</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free when setting an attribute value via <code>XML::Attr#value=</code> or <code>#content=</code>. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-phwj-rprq-35pp">GHSA-phwj-rprq-35pp</a> for more information.</li> <li>[CRuby] (Low) Fixed a null pointer dereference when methods are called on uninitialized wrapper objects (e.g. via <code>allocate</code>); these now raise instead of crashing the process. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-9cv2-cfxc-v4v2">GHSA-9cv2-cfxc-v4v2</a> for more information.</li> <li>[CRuby] (Low) Fixed a possible use-after-free when <code>Document#encoding=</code> raises an exception. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5v8h-3h3q-446p">GHSA-5v8h-3h3q-446p</a> for more information.</li> <li>[CRuby] (Medium) Fixed an out-of-bounds read in <code>XML::NodeSet#[]</code> (alias <code>#slice</code>) when given a large negative index. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5prr-v3j2-97mh">GHSA-5prr-v3j2-97mh</a> for more information.</li> <li>[JRuby] (Low) <code>XML::Schema</code> now enforces the <code>NONET</code> parse option, which Nokogiri enables by default. It was not enforced on JRuby, so a schema parsed with default options could still fetch external resources over the network, potentially enabling SSRF or XXE attacks and bypassing the mitigation for CVE-2020-26247. See <a href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-8678-w3jw-xfc2">GHSA-8678-w3jw-xfc2</a> for more information.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/sparklemotion/nokogiri/commit/8cfb9daae9ee4a0837508eab43c40fbc8c4138c9"><code>8cfb9da</code></a> version bump to v1.19.4</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/a856d1e46bda04ef47a0bd2b9eefe86df1eb0bb2"><code>a856d1e</code></a> fix: JRuby NONET bypass in XML::Schema (v1.19.x) (<a href="https://redirect.github.com/sparklemotion/nokogiri/issues/3639">#3639</a>)</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/6a0aa1e7042ea58e10db713d4984c692a8db1a30"><code>6a0aa1e</code></a> fix(CRuby): use-after-free in Document#encoding= when setter raises (v1.19.x)...</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/f658a54ab2df58a3525967c339edce9649c197d4"><code>f658a54</code></a> fix: JRuby NONET bypass in XML::Schema</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/39d26fea52cda8ac15313561824fd0bc018818aa"><code>39d26fe</code></a> fix(CRuby): use-after-free in Document#encoding= when setter raises</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/04a09ddd67a4b573eb5c634655c2fb857e0436ad"><code>04a09dd</code></a> fix(CRuby): out-of-bounds read in NodeSet#[] with large negative index (v1.19...</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/7799fbd325f9f5e10fcccc77daaa903949a9d545"><code>7799fbd</code></a> fix: avoid NPE on uninitialized XML::Node structs (v1.19.x) (<a href="https://redirect.github.com/sparklemotion/nokogiri/issues/3645">#3645</a>)</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/ef19e1329c39f885e980b301f33fb233f3431d14"><code>ef19e13</code></a> fix(CRuby): avoid UAF in XML::Attr#value= (v1.19.x) (<a href="https://redirect.github.com/sparklemotion/nokogiri/issues/3644">#3644</a>)</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/5524fa97868ae26dfd74d700aba256b117262267"><code>5524fa9</code></a> fix: <code>Document#root=</code> rejects non-element nodes (v1.19.x) (<a href="https://redirect.github.com/sparklemotion/nokogiri/issues/3643">#3643</a>)</li> <li><a href="https://github.com/sparklemotion/nokogiri/commit/9891ad1092a265ae1cef220c377ebbabc9fde622"><code>9891ad1</code></a> fix(CRuby): use-after-free in XPathContext document lifetime (v1.19.x) (<a href="https://redirect.github.com/sparklemotion/nokogiri/issues/3641">#3641</a>)</li> <li>Additional commits viewable in <a href="https://github.com/sparklemotion/nokogiri/compare/v1.19.3...v1.19.4">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/alshedivat/al-folio/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) from 1.3.6 to 1.3.7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/ruby-concurrency/concurrent-ruby/releases">concurrent-ruby's releases</a>.</em></p> <blockquote> <h2>v1.3.7</h2> <!-- raw HTML omitted --> <p>There are 3 security fixes in this release, so updating is recommended. These security vulnerabilities are not very likely to be hit in practice and have a corresponding <code>Low</code> severity score.</p> <!-- raw HTML omitted --> <h2>What's Changed</h2> <ul> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-h8w8-99g7-qmvj">CVE-2026-54904</a> <code>AtomicReference#update</code> livelocks when the stored value is <code>Float::NAN</code>. Fix by <a href="https://github.com/joshuay03"><code>@joshuay03</code></a> and <a href="https://github.com/eregon"><code>@eregon</code></a></li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-wv3x-4vxv-whpp">CVE-2026-54905</a> <code>ReentrantReadWriteLock</code> read-count overflow grants a write lock without exclusivity. Fix by <a href="https://github.com/joshuay03"><code>@joshuay03</code></a></li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-6wx8-w4f5-wwcr">CVE-2026-54906</a> <code>ReadWriteLock</code> allows wrong-thread write release and stray read-release counter corruption. Fix by <a href="https://github.com/joshuay03"><code>@joshuay03</code></a></li> <li>concurrent-ruby-ext: fix build on Darwin 32-bit by <a href="https://github.com/barracuda156"><code>@barracuda156</code></a> in <a href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1064">ruby-concurrency/concurrent-ruby#1064</a></li> <li>Add SECURITY.md by <a href="https://github.com/eregon"><code>@eregon</code></a> in <a href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1104">ruby-concurrency/concurrent-ruby#1104</a></li> <li>Add Ruby 4.0 in CI by <a href="https://github.com/eregon"><code>@eregon</code></a> in <a href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1106">ruby-concurrency/concurrent-ruby#1106</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/barracuda156"><code>@barracuda156</code></a> made their first contribution in <a href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1064">ruby-concurrency/concurrent-ruby#1064</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.6...v1.3.7">https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.6...v1.3.7</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/ruby-concurrency/concurrent-ruby/blob/master/CHANGELOG.md">concurrent-ruby's changelog</a>.</em></p> <blockquote> <h2>Release v1.3.7 (16 June 2026)</h2> <p>concurrent-ruby:</p> <ul> <li>See the <a href="https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7">release notes on GitHub</a>.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/4c8fc28ab6bb9bd8258a4c0c2fa6d35ebe77b3cb"><code>4c8fc28</code></a> Release 1.3.7</li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/d91ca9426cb819d6cc63f1bd64bfe54644d0beca"><code>d91ca94</code></a> Fix AtomicReference#update livelock when stored value is Float::NAN on JRuby ...</li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/7e4d711bacf7a1dac3ef6bda44004387be2dc7e6"><code>7e4d711</code></a> Fix <code>ReentrantReadWriteLock</code> read hold overflow into write-lock bit</li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/6e37e0644b83b182971dc540d2e4bee38df61386"><code>6e37e06</code></a> Fix <code>AtomicReference#update</code> livelock when stored value is <code>Float::NAN</code></li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/2825cfa12cb708b76557803957f76862eb1151a2"><code>2825cfa</code></a> Cleanup spec</li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/3fd493283ca5f84f0ef4e84aabd43ad68df4626b"><code>3fd4932</code></a> Fix <code>ReadWriteLock</code> wrong-thread write release and stray read release</li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/1974b4772efc034ee8eaa562b4370343f4c5c54b"><code>1974b47</code></a> Add Ruby 4.0 in CI</li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/df8706d40c483d76bbb0b3a35a633c68fa9e17be"><code>df8706d</code></a> Add SECURITY.md (<a href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/issues/1104">#1104</a>)</li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/7a1b78941c081106c20a9ca0144ac73a48d254ab"><code>7a1b789</code></a> Bump actions/upload-pages-artifact from 4 to 5</li> <li><a href="https://github.com/ruby-concurrency/concurrent-ruby/commit/9b2dbf712896a638a73d2fa221206961c8d6484d"><code>9b2dbf7</code></a> Bump actions/deploy-pages from 4 to 5</li> <li>Additional commits viewable in <a href="https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.6...v1.3.7">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/alshedivat/al-folio/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [loofah](https://github.com/flavorjones/loofah) from 2.25.1 to 2.25.2. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/flavorjones/loofah/releases">loofah's releases</a>.</em></p> <blockquote> <h2>2.25.2 / 2026-07-15</h2> <h3>Security</h3> <ul> <li>Ensure <code>Loofah::HTML5::Scrub.allowed_uri?</code> recognizes numeric character references without semicolons (e.g. <code>javascript&#58alert(1)</code>), which browsers decode and execute, and rejects schemes split by them. See <a href="https://github.com/flavorjones/loofah/security/advisories/GHSA-5qhf-9phg-95m2">GHSA-5qhf-9phg-95m2</a>. <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> <li>Ensure <code>Loofah::HTML5::Scrub.allowed_uri?</code> recognizes the named character references <code>&Tab;</code> and <code>&NewLine;</code>, which <code>CGI.unescapeHTML</code> does not decode and browsers strip from URIs, and rejects schemes split by them (e.g. <code>java&Tab;script:alert(1)</code>). See <a href="https://github.com/flavorjones/loofah/security/advisories/GHSA-8whx-365g-h9vv">GHSA-8whx-365g-h9vv</a>. <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> <li>Ensure that both <code>href</code> and <code>xlink:href</code> attributes on SVG elements like <code>use</code> are restricted to local (same-document) references. Previously only <code>xlink:href</code> was restricted, allowing the SVG 2 <code>href</code> attribute to reference external documents. See <a href="https://github.com/flavorjones/loofah/security/advisories/GHSA-9wjq-cp2p-hrgf">GHSA-9wjq-cp2p-hrgf</a>. <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> </ul> <h3>Improved</h3> <ul> <li>Harden <code>data:</code> URI mediatype parsing in <code>Loofah::HTML5::Scrub.allowed_uri?</code>. The mediatype is now parsed following the <a href="https://fetch.spec.whatwg.org/#data-urls">WHATWG data: URL spec</a> and <a href="https://www.rfc-editor.org/rfc/rfc2397">RFC 2397</a> instead of simply being split on a colon. A <code>data:</code> URI with an omitted or malformed mediatype is now treated as <code>text/plain</code> and allowed, and one without the required comma is now rejected. <a href="https://redirect.github.com/flavorjones/loofah/issues/305">#305</a> <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> <li>Remove <code>feed</code> from the default set of allowed protocols. The <a href="https://en.wikipedia.org/wiki/Feed_URI_scheme">feed URI scheme</a> was never accepted as a standard protocol, and no major browser supports it. Removing it reduces the attack surface particularly for non-browser contexts. <a href="https://redirect.github.com/flavorjones/loofah/issues/304">#304</a> <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> <li>Remove a vestigial <code>&#x70</code> alternative from <code>Loofah::HTML5::SafeList::PROTOCOL_SEPARATOR</code>. This appears to be an ancient typo dating back to pre-extraction Rails circa 2007. <a href="https://redirect.github.com/flavorjones/loofah/issues/305">#305</a> <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/flavorjones/loofah/blob/main/CHANGELOG.md">loofah's changelog</a>.</em></p> <blockquote> <h2>2.25.2 / 2026-07-15</h2> <h3>Security</h3> <ul> <li>Ensure <code>Loofah::HTML5::Scrub.allowed_uri?</code> recognizes numeric character references without semicolons (e.g. <code>javascript&#58alert(1)</code>), which browsers decode and execute, and rejects schemes split by them. See <a href="https://github.com/flavorjones/loofah/security/advisories/GHSA-5qhf-9phg-95m2">GHSA-5qhf-9phg-95m2</a>. <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> <li>Ensure <code>Loofah::HTML5::Scrub.allowed_uri?</code> recognizes the named character references <code>&Tab;</code> and <code>&NewLine;</code>, which <code>CGI.unescapeHTML</code> does not decode and browsers strip from URIs, and rejects schemes split by them (e.g. <code>java&Tab;script:alert(1)</code>). See <a href="https://github.com/flavorjones/loofah/security/advisories/GHSA-8whx-365g-h9vv">GHSA-8whx-365g-h9vv</a>. <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> <li>Ensure that both <code>href</code> and <code>xlink:href</code> attributes on SVG elements like <code>use</code> are restricted to local (same-document) references. Previously only <code>xlink:href</code> was restricted, allowing the SVG 2 <code>href</code> attribute to reference external documents. See <a href="https://github.com/flavorjones/loofah/security/advisories/GHSA-9wjq-cp2p-hrgf">GHSA-9wjq-cp2p-hrgf</a>. <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> </ul> <h3>Improved</h3> <ul> <li>Harden <code>data:</code> URI mediatype parsing in <code>Loofah::HTML5::Scrub.allowed_uri?</code>. The mediatype is now parsed following the <a href="https://fetch.spec.whatwg.org/#data-urls">WHATWG data: URL spec</a> and <a href="https://www.rfc-editor.org/rfc/rfc2397">RFC 2397</a> instead of simply being split on a colon. A <code>data:</code> URI with an omitted or malformed mediatype is now treated as <code>text/plain</code> and allowed, and one without the required comma is now rejected. <a href="https://redirect.github.com/flavorjones/loofah/issues/305">#305</a> <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> <li>Remove <code>feed</code> from the default set of allowed protocols. The <a href="https://en.wikipedia.org/wiki/Feed_URI_scheme">feed URI scheme</a> was never accepted as a standard protocol, and no major browser supports it. Removing it reduces the attack surface particularly for non-browser contexts. <a href="https://redirect.github.com/flavorjones/loofah/issues/304">#304</a> <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> <li>Remove a vestigial <code>&#x70</code> alternative from <code>Loofah::HTML5::SafeList::PROTOCOL_SEPARATOR</code>. This appears to be an ancient typo dating back to pre-extraction Rails circa 2007. <a href="https://redirect.github.com/flavorjones/loofah/issues/305">#305</a> <a href="https://github.com/flavorjones"><code>@flavorjones</code></a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/flavorjones/loofah/commit/2706d7e858426ba856d9711b0e761b2fee7986c4"><code>2706d7e</code></a> version bump to v2.25.2</li> <li><a href="https://github.com/flavorjones/loofah/commit/1afde0cb8db147debed5d7200a7de947b09c1d9b"><code>1afde0c</code></a> Merge pull request <a href="https://redirect.github.com/flavorjones/loofah/issues/308">#308</a> from flavorjones/security-2252</li> <li><a href="https://github.com/flavorjones/loofah/commit/f1be9d893b5a8dd79240441a912d8897e74c38c0"><code>f1be9d8</code></a> Update <code>allowed_uri?</code> to decode semicolon-less numeric character references</li> <li><a href="https://github.com/flavorjones/loofah/commit/5e91af861e3cdab47b91dd0b81f3afdfd13a5e19"><code>5e91af8</code></a> Update <code>allowed_uri?</code> to handle named whitespace character references</li> <li><a href="https://github.com/flavorjones/loofah/commit/20867b9be689521887364b74822c41ef830523c9"><code>20867b9</code></a> Properly restrict SVG href attributes</li> <li><a href="https://github.com/flavorjones/loofah/commit/5f3bff46b610c1221c4bdb4e5b5b90e1178576cc"><code>5f3bff4</code></a> test: opt into JSON comment parsing for sanitizer testdata (<a href="https://redirect.github.com/flavorjones/loofah/issues/307">#307</a>)</li> <li><a href="https://github.com/flavorjones/loofah/commit/b07713d155ec7f5ae101464f09483a45efd481c2"><code>b07713d</code></a> test: do not run in verbose mode</li> <li><a href="https://github.com/flavorjones/loofah/commit/babe7a86e808e4f4df638140bf6719d18d97ffae"><code>babe7a8</code></a> doc: update CHANGELOG</li> <li><a href="https://github.com/flavorjones/loofah/commit/a8d8d96d916f08ac46f478cbe9e8ae056c98f2b3"><code>a8d8d96</code></a> Merge pull request <a href="https://redirect.github.com/flavorjones/loofah/issues/305">#305</a> from flavorjones/drop-protocol-typo</li> <li><a href="https://github.com/flavorjones/loofah/commit/b52f4b022db0a35f08d7f916fdf6034d312c7c8d"><code>b52f4b0</code></a> version bump to 2.25.2.beta1</li> <li>Additional commits viewable in <a href="https://github.com/flavorjones/loofah/compare/v2.25.1...v2.25.2">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/alshedivat/al-folio/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [json](https://github.com/ruby/json) from 2.19.7 to 2.19.9. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/ruby/json/releases">json's releases</a>.</em></p> <blockquote> <h2>v2.19.9</h2> <ul> <li>Fix buffer overflow that could lead to a crash when writing JSON directly into an IO with <code>JSON.generate(object, io)</code>. [CVE-2026-54696].</li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/ruby/json/compare/v2.19.8...v2.19.9">https://github.com/ruby/json/compare/v2.19.8...v2.19.9</a></p> <h2>v2.19.8</h2> <h2>What's Changed</h2> <ul> <li>Fix 1-byte buffer overread on EOS errors.</li> <li>Handle invalid types passed as <code>max_nesting</code> option.</li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/ruby/json/compare/v2.19.7...v2.19.8">https://github.com/ruby/json/compare/v2.19.7...v2.19.8</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/ruby/json/blob/master/CHANGES.md">json's changelog</a>.</em></p> <blockquote> <h3>2026-06-11 (2.19.9)</h3> <ul> <li>Fix buffer overflow that could lead to a crash when writing JSON directly into an IO with <code>JSON.generate(object, io)</code>. [CVE-2026-54696].</li> </ul> <h3>2026-06-03 (2.19.8)</h3> <ul> <li>Fix 1-byte buffer overread on EOS errors.</li> <li>Handle invalid types passed as <code>max_nesting</code> option.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/ruby/json/commit/2cff2678d5af54890a49da58345ac141b571f661"><code>2cff267</code></a> Release 2.19.9</li> <li><a href="https://github.com/ruby/json/commit/fd6a65bd08e5f3a429c03919ebfd8dd19158f095"><code>fd6a65b</code></a> generator.c: don't start with a stack buffer in IO case</li> <li><a href="https://github.com/ruby/json/commit/5233dd9b851a4924f793aec1a1658ed8b66a34c7"><code>5233dd9</code></a> Release 2.19.8</li> <li><a href="https://github.com/ruby/json/commit/3f44b26cf34f37e97065ff37f5eaecac69d5f28e"><code>3f44b26</code></a> Prevent buffer over-read when generating EOF error</li> <li><a href="https://github.com/ruby/json/commit/be8d068a8eb1124fdc2273e102dc986edf1140f7"><code>be8d068</code></a> Handle invalid types passed as <code>max_nesting</code> option</li> <li><a href="https://github.com/ruby/json/commit/59501c07de4257714d94a2d5bd44f08fad1a4a4c"><code>59501c0</code></a> Get rid of all_images gem</li> <li><a href="https://github.com/ruby/json/commit/c7a7b2be6f20e52439f4fdc5263e9b539fc6ad6c"><code>c7a7b2b</code></a> Add a security note in README</li> <li>See full diff in <a href="https://github.com/ruby/json/compare/v2.19.7...v2.19.9">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/alshedivat/al-folio/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Summary Added our lab from Worcester Polytechnic Institute (WPI CHIPS Design Studio) to the README.md file. ## Ownership Routing - [x] I confirmed this PR targets the correct repo based on `docs/BOUNDARIES.md`. - [X] This PR only changes starter-owned scope (`al-folio`) **or** I am porting a routed change and linked the owning repo issue/PR. Owning repo (if not starter): <!-- e.g., al-org-dev/al-folio-core --> Related issue/PR: <!-- link --> ## Plugin Ecosystem (if applicable) - [X] Not applicable - [ ] This PR proposes a plugin for **featured-only** listing. - [ ] This PR proposes a plugin for **bundled** starter inclusion. If plugin-related, provide: - Plugin repo URL: - Gem name: - Jekyll plugin id: - Compatibility (`al_folio_min`/`al_folio_max`): - Demo page/post path: - Maintainer contact: ## Starter Wiring Changes - [X] Not applicable - [ ] Updated `Gemfile` dependency wiring. - [ ] Updated `_config.yml` plugin activation/config. - [ ] Updated `_data/featured_plugins.yml` metadata. ## Validation - [ ] `npm ci` - [ ] `bundle exec jekyll build` - [ ] `npm run lint:prettier` - [ ] `npm run lint:style-contract` - [ ] Integration tests (`test/integration_*.sh`) as needed - [ ] Visual tests (`npm run test:visual`) as needed ## Notes README-only change, no wiring or runtime impact Compatibility, migration implications, and follow-ups:
## Summary Adds my personal site (https://chrhenning.com/) to the user community list in `README.md`, as invited by the "Feel free to add your own page(s) by sending a PR" note. Single-line addition; no config, runtime, or plugin changes. ## Ownership Routing - [x] I confirmed this PR targets the correct repo based on `docs/BOUNDARIES.md`. - [x] This PR only changes starter-owned scope (`al-folio`) **or** I am porting a routed change and linked the owning repo issue/PR. Owning repo (if not starter): N/A — starter-owned (`README.md`) Related issue/PR: N/A ## Plugin Ecosystem (if applicable) - [x] Not applicable - [ ] This PR proposes a plugin for **featured-only** listing. - [ ] This PR proposes a plugin for **bundled** starter inclusion. If plugin-related, provide: - Plugin repo URL: - Gem name: - Jekyll plugin id: - Compatibility (`al_folio_min`/`al_folio_max`): - Demo page/post path: - Maintainer contact: ## Starter Wiring Changes - [x] Not applicable - [ ] Updated `Gemfile` dependency wiring. - [ ] Updated `_config.yml` plugin activation/config. - [ ] Updated `_data/featured_plugins.yml` metadata. ## Validation - [ ] `npm ci` - [ ] `bundle exec jekyll build` - [ ] `npm run lint:prettier` - [ ] `npm run lint:style-contract` - [ ] Integration tests (`test/integration_*.sh`) as needed - [ ] Visual tests (`npm run test:visual`) as needed N/A — change is a single content line in `README.md` and touches no build, runtime, or styling paths. ## Notes No compatibility or migration implications. Documentation/content-only change.
## Summary Adds my al-folio-based academic homepage to the User community → Academics list. Website: https://dylantao.github.io/ ## Validation Not run; README-only documentation change. ## Ownership Routing - [x] I confirmed this PR targets the correct repo based on `docs/BOUNDARIES.md`. - [x] This PR only changes starter-owned scope (`al-folio`) **or** I am porting a routed change and linked the owning repo issue/PR. Owning repo (if not starter): <!-- e.g., al-org-dev/al-folio-core --> Related issue/PR: <!-- link --> ## Plugin Ecosystem (if applicable) - [x] Not applicable - [ ] This PR proposes a plugin for **featured-only** listing. - [ ] This PR proposes a plugin for **bundled** starter inclusion. If plugin-related, provide: - Plugin repo URL: - Gem name: - Jekyll plugin id: - Compatibility (`al_folio_min`/`al_folio_max`): - Demo page/post path: - Maintainer contact: ## Starter Wiring Changes - [x] Not applicable - [ ] Updated `Gemfile` dependency wiring. - [ ] Updated `_config.yml` plugin activation/config. - [ ] Updated `_data/featured_plugins.yml` metadata. ## Validation - [x] `npm ci` - [x] `bundle exec jekyll build` - [x] `npm run lint:prettier` - [x] `npm run lint:style-contract` - [x] Integration tests (`test/integration_*.sh`) as needed - [x] Visual tests (`npm run test:visual`) as needed ## Notes Compatibility, migration implications, and follow-ups: Co-authored-by: Maruan <alshedivat@users.noreply.github.com>
…the showcase out of the README (alshedivat#3681) A documentation overhaul in four commits. Every claim was verified against the repo, the workflows, or the installed gem before being changed — where a reported defect turned out to be inaccurate, it was skipped and is called out below. **Docs-only.** No runtime, no `test/style_contract.js`, no CI gating changes. --- ## 1. Factual errors in user-facing guides (`59eecedd`) | Fix | Detail | | --- | --- | | `QUICKSTART.md` | Told users to edit a `theme_color` key in `_config.yml`. No such key exists — in v1.x the palette is a Sass token owned by `al_folio_core` (`--global-theme-color` / `$purple-color`). Now points at `CUSTOMIZE.md#changing-theme-color`. | | `CUSTOMIZE.md` / `ANALYTICS.md` | Analytics schema corrected. `_config.yml` ships `analytics.{google,cronitor,pirsch,openpanel}` ID values; a provider activates when its **ID** is non-empty. | | `CUSTOMIZE.md` | `assets/pdfs/` → `assets/pdf/` (contradicted the same section 50 lines later). | | `CUSTOMIZE.md` | `bin/update_citations.py` → `bin/update_scholar_citations.py`, plus the `scholarly` dependency. | | `CUSTOMIZE.md` | Three default collections → four (`news`, `projects`, `books`, `teachings`), matching `collections:` in `_config.yml`. | | `INSTALL.md` | `purgecss` is not a devDependency, so `purgecss -c purgecss.config.js` is not runnable after `npm ci`. Documented installing it (CI installs it globally). | | `FAQ.md` | Two dead deployment anchors (`#deployment` on FAQ itself, and on the README) → `INSTALL.md#deployment`. | | `FAQ.md` | Workflow list regenerated: it documented 10 of the 19 workflows. Now complete and grouped by purpose. | | `CONTRIBUTING.md` | Corrected the claim that `CLAUDE.md` "simply contains `@AGENTS.md`". | ## 2. Agent-facing documentation (`7bb7e5e3`) The ownership rule was restated in ~9 places with none declaring itself authoritative, while the highest-value operational knowledge lived **only** in `CLAUDE.md` — which non-Claude agents never read. - **New `docs/ARCHITECTURE.md`** — single home for cross-repo architecture. Leads with *"failure modes that produce no error message"*: silent feature gating, the two-list `Gemfile`/`_config.yml` sync, and the `--baseurl /al-folio` requirement. Also holds the wrapper→tag→gem delegation table (moved out of `CLAUDE.md`, re-verified against each installed gem's `register_tag` calls). - **`AGENTS.md` rewritten** as the authoritative, tool-neutral entry point: a change-type routing table up top, and an explicit **stop sign** naming the paths that must not exist here. - **`.github/copilot-instructions.md`** reduced from a verbatim duplicate to a pointer, so the two cannot drift. - **`CLAUDE.md`** trimmed to Claude-specific content. Three defects fixed along the way: a stale `al_folio_core '= 1.0.9'` pin (Gemfile says `1.0.11` — now tells you to read the Gemfile rather than quoting a version), a hardcoded machine-specific path, and an incorrect description of `bin/setup-python-deps` (it only pip-installs jupyter/nbconvert and never reads `requirements.txt`). - **Integration test count corrected** from "five" to six everywhere — `test/integration_css_minify.sh` exists and is gated by `unit-tests.yml`. Added the missing `bundle install` to the validated command set. ## 3. Showcase moved out of the README (`ea6473c7`) The table was 199 lines and ~34% of the README, sitting above both the TOC and "Getting started". - Extracted verbatim to **`docs/SHOWCASE.md`**. All **190 links diffed before and after: none removed, reordered, or added.** No liveness audit ran in this environment, so nothing was pruned. - "Getting started" now sits directly under the badges, above the fold. - **Add-your-site-by-PR is retired.** README, `CONTRIBUTING.md`, the PR template, and the issue chooser now point to the *Showcase* category of GitHub Discussions, worded to read correctly once a dedicated category exists. - README opening reframed from "a Jekyll theme for academics" to the thin-starter/plugin identity. -⚠️ **`docs/SHOWCASE.md` added to the lychee excludes.** Those 190 community links were only unchecked because `README.md` is excluded; moving them to a checked path would have started failing `broken-links.yml`, which runs with `fail: true`. ## 4. Repo hygiene (`082faac9`) - **`update-tocs.yml`**: `paths:`/`files:` globs were `*.md` / `./*.md`, which never match `docs/*.md` — the root cause of every stale TOC under `docs/`. Now matches both; stale TOCs regenerated. - **`_config.yml` `exclude:`**: dropped four entries for files that now live in `docs/`; added `AGENTS.md` and `CLAUDE.md`, which were being **copied into `_site/` on every build**. - **`.prettierignore`**: pruned five entries for gem-owned paths, each verified absent. - **`_pages/plugins.md`**: `nav: false` was hiding the plugin catalog page the README promotes. --- ## 🔶 Maintainer decision needed: style contract vs. documented overrides `BOUNDARIES.md` and the FAQ tell **users** that local `_layouts`/`_includes`/`_sass` overrides are supported — but `test/style_contract.js` fails when those directories exist, and that check **ships to every site created from this template**. A user who adds a perfectly legal override sees the starter's own contract check fail in their fork. Per instructions I **documented the distinction but changed no code**: overrides are legal in a user's own site; the starter repo itself must not contain them. Whether to re-scope the check to the upstream repo only is flagged as an open decision in `ARCHITECTURE.md` and `BOUNDARIES.md`. ## Survey claims I found inaccurate - **"`enable_google_analytics: true` is a nonexistent key."** Not quite — `al_analytics` **does** read it, as an optional *off-switch*. The real problem is that the flag doesn't enable anything (the ID does), and setting it alone is a no-op. Documented accurately rather than as "nonexistent". - **"The repo has ~22 workflows."** It has **19** `.yml` workflows plus `schedule-posts.txt`, which is a disabled template, not a workflow. - **"Showcase PR instructions in README, CONTRIBUTING, PR template, and issue templates."** Only `README.md:34` actually had one. The other locations were updated proactively so the new policy is visible where people would look. ## Validation | Check | Result | | --- | --- | | `npm run lint:prettier` | ✅ pass (after `npx prettier . --write`) | | `npm run lint:style-contract` | ✅ pass | | `bundle exec jekyll build --baseurl /al-folio` | ✅ builds (see caveat) | | `bundle exec al-folio upgrade audit` | ✅ Blocking: 0 | | `bundle exec al-folio upgrade overrides audit` | ✅ no overrides | | `bash test/integration_upgrade_cli.sh` | ✅ pass | | Internal doc links/anchors | ✅ all resolve (scripted check across 16 files) | | Showcase links | ✅ 190/190 byte-identical | **Build caveat:** in this sandbox a full build fails inside `al_ext_posts` fetching `medium.com`/`blog.google` through the HTTPS proxy. **Confirmed pre-existing** — clean `origin/main` fails identically. With `external_sources: []` and ImageMagick disabled (binary absent here), the build completes in ~12s. `integration_plugin_toggles.sh` fails for the same network reason. CI has network and should be unaffected. Verified in the built output: `AGENTS.md`/`CLAUDE.md` no longer leak into `_site/`, and `/plugins/` builds and appears in the navbar. --- _Generated by [Claude Code](https://claude.ai/code/session_01J5uhLakE68MtxJhRxpYL7C)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
…alshedivat#3680) Closes alshedivat#3629 (the service-switch half of it). ## Problem The `/repositories/` page points its stat cards at the public **github-readme-stats** instance, which has been unreliable for a long time — cards come back blank. Reported in alshedivat#3539, alshedivat#3388 and alshedivat#2625. In alshedivat#3629 a maintainer of **[github-stats-extended](https://github.com/stats-organization/github-stats-extended)**, the actively maintained successor fork, proposed switching to it and offered to help. This is the starter-side half of that switch. ## The swap Per the fork's [compatibility notes](https://github.com/stats-organization/github-stats-extended/blob/master/docs/fork.md#compatibility-notes): > "you can change an existing stats card url from github-readme-stats to GitHub-Stats-Extended simply by changing the domain […] The card will look the same." Only the host changes — `/api/` and `/api/pin/` and every query parameter stay identical. ### Parameter mapping | Parameter | Old | New | Note | | --- | --- | --- | --- | | `username` | ✓ | ✓ | identical | | `repo` | ✓ | ✓ | identical | | `theme` | ✓ | ✓ | `repo_theme_light` / `repo_theme_dark` keep working; the fork ships the same [inbuilt theme names](https://github.com/stats-organization/github-stats-extended/blob/master/packages/core/src/themes/README.md) | | `locale` | ✓ | ✓ | same codes, now at [`docs/advanced_documentation.md#available-locales`](https://github.com/stats-organization/github-stats-extended/blob/master/docs/advanced_documentation.md#available-locales) | | `show_owner` | ✓ | ✓ | identical | | `description_lines_count` | ✓ | ✓ | identical | | `show_icons` | ✓ | ✓ | identical | | `anon` | not sent | n/a | al-folio has never sent this | **No parameter lost an equivalent.** The one documented rendering difference is improved line wrapping for long repository descriptions. Trophies are unchanged — `github-profile-trophy` is a separate project and out of scope. ## Ownership Per `docs/BOUNDARIES.md`, the includes that build these URLs are owned by `al_folio_core`, so the runtime change lives in **al-org-dev/al-folio-core#29**. This PR only touches starter wiring, docs and the visual tests. ## Changes - **`_config.yml`** — `external_services.github_readme_stats_url` → `https://github-stats-extended.vercel.app`; `repo_theme_*` comments repointed at the fork's theme list - **`docs/CUSTOMIZE.md`** — updated the external-services section, plus a new *Migrating from github-readme-stats* subsection, since existing sites have the old host pinned in their own `_config.yml` and need to change it by hand - **`README.md`** — feature description links to the new project - **`test/visual/helpers.js`**, **`test/visual/interactions.spec.js`** — stub and match **both** hosts. This matters: the visual-regression job diffs the candidate against a **v0.16.3 baseline** site that still points at github-readme-stats, so both sides must be intercepted or the parity comparison stops being deterministic. ## Testing - `npm run lint:prettier` — *All matched files use Prettier code style!* - `npm run lint:style-contract` — *Starter style contract check passed.* - `bundle exec jekyll build --baseurl /al-folio` — succeeds; the rendered `/repositories/` page emits the new host for all 9 example repos and both user cards, e.g. ``` https://github-stats-extended.vercel.app/api/pin/?username=alshedivat&repo=al-folio&theme=default&locale=en&show_owner=false&description_lines_count=2 https://github-stats-extended.vercel.app/api/pin/?username=jekyll&repo=jekyll&theme=dark&locale=en&show_owner=true&description_lines_count=2 https://github-stats-extended.vercel.app/api/?username=alshedivat&theme=default&locale=en&show_icons=true ``` with `show_owner` correctly `true`/`false` per repo, both light (`theme=default`) and dark (`theme=dark`) variants present, and trophy URLs untouched. (Three unrelated environment gaps had to be worked around for that build — no `jupyter-nbconvert`, no ImageMagick `convert`, and no outbound network for `al_ext_posts` — none of them related to this change.) ### Live service check — not possible here **I could not obtain live HTTP status codes.** This session's egress policy rejects both hosts at the proxy with `403` on `CONNECT`, before anything reaches the service: ``` github-stats-extended.vercel.app → curl: (56) CONNECT tunnel failed, response 403 github-readme-stats.vercel.app → curl: (56) CONNECT tunnel failed, response 403 ``` The **old** host is blocked identically, so this is a sandbox restriction and is not evidence about either service. **The 403s are the proxy's, not the service's — please open one of the URLs above before merging to confirm a card actually renders.** ## Dependency between the two PRs They are **independent** — neither blocks the other: - **This PR alone** already switches the starter site, because the includes read the URL from `_config.yml` and that works on the currently pinned `al_folio_core = 1.0.11`. - **al-org-dev/al-folio-core#29** changes the built-in *default* (for sites with no `external_services:` block, which previously got a broken relative URL) and repoints the in-template doc links. The `Gemfile` pin is deliberately left at `= 1.0.11` here, since 1.0.12 is not published yet. Once core#29 is released, bump it to `= 1.0.12` in a follow-up. ## Not addressed alshedivat#3629 also floats a second idea — an optional integration with [github-readme-stats-action](https://github.com/stats-organization/github-readme-stats-action), which commits generated SVGs from a workflow instead of hotlinking a live service. That is a separate feature and is not part of this PR; the issue is worth keeping open for it. --- _Generated by [Claude Code](https://claude.ai/code/session_01J5uhLakE68MtxJhRxpYL7C)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Replaces the dead `api.star-history.com` hotlink with a chart generated in-repo and refreshed automatically. ## Why **1. The service is down for everyone.** ``` $ curl "https://api.star-history.com/svg?repos=alshedivat/al-folio&type=Date" HTTP 500 — Repo alshedivat/al-folio: timeout of 10000ms exceeded ``` 5/5 attempts failed, and it reproduces on unrelated repos including `octocat/Hello-World` (2 stars) — so it's a service-wide backend failure, not our repo or its size. Their website root returns 200; specifically the SVG endpoint is broken. **2. It now asks visitors for a token that can push code.** star-history.com prompts for a GitHub token with **`Contents: read and write`**, claiming "the stargazers endpoint now requires contents write". That claim is false. Unauthenticated, no headers beyond `Accept`: ``` GET /repos/alshedivat/al-folio/stargazers -> 200 Accept: application/vnd.github.star+json -> 200, with starred_at timestamps GET /repos/alshedivat/al-folio -> stargazers_count = 15931 ``` `Contents: write` is the permission to **push code**. For a template this widely forked, that's not a dependency worth keeping even if the backend recovers. ## What this does - **`bin/generate_star_history.py`** — fetches the public stargazer timestamps and renders light + dark SVGs. No third-party services, no runtime dependencies, stdlib only. - Samples ~28 pages across the history instead of fetching all ~160, so a refresh is ~29 requests. - Anchors the final point at the **most recent star**, not "now", so repeated runs are byte-identical rather than producing a daily no-op commit. Verified: two consecutive runs → same md5. - **`.github/workflows/star-history.yml`** — regenerates on every push to `main`, weekly on a schedule, or on demand; commits only when the chart actually changed. - **`README.md`** — serves the committed assets via the existing `<picture>` + `prefers-color-scheme` pattern, so it can't 500 and can't prompt anyone for anything. Links to the stargazers page instead of star-history.com. ## Loop and blast-radius guards Two things I was careful about, since this workflow commits to the branch that triggers it: - **No self-retrigger.** `paths-ignore` on the generated SVGs means the bot's own commit — which touches nothing else — can't retrigger the workflow. (GitHub also declines to raise `push` events for commits made with `GITHUB_TOKEN`, so there are two independent guards.) Plus `concurrency` so two runs can't race to commit. - **Doesn't leak to template users.** Gated on `github.repository == 'alshedivat/al-folio'`, matching the existing convention in `broken-links.yml`. Without it, every site generated from this template would spend Actions minutes charting someone else's repo and committing files they never asked for. `GITHUB_TOKEN` is passed only to lift the API rate limit from 60/hr to 5000/hr — the data itself is public, and no personal or scoped token is involved. ## Result 15,931 stars, 29 sampled points, 2016-09-21 → 2026-07-28, styled with al-folio's own palette (`#b509ac`, and a lightened `#d94fd0` on dark for contrast against `#1c1c1d`). ## Verified - Rendered both SVGs in headless Chromium and reviewed them; fixed one real defect found that way — year ticks were derived from sampled data points, so the sparse early years never appeared and the axis jumped 2016 → 2020. Ticks are now calendar-based. - Both files parse as valid XML. - `npm run lint:style-contract` → passed. - `npm run lint:prettier` → the repo currently fails on three unrelated docs files; that is **pre-existing on `main`** and fixed separately in alshedivat#3683. This branch adds no new Prettier failures. ## Note `main` is protected, so if the Actions bot can't push directly the workflow will fail loudly rather than silently. If you'd rather it opened a PR per refresh instead of committing, say so and I'll switch it. --- _Generated by [Claude Code](https://claude.ai/code/session_01J5uhLakE68MtxJhRxpYL7C)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
…at#3685) The first real run of the star-history workflow (from the alshedivat#3684 merge) **failed**. Fixing it. ## Not what I expected I'd flagged branch protection as the likely failure mode. It wasn't — the chart generated fine (61s, exit 0) and the push was rejected as a plain non-fast-forward: ``` error: failed to push some refs to 'https://github.com/alshedivat/al-folio' hint: Updates were rejected because the remote contains work that you do not hint: have locally. ``` ## It's a race between two workflows that both commit to main ``` 03:28:52 star-history checks out ffee0cd 03:29:05 update-tocs pushes 5808e06 "Auto update markdown TOC" ← main moves 03:29:55 star-history finishes generating (61s of API sampling) 03:29:56 push rejected — main had moved 51 seconds earlier ``` `update-tocs.yml` triggers on the same push and finishes in ~15s; chart generation takes ~61s because it samples 29 pages of the stargazers API. Any merge touching markdown fires both, so **this would recur routinely** — it isn't a one-off. Worth noting the two guards I built in did work as designed: `paths-ignore` and the `GITHUB_TOKEN` rule prevent the workflow retriggering *itself*. Neither addresses a *sibling* workflow moving the ref, which is what happened. ## Fix Rebase onto the new tip and retry, up to three attempts: ```bash for attempt in 1 2 3; do if git push; then echo "Pushed on attempt ${attempt}." exit 0 fi echo "Push rejected (main moved); rebasing onto origin/main and retrying." git pull --rebase origin main done echo "::error::Could not push the refreshed chart after 3 attempts." exit 1 ``` Only the two generated SVGs are ever in flight, and nothing else writes them, so the rebase has no realistic conflict. A genuine failure after three attempts still fails the run loudly rather than silently skipping the refresh. ## Note on the current chart `main`'s committed SVGs are from the PR branch and are slightly stale (they were generated before the last few stars). The next successful run — this merge will trigger one — refreshes them. Nothing is broken in the meantime: the README renders the committed assets either way, which was the point of self-hosting. `prettier --check` clean; workflow YAML parses. --- _Generated by [Claude Code](https://claude.ai/code/session_01J5uhLakE68MtxJhRxpYL7C)_ Co-authored-by: Claude <noreply@anthropic.com>
…ader (alshedivat#3682) All eight gems that had unreleased work sitting on `main` are now published, so the starter can move off the pins it has been stuck on. They bump together here because one of them changes behaviour that `_config.yml` gates. | gem | from | to | | --- | --- | --- | | `al_folio_core` | 1.0.11 | **1.0.12** | | `al_folio_cv` | 1.0.0 | **1.0.1** | | `al_folio_distill` | 1.0.2 | **1.0.3** | | `al_analytics` | 1.0.0 | **1.0.1** | | `al_ext_posts` | 1.0.1 | **1.0.3** (1.0.2 was never published either) | | `al_img_tools` | 1.0.2 | **1.0.3** | | `al_search` | 1.0.2 | **1.0.3** | | `al_math` | 1.0.1 | **1.0.2** | ## The Distill loader, and why it is in this PR `_config.yml` shipped `al_folio.distill.allow_remote_loader: true`. Under 1.0.2 that flag only gated a log line, so it was inert. **1.0.3 turns it into a real switch**: `true` opts the site out of the vendored, hash-pinned Distill runtime and back onto `https://distill.pub/template.v2.js`, fetched with **no subresource integrity**. Bumping the pin without flipping the flag would ship that gem's entire hardening with its protection turned off — for this site, and for every site generated from this template. So the flag flips here, in the same change as the pin. This is not a stylistic preference: `al-folio upgrade audit` enforces the pairing. `check_distill_runtime` returns early while the flag is `true`, so splitting the two produces a **blocking** finding. That is also the correction to what I said earlier about alshedivat#3682 being mergeable on its own — it was not. Verified on the rendered post at `/blog/2021/distill/`: ```html <script src="/al-folio/assets/js/distillpub/template.v2.js" integrity="sha256-R5CDHO0C98TyAJss32l4ztqDUfAGDTtZ3Zs6qxMuJxo="> <script src="/al-folio/assets/js/distillpub/transforms.v2.js" integrity="sha256-XYVZD1ZSuRCrJBEBl0nIPvWlo/u5tzmtyStFV7a/PTk="> ``` Both local, both integrity-pinned, and no page in the built site references `distill.pub/template`. ## Also here - **`test/integration_distill.sh`** asserted the 1.0.2 transforms runtime hash. Rehashed against the *published* 1.0.3 gem rather than a computed guess: `70e3f488…` → `5d85590f…`. - **Dropped the dead `third_party_libraries.polyfill` entry.** `al_math` 1.0.2 stopped emitting the polyfill.io tag, and no gem reads that config key. Confirmed absent from the built site. - **`test/style_contract.js` hard-coded `al_math '= 1.0.1'`**, so this bump would have failed the style contract. Relaxed to assert an exact released pin of *any* version — the boundary the check actually exists to protect — keeping the separate check that rejects a git-branch pin. Otherwise every routine version bump trips a gate that is meant to guard the thin-starter contract, not the version number. Left alone deliberately: the `jquery` and `mdb` entries are also unread by any gem, but `al_folio_upgrade` carries a `legacy_jquery_usage` audit rule keyed on `third_party_libraries.jquery`, so removing those wants its own pass. ## Verification - `bundle install` — all eight resolve from RubyGems - all six `test/integration_*.sh` — pass - `npm run lint:style-contract`, `npm run lint:prettier` — pass - `bundle exec al-folio upgrade audit` — **Blocking: 0**, Non-blocking: 6 - built site smoke-checked: MathJax present, `swiper@12.1.2` (the CVE fix), repo cards on `github-stats-extended` with zero remaining `github-readme-stats` references, CV page renders all sections Co-authored-by: Claude <noreply@anthropic.com>
…lytics providers (alshedivat#3687) Both gems published after al-org-dev/al-folio-cv#7 and al-org-dev/al-analytics#14 merged. | gem | from | to | | --- | --- | --- | | `al_folio_cv` | 1.0.1 | **1.0.2** | | `al_analytics` | 1.0.1 | **1.0.2** | `al_folio_cv` 1.0.2 fixes CV entries with a bare `date` rendering no badge (alshedivat#3339), plus empty date badges in the awards and publications sections. ## Why the config changes ship with the pins A provider that exists in the gem but is absent from `_config.yml` and the docs is invisible — the second of the three silent failure modes in `AGENTS.md`. **Two** providers were in that state: - **Cloudflare Web Analytics** — new in `al_analytics` 1.0.2, fixes alshedivat#3351 - **Simple Analytics** — shipped in `al_analytics` **1.0.1**, pinned since the last release, and never documented. It has been reachable but undiscoverable this whole time. Both are now in the `analytics:` block and in `docs/ANALYTICS.md`. Cloudflare follows the existing convention exactly: set `analytics.cloudflare` to the beacon token and it turns on, with `enable_cloudflare_analytics` as an optional off-switch, same as every other provider. Simple Analytics **cannot** follow it, and that is worth being explicit about. It identifies a site by its domain, so there is no ID to put in the block and therefore nothing for the plugin to infer intent from — the flag alone controls it. A user who expects the usual "set the ID and it works" pattern gets silence. The asymmetry is called out both in `docs/ANALYTICS.md` and in the config comment. `enable_simple_analytics: false` is written out explicitly rather than left unset. Both mean off; the explicit form puts the option in the file where users actually go looking. ## Verified Built the site both ways rather than trusting the templates: **No token, flag false** — zero occurrences of `cloudflareinsights` or `simpleanalyticscdn` anywhere in the output. No beacon tag with an empty token. **Token set, flag true:** ```html <script defer src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon='{"token": "0123456789abcdef0123456789abcdef"}'> <script async src="https://scripts.simpleanalyticscdn.com/latest.js"> ``` The Cloudflare markup matches the snippet in Cloudflare's dashboard byte for byte. (Test token used only for the build; the committed config ships empty.) Also: all six `test/integration_*.sh` pass, `lint:prettier` and `lint:style-contract` pass, and `al-folio upgrade audit` reports **Blocking: 0**. ## Deliberately not included The `apple_touch_icon` documentation and asset, which depend on al-org-dev/al-folio-core#36 and `al_folio_core` 1.0.13. Documenting that key now would describe something that does nothing — the same failure this PR is fixing for the two analytics providers. It follows once core#36 merges and the gem publishes. --- _Generated by [Claude Code](https://claude.ai/code/session_01J5uhLakE68MtxJhRxpYL7C)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
…edivat#3688) Merging this makes cutting v1.1 a one-click dispatch instead of a manual step. ## Why Creating a release means creating a tag, and pushing to `refs/tags/*` fails with **HTTP 403** from my environment — I retried with three different refspec forms (`refs/tags/v1.1`, a lightweight local tag, and `origin/main:refs/tags/v1.1`); all rejected, and the ref never lands. Branch pushes are fine. So releases have been a step only you could perform. This moves tag creation onto the runner, where `GITHUB_TOKEN` already has `contents: write` and `gh release create` creates the tag as part of publishing. ## How notes work Read from `docs/releases/<tag>.md`, **not** a dispatch input. That means: - they get reviewed in a PR before they can ever be published - the repo keeps a record of what each release claimed - a release can't be cut with hastily typed or missing notes ## Guards Publishing is hard to walk back once people have fetched the tag, so: - the tag must look like a version (`v1.1` or `v1.1.0`) - **refuses if the tag already exists**, rather than moving it - refuses if the notes file is missing or empty - `draft: true` by default, so the normal path is to read it before it goes public - `workflow_dispatch` only — nothing fires on a push - gated on `github.repository == 'alshedivat/al-folio'`, matching `star-history.yml`, so sites generated from this template don't carry a workflow that cuts releases of *your* project ## Also here **`docs/releases/v1.1.md`** — the v1.1 notes. Headline is that this is a security release: the Swiper prototype-pollution CVE (CVSS 9.4), the polyfill.io supply-chain tag, and the Distill runtime that was silently discarding its own hash-pinned copy to load from `distill.pub` with no SRI. Plus blank repo cards, off-screen mobile submenus, relative `og:image`, the CV ordering fix, empty external-post titles, the docs pass, and the release automation. Gem versions were checked against the actual `Gemfile` at the `v1.0` tag rather than the v1.0 release prose. **`broken-links.yml` excludes `docs/releases`** — release notes link to the compare range for the tag they're about to create, which can't resolve until the release exists. I confirmed `compare/v1.0...v1.1` returns 404 today, so without this the link checker fails on every release PR. (`update-tocs.yml` matches `docs/*.md`, not `docs/**/*.md`, so notes files don't get a TOC — verified.) ## After merge I dispatch `Create release` with `tag: v1.1` and `draft: false`, and v1.1 is out. No tag push needed from either of us. ## One thing to decide **alshedivat#3687 is green and unmerged.** It pins `al_folio_cv 1.0.2` (the CV bare-`date` fix, alshedivat#3339) and `al_analytics 1.0.2` (Cloudflare Web Analytics, alshedivat#3351). As written, these notes describe `main` *without* it, so v1.1 would ship without those two. If you'd rather they were in v1.1, merge alshedivat#3687 as well and I'll update the notes before dispatching. Either is fine — just don't want to release notes that understate what shipped. --- _Generated by [Claude Code](https://claude.ai/code/session_01J5uhLakE68MtxJhRxpYL7C)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
The fork was last synced against a pre-v1.0 al-folio, where layouts, includes
and styles lived in this repo. al-folio v1.x moves all of that into the
al_folio_core / al_* gem family, so this merge deletes the local copies and
keeps only files we intentionally customise as overrides.
Overrides kept (gem-owned paths):
_includes/figure.liquid skip webp srcset for GIFs; pass `style` through
_includes/footer.liquid Umami analytics (al_analytics has no Umami provider)
_includes/header.liquid navbar wordmark via site.logo.*
_includes/repository/repo.liquid pin show_owner=false across our three orgs
_layouts/about.liquid hide title/subtitle, capitalised section headings
_layouts/bib.liquid publications/ preview dir, DOI button suppressed
_layouts/page.liquid team profile portraits + GitHub README embed
assets/css/main.scss adds `@use "custom"`
Overrides dropped, now covered upstream or by config:
_includes/repository/repo_user.liquid stats host is now external_services.*
_includes/social.liquid replaced by a jekyll-socials custom entry
(linkedin_company) in _data/socials.yml
_sass/_base.scss pre-v1 monolith; the two site rules moved to
_sass/_themes.scss _sass/_custom.scss (theme-aware-logo was dead CSS,
and v1 handles the tri-state theme toggle natively)
Also: _pages/code.md passes repository=repo.id so the gem include works with our
object-form _data/repositories.yml; upstream demo content this fork had already
removed stays removed; feedjira/httparty dropped (unused - the profile-readme
plugin uses stdlib open-uri).
Picks up the v1.1 security fixes: Swiper 12.1.2 (CVE-2026-27212, CVSS 9.4),
polyfill.io removed from MathJax, and Distill's remote loader disabled
(allow_remote_loader: false).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three follow-ups from verifying the v1.1 build: - `_includes/header.liquid`: the logo `alt` chained `site.title | default: ... | append: site.middle_name | append: site.last_name`, so with a non-blank `site.title` it appended the name parts anyway and rendered "Sustainable Urban Systems Lab Urban Systems Lab". Now it picks one branch or the other. This bug predates the migration; fixing it here since the file was being rewritten. - `_config.yml`: exclude `test/`. v1.1 ships a Playwright/integration harness in the starter but does not exclude it, so the specs and shell scripts were being published to the live site. - `.al-folio-overrides.yml`: records the 8 intentional overrides with the upstream checksums they were reviewed against, so `al-folio upgrade overrides audit` can flag drift on future gem bumps. Verified in Docker (ruby 3.3.12): jekyll build clean, `al-folio upgrade audit` reports 0 blocking findings, and the resolved gems include al_img_tools 1.0.3, al_math 1.0.2 and al_folio_distill 1.0.3 — the three carrying the v1.1 security fixes. Swiper resolves to 12.1.2 with matching SRI hashes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
✅ Deploy Preview for sustainableurbansystems ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
kastnerp
marked this pull request as ready for review
July 30, 2026 06:56
kastnerp
added a commit
that referenced
this pull request
Jul 30, 2026
* Update dogan.md
* Team Updates
* Team Updates
* Update thach.md
* Update gomez.md
* GitHub profile autoinclude
Update page.liquid
.
* GitHub autoinclude
* Update yang.md
* fixed run files
* Update gt-arch-7014.md
* Update gt-arch-7014.md
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* feat: add Code tab and GitHub repo cards
* feat: add Code tab and GitHub repo cards
* Update li.md
* Update join.md
* Update Google Scholar citations
* Add news posts for Sina defense and CHHS talk
* Update Google Scholar citations
* Update Google Scholar citations
* Update remote_include URL in thach.md (#37)
* Fix repository page layout
* Improve repository card title overflow
* Restore repository card design
* Update almaian.md
* Update _base.scss
* Update almaian.md
* .
* Update repo.liquid
* Update karadag.md
* Add Shen visit news post
* Normalize image asset paths
* Prevent team avatar footer overlap
* Add Cypress thesis defense news post
* Add Jimmy team profile (#39)
* Jimmy Miao Zhang
* Jimmy Miao Zhang Profile Photo
* Revise Jimmy's profile details and image
Updated profile information for Jimmy Miao.
* Update and rename jimmy.md to miao.md
* Update miao.md
* Update Google Scholar citations
* Update Google Scholar citations
* Create announcement_43.md
* Add MT projects for Benjamin Shih and Joseph Aerathu
* Fix video rendering on Joseph Aerathu project page
* Add project links to team pages
* Add CP-GNI2024-Symposium-Enriching-geospatial-building-datasets project (#41)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update title to 'Jimmy Miao Zhang' (#40)
* Update Google Scholar citations
* Update papers.bib with missing code links (#43)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update Google Scholar citations
* Update about.liquid
* Add Karadag 2026 publication (#44)
* Add Karadag 2026 urban wind simulation publication
- Added the BibTeX entry for `KARADAG2026107614` to `_bibliography/papers.bib`.
- Associated the publication with the `cfdgan-compressed.gif` preview image.
- Added the `bibtex_show` field to the new entry.
- Added `2026` to `years_papers` in `_pages/research/children/publications.md` so the newly added publication is rendered on the website.
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Add specific karadag image to publication
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Change publication preview image to abstract screenshot
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update karadag_abstract.png
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Fix formatting of year fields in _bibliography/papers.bib (#46)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update Google Scholar citations
* Dynamically pull Sina Rahimi's PhD README in project page (#47)
Replaced the hardcoded source link in `_projects/PhD-SinaRahimi.md` with a Liquid remote_include block that fetches and displays the actual GitHub README.md content.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update Google Scholar citations
* Update Google Scholar citations
* fix: switch repo cards to working github-readme-stats deployment (#49)
Public instance github-readme-stats.vercel.app returns 503
DEPLOYMENT_PAUSED, breaking all repo card images on /code/.
Point at the author's working deployment alias instead.
Co-authored-by: Patrick Kastner <1919773+kastnerp@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Add new display categories in theses.md (#48)
* Add new display categories in theses.md
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Add new display categories in theses.md
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Integrate new projects and update bibtex
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Integrate new projects and update bibtex
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update bibtex fields and add macadThesis24
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Remove macadThesis24
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update Google Scholar citations
* Add Best Poster Award details to Maryam SimBuild 2026 post
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Add SimBuild 2026 award photo and certificate to Maryam post
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Update Google Scholar citations
* Update socials.yml
* Update Google Scholar citations
* Update to al-folio v1.1 (v0 → v1 gem architecture migration) (#50)
* Added support for helping agents (#3379)
Since a lot of our users don't have a coding background and given
recently development with AI agents, I decided to try to add support for
specialized agents in our repository. They were created following
[agents.md](https://agents.md/) "specifications" and are currently 2:
- `customize-agent` - to help new users with access to GitHub Copilot
customize their site
- `docs-agent` - to help us keep the documentation always updated with
the latest changes in our code
I don't really know how useful they'll actually be, but I think most of
our users might actually benefit from the `customize-agent`, so it is
worth a shot.
<img width="852" height="1043" alt="image"
src="https://github.com/user-attachments/assets/e8390f1a-cec3-42a8-b01e-26d658ea78e8"
/>
Edit: also added a link to a [Code Wiki to our
repository](https://codewiki.google/github.com/alshedivat/al-folio) and
[DeepWiki](https://deepwiki.com/alshedivat/al-folio). This allows any
user to chat online with AIs (Gemini and Devin) about our repository.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Auto update markdown TOC
* Fix bib / code layout bug (#3387)
Resolve #3370
Resolve #3380
Based on the
[comment](https://github.com/alshedivat/al-folio/issues/3370#issuecomment-3565962058)
of @MarkusThill, I created a bugfix that solved the issue on my website.
Hope that fixes it in general; thus the PR :) However, I'm not an expert
for scss .. so handle with care :)
* Fix: bibliography month persists to subsequent entries without month (#3391)
Fixes #3386 (the part about the wrong months; the other part (layouting
of bibtex) is fixed in #3387)
## Summary
- Fixes incorrect month shown for bibliography entries that do not
specify a `month` in BibTeX.
- Ensures `month`/`year` do not persist between entries in
`_layouts/bib.liquid`.
## Root Cause
- In Liquid, captured variables persist across iterations if not
reinitialized.
- `entrymonth` and `entryyear` were only set when
`entry.month`/`entry.year` existed, causing values from a previous entry
to leak into the next one when those fields were missing.
## Changes
- Reinitialize date-related variables per entry before conditional
captures:
## Behavior
- Before: Entries without a `month` could display the previous entry's
month.
- After: Entries without a `month` display only the `year`; entries with
a `month` display the correct month and year.
<img width="1956" height="918" alt="image"
src="https://github.com/user-attachments/assets/7a9682e7-55ab-43b7-8f82-f638d14ce08e"
/>
* Fixed 1 px first load issue (#3416)
Fix #3164
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Added support for default categories and tags for external posts (#3417)
Based on discussion #3393.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Add link to personal GitHub page on academics section in README (#3400)
* Add auto-orient flag to Imagemagick config (#3409)
Currently, images generated by Imagemagick do not respect the
orientation of the source image. By adding the auto-orient flag, the
images are the correct orientation.
Before
<img width="920" height="562" alt="image"
src="https://github.com/user-attachments/assets/73f59d7f-b6c5-468a-9023-0f0457a53a3c"
/>
After
<img width="947" height="621" alt="image"
src="https://github.com/user-attachments/assets/2f24de99-2e84-4052-8d0f-945acdad81e4"
/>
* Update deps (#3418)
Closes #3402
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Added new line to README badges
* Changed maintainers urls to https
* Updated prettier (#3420)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Fix typo in Bootstrap small column class usage (#3421)
This PR fixes a recurring typo in multiple Liquid templates where the
Bootstrap class `cl-sm` is used instead of `col-sm`.
Because of this typo, the `col-sm` styling was not being applied. All
instances have been corrected.
* Update Google Scholar citations
* Make external service URLs configurable for repository page (#3422)
## Description
This PR makes the URLs for external services used on the repository page
configurable in `_config.yml`. This allows users to self-host these
services for better reliability, privacy, and customization.
## Changes
- Added `external_services` configuration section in `_config.yml` with:
- `github_readme_stats_url` (default:
`https://github-readme-stats.vercel.app`)
- `github_profile_trophy_url` (default:
`https://github-profile-trophy.vercel.app`)
- Updated repository template files to use configurable URLs:
- `_includes/repository/repo_user.liquid`
- `_includes/repository/repo.liquid`
- `_includes/repository/repo_trophies.liquid`
- Added documentation in `CUSTOMIZE.md` explaining:
- Why self-hosting is recommended (default services may have
availability issues)
- How to configure custom service URLs
- Links to the service repositories for deployment instructions
## Resolves
Resolves #3388 - This makes it possible to configure self-hosted
versions of these services, giving users full control over the external
services used for displaying GitHub statistics and trophies.
## Testing
- Verified that default configuration still works with original service
URLs
- Confirmed that URLs are properly interpolated in all template files
- Documentation clearly explains the configuration options
* Auto update markdown TOC
* Remove link to sam-bieberich.github.io (#3425)
Removed a link to sam-bieberich.github.io from the README.
* Add link to personal GitHub page on academics section in README (#3424)
* Add j1yoo.github.io to User community (#3427)
Hi! I'd like to add my academic website to the User community section.
**Website:** https://j1yoo.github.io/
This PR adds a single star link to the Academics row in the User
community table.
Thank you for creating and maintaining this beautiful theme!
Co-authored-by: Jaewon Yoo <jwyoo4@gmail.com>
* add filtered BibTeX keywords (#3403)
add `dimensions, eprint` and `pmid` to the filtered keywords
* Add HAL button (#3404)
Adds a HAL button in the same spirit as the arXiv button.
- add HAL button to `_layouts/bib.liquid`
- add `hal` to the filtered keywords in `_config.yml`
- add `hal` to the documentation in `CUSTOMIZE.md`
* Improved collections section in CUSTOMIZE guide (#3431)
Improved section based on comments from #2369.
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Add zhoji.github.io to User community in README.md (#3433)
Adding my personal website for the al-folio community :) Thanks for
creating such a cool template!
* Changed code to use plugin to handle 3rd party libraries downloads (#3435)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Changed to use cache bust plugin (#3436)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Update deps (#3437)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Changed to use jekyll-socials plugin (#3439)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Updated deps and deploy version (#3440)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Fixed dates in book-shelf (#3446)
Fixes #3443.
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Updated deps to fix issue with jekyll-socials (#3447)
Fixes #3445
Signed-off-by: George Araújo <george.gcac@gmail.com>
* ⚡ Optimize Google Scholar Citations Regex Definition (#3449)
💡 **What:** Moved the regex definition `/Cited by (\d+[,\d]*)/` from the
method scope to a class-level constant `CITED_BY_REGEX`.
🎯 **Why:** To improve code cleanliness and avoid potential re-definition
of the regex object in every method call (or loop), adhering to best
practices.
📊 **Measured Improvement:**
* **Baseline:** The regex was defined as a literal inside the `render`
method, which is called for each tag usage.
* **Optimization:** The regex is now defined once as a constant.
* **Note:** Performance benchmarks were not possible in the current
environment due to missing Ruby runtime. However, this is a standard
Ruby optimization that improves maintainability and theoretically avoids
object allocation overhead in older Ruby versions or complex scenarios.
Modern Ruby optimizes literals well, but the constant approach is
cleaner and DRYer.
---
*PR created automatically by Jules for task
[10688912524063334698](https://jules.google.com/task/10688912524063334698)
started by @alshedivat*
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Refactor: Use Liquid filter to find home page title (#3448)
Refactored the script in _scripts/search.liquid.js to use a more
efficient Liquid 'where' filter to find the home page title. This
replaces an inefficient for loop that iterated through all site pages.
---
*PR created automatically by Jules for task
[5748098109809984605](https://jules.google.com/task/5748098109809984605)
started by @alshedivat*
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Revert "Refactor: Use Liquid filter to find home page title" (#3451)
Reverts alshedivat/al-folio#3448
* Updated jekyll-archives-v2 (#3460)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Add course schedule feature to teaching page (#2258) (#3147)
Implements the course schedule feature requested in issue
#[2258](https://github.com/alshedivat/al-folio/issues/2258).
This PR adds a new course schedule feature to the al-folio theme,
allowing academics to easily create and display structured course
information.
**Changes:**
- Added a `courses` collection to organize and display academic courses
- Created course layout and display templates with responsive design
- Implemented organization by year and term with automatic sorting
- Added support for weekly schedule with topics and course materials
- Simplified documentation with a README for course creation
This feature makes it easier for academics to showcase their teaching
materials with a consistent, organized display of course schedules,
helping users create professional teaching pages without custom
implementation.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Add calendar iframe and togglAdd calendar iframe and toggle buttone button (#3144)
### Description
This PR adds a Google Calendar integration feature as described in issue
#872. Users can embed their own calendar using an iframe configured via
`_config.yml`, and the calendar is toggleable through a responsive
button. This component is styled to visually blend into the theme and
supports responsive display across desktop and mobile.
### Changes
- Added `calendar.liquid` in `_includes`
- Modified `about.md` to include the toggleable calendar block
- Introduced `calendar` config section in `_config.yml`
- Appended calendar-related styles in `_sass/_base.scss`
### Configuration
To enable this feature, add the following to `_config.yml`:
```yaml
calendar:
enabled: true
calendar_id: your_calendar_id@group.calendar.google.com
timezone: UTC
style: "border:0; width:100%; height:600px;"
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: dodo <349507644@qq.com>
Co-authored-by: George <31376482+george-gca@users.noreply.github.com>
Co-authored-by: George Araújo <george.gcac@gmail.com>
* Update Google Scholar citations
* Updated jekyll-socials to latest version (#3464)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Add smsnoBin77 link to README (#3473)
Add a new link to the README for smsnoBin77.
* Unify jsonresume and RenderCV CVs solutions (#3462)
Fixes #2787 as an alternative to #2969. It was getting too cumbersome to
have 2 different data sources for CV and also a lot of different layout
files, so I decided to unify them all.
Main changes:
- synchronized the information inside RenderCV (`_data/cv.yml`) and
JSONResume (`assets/json/resume.json`)
- unified layout files for CV information
- added the option to set the "data source" in the CV page
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* chore: render the latest CV
* Rendercv missing commits (#3475)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* chore: render the latest CV
* Update Google Scholar citations
* Update SASS syntax in base (non-font) files (#3281)
Partially fixes issue #3256 by updating SASS syntax in main SCSS files.
To fully address the issue, FontAwesome should be updated to `v7.x` and
Tabler to `v3.30` or higher (see Tabler fix
[here](https://github.com/tabler/tabler-icons/pull/1256)), where the
SCSS has been fixed.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Improve readme, add site-wide CSP (#3485)
This pull request significantly expands and clarifies the documentation
for the al-folio Jekyll theme, focusing on improved file structure
explanations, enhanced quick reference guides, and the addition of a
comprehensive analytics setup guide. The changes make it easier for
users and contributors to understand the project organization, available
features, and configuration options, especially regarding CV formats,
teaching pages, and analytics integration.
**Key documentation and structure improvements:**
*Expanded file and collection structure:*
- The file structure documentation in
`.github/agents/customize.agent.md` and `.github/agents/docs.agent.md`
now details all major directories, including new and existing
collections such as `_books/`, `_teachings/`, `_scripts/`, `_plugins/`,
and expanded `assets/` subdirectories. It also covers new configuration
and utility files, making it easier for users to locate and understand
the purpose of each file or folder.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L24-R66)
[[2]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L17-R58)
*Documentation and quick reference enhancements:*
- The quick reference table in `.github/agents/customize.agent.md` has
been updated to include new actions like adding teaching pages, setting
up analytics, improving SEO, and ensuring accessibility, with more
precise documentation links.
- The documentation map now lists all major guides (e.g.,
`QUICKSTART.md`, `INSTALL.md`, `TROUBLESHOOTING.md`, `ACCESSIBILITY.md`,
`ANALYTICS.md`, `SEO.md`), providing a clearer overview of available
resources.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L58-R110)
[[2]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L17-R58)
**Feature and configuration documentation updates:**
*CV/resume format guidance:*
- The CV documentation now clarifies that users can maintain both
RenderCV and JSONResume formats simultaneously, with clear instructions
on switching between them and deleting unused files if desired.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L139-R185)
[[2]](diffhunk://#diff-52f2a9488bfe4177d1f1d01120859dad0b3e2d087283ded68f72d47b4f183391L291-R291)
*Teaching pages and new collections:*
- Adds documentation for the new `_teachings/` collection, including
required frontmatter and support for course materials, as well as
updates to enable/disable teaching and books pages via `_config.yml`.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L180-R252)
[[2]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L24-R66)
*Analytics integration:*
- Introduces a new `ANALYTICS.md` guide with detailed setup instructions
for Google Analytics, privacy-friendly alternatives (Plausible, Pirsch,
Openpanel, GoAccess), GDPR considerations, and a comparison table to
help users choose the right analytics provider.
- The configuration documentation now references analytics setup and
related configuration options.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L180-R252)
[[2]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L479-R550)
These updates collectively make the documentation more comprehensive,
actionable, and user-friendly for both new and advanced users.
**References:**
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L24-R66)
[[2]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L58-R110)
[[3]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L139-R185)
[[4]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L180-R252)
[[5]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L479-R550)
[[6]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L17-R58)
[[7]](diffhunk://#diff-0967e840631a541bb95e057e1c6d4884274cf56d5a217d7fee2eb7223b6b4c0dR1-R268)
[[8]](diffhunk://#diff-52f2a9488bfe4177d1f1d01120859dad0b3e2d087283ded68f72d47b4f183391L291-R291)
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Auto update markdown TOC
* Added copilot instructions, AGENTS.md, improved README files (#3486)
This pull request introduces several documentation improvements and adds
comprehensive Copilot and agent instruction files to the al-folio
repository. The most significant changes are the addition of
repository-wide and path-specific Copilot instructions, updates to agent
documentation to reference these instructions, and improvements to the
documentation structure and clarity regarding file purposes and
workflows.
**Copilot and Agent Instruction Enhancements:**
- Added a new `.github/copilot-instructions.md` file providing detailed,
repository-wide setup, build, CI/CD, troubleshooting, and file format
guidance for Copilot coding agents.
- Introduced `.github/instructions/bibtex-bibliography.instructions.md`
with specific instructions for editing and validating BibTeX files,
including custom keywords, formatting rules, and integration with
Jekyll-Scholar.
- Updated agent documentation files (`customize.agent.md`,
`docs.agent.md`) to reference the new Copilot instruction files and
explain their purpose and usage for both repository-wide and
path-specific scenarios.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L57-R65)
[[2]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L107-R122)
[[3]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L49-R51)
[[4]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L106-R137)
**Documentation Structure and Clarity Improvements:**
- Clarified and reorganized the documentation file list in agent files,
removing references to deprecated or merged files (e.g.,
`MAINTENANCE.md`, `ACCESSIBILITY.md`) and updating descriptions to
reflect current usage.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L57-R65)
[[2]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L21-R21)
[[3]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L106-R137)
- Enhanced documentation on the purpose and application of each
documentation file, and added detailed explanations of Copilot
instruction files and their role in project development.
**Workflow and Validation Updates:**
- Updated references and descriptions for GitHub Actions workflows in
agent documentation to include the Copilot environment setup and clarify
pre-commit and CI/CD requirements.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L57-R65)
[[2]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L49-R51)
- Corrected references for accessibility guidance, now directing users
to `TROUBLESHOOTING.md` instead of the removed `ACCESSIBILITY.md`.
These changes collectively improve the onboarding experience for both
human contributors and AI agents, ensuring consistent adherence to
project conventions and reducing errors.
**References:**
[[1]](diffhunk://#diff-227c2c26cb2ee0ce0f46a320fc48fbcbdf21801a57f59161b1d0861e8aad55f5R1-R253)
[[2]](diffhunk://#diff-6fd2827fb8d9c2dd6dc973572201853487ecbbd1120b00425d4f1c21dfdcf35fR1-R174)
[[3]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L57-R65)
[[4]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L107-R122)
[[5]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L550-R562)
[[6]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L21-R21)
[[7]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L49-R51)
[[8]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L106-R137)
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Auto update markdown TOC
* docs: correct email configuration location in QUICKSTART.md (#3489)
Fixes #3488
Updates `QUICKSTART.md` to correctly point to `_data/socials.yml` for
email configuration, as the `email` field is not present in
`_config.yml`.
* fix(devcontainer): remove broken yarn apt source to fix build (#3490)
This change introduces a Dockerfile to the devcontainer configuration
that removes the broken Yarn repository from `/etc/apt/sources.list.d/`.
This prevents `apt-get update` from failing due to an expired or missing
GPG key for the Yarn repository.
Fixes #3487
* Improve AGENTS.md structure
Removed duplicate quick links for coding agents and customization.
* fix: CV rendering failure without Volunteer field (#3479)
Fixes #3478
* fix tikzjax (#3477)
Fixes #3216 – TikZJax not working.
1. Changing SHA simply doesn't work, `window.tikzjax` is undefined and
it doesn't render anything.
2. I switched to the JS distributed by
[benrbray/tikzjax](https://github.com/benrbray/tikzjax/tree/develop),
added under `assets.js` to prevent future issues.
3. Documents now require to start with `\begin{document}`, should be a
simple fix.
<img width="789" height="341" alt="Screenshot 2026-01-24 at 1 10 39 PM"
src="https://github.com/user-attachments/assets/8272471d-df94-4118-a726-00ed09dcf1e8"
/>
<img width="780" height="380" alt="Screenshot 2026-01-24 at 1 06 13 PM"
src="https://github.com/user-attachments/assets/11284661-de15-4d57-a1d9-4959f562f826"
/>
* Fix #2598, shift to last_modified_at instead of last_updated. (#3493)
Use `last_modified_at` rather than `last_updated`. So that the
jekyll-sitemap plugin automatically looks for the standard
`last_modified_at` front matter field to generate the `<lastmod>` tag in
your `sitemap.xml`.
It fixes [#2598](https://github.com/alshedivat/al-folio/issues/2598)
Also, it preserves backward compatibility, as the updated metadata logic
prioritizes the `page.last_modified_at`, and defaults to
`page.last_updated`.
* Making Gemini and Claude configuration files point to AGENTS.md (#3494)
This pull request updates project documentation to clarify and
standardize the development workflow, Git practices, and troubleshooting
resources. The main changes include adding a dedicated Git workflow
guide and reorganizing the `AGENTS.md` file for better clarity and
usability.
**Documentation and Workflow Improvements:**
* Added a new `.github/GIT_WORKFLOW.md` file detailing commit message
conventions, types, and best practices for staging and ignoring files.
* Reorganized and clarified the pre-commit checklist and local
development instructions in `AGENTS.md`, emphasizing Docker usage and
proper code formatting.
* Updated the section on configuration and troubleshooting in
`AGENTS.md` to better direct users to relevant resources and removed
redundant or outdated instructions.
[[1]](diffhunk://#diff-a54ff182c7e8acf56acfd6e4b9c3ff41e2c41a31c9b211b2deb9df75d9a478f9L57-R58)
[[2]](diffhunk://#diff-a54ff182c7e8acf56acfd6e4b9c3ff41e2c41a31c9b211b2deb9df75d9a478f9L100-R74)
**Configuration and Context Updates:**
* Added a `.gemini/settings.json` file to define context files for
Gemini agent operations, ensuring relevant documentation is available
for automation tools.
* Created `CLAUDE.md` file pointing to `AGENTS.md`.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Enhance documentation for GitHub Copilot agents
Added CLAUDE.md file for AI assistant integration and updated Copilot agents description.
* Fix Gemini settings
* Added information about creating custom metadata for collections
* Update Google Scholar citations
* Add GDPR-compliant cookie consent with analytics blocking (#3492)
Implements cookie consent using vanilla-cookieconsent v3 to comply with
GDPR requirements. Analytics scripts are blocked until user consent is
obtained.
## Changes
**Library Integration**
- Added `vanilla-cookieconsent@3.1.0` to `_config.yml` third-party
libraries with SRI hashes
- Created `_scripts/cookie-consent-setup.js` with consent modal and
settings configuration
- Added CSS/JS includes in `_includes/head.liquid` and
`_includes/scripts.liquid`
**Analytics Blocking**
- Modified analytics scripts in `scripts.liquid` and
`distill_scripts.liquid` to use conditional `type="text/plain"
data-category="analytics"` when consent is disabled
- Blocks Google Analytics, Cronitor, Pirsch, and OpenPanel until consent
granted
- Library automatically converts blocked scripts to executable on user
acceptance
**Configuration**
- Added `enable_cookie_consent` flag (default: `false`)
- Cookie categories: `necessary` (always on), `analytics` (optional)
- 182-day cookie expiration, auto-clear on rejection
## Implementation
```liquid
{% if site.enable_cookie_consent %}
<script type="text/plain" data-category="analytics" async src="...gtag.js"></script>
{% else %}
<script async src="...gtag.js"></script>
{% endif %}
```
Enable in `_config.yml`:
```yaml
enable_cookie_consent: true
```
## Screenshots
**Consent Modal**

**Settings Modal**

> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `cdn.jsdelivr.net`
> - Triggering command: `/usr/bin/curl curl -s REDACTED` (dns block)
> - `cookieconsent.orestbida.com`
> - Triggering command:
`/home/REDACTED/work/_temp/ghcca-node/node/bin/node
/home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps
/home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js`
(dns block)
> - `medium.com`
> - Triggering command: `/usr/local/bin/ruby ruby
/usr/local/bundle/bin/bundle exec jekyll serve --watch --port=8080
--host=0.0.0.0 --livereload --verbose --trace --force_polling s
6_64-linux /etc/locale.gen by/backward -binutils_2.44-3grep .deb eb
/systemd-sysctl` (dns block)
> - `publish.twitter.com`
> - Triggering command: `/usr/local/bin/ruby ruby
/usr/local/bundle/bin/bundle exec jekyll serve --watch --port=8080
--host=0.0.0.0 --livereload --verbose --trace --force_polling lude��
lude/ruby-4.0.0//run/containerd/io.containerd.runtime.v2.task/moby/a4760212ce4eda97e32b6dfa4d3ea/usr/sbin/iptables
r/runc-log.json f8_range lude r-strong E r/wc7in709a54d7hshow` (dns
block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/alshedivat/al-folio/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>GDPR compliant cookie consent dialog</issue_title>
> <issue_description>Hi,
>
> since I am from Europe and want my site to be accessed by EU citizens
I need to ask users if they are ok with the use of cookies. Adding a
dialogue by default that that asks the user before any cookies /
localStorage are used would be nice.
>
> I have integrated the dialog from
[https://www.cookieconsent.com/](https://www.cookieconsent.com/) on [my
website](http://hschwane.github.io) and am happy to file a PR if you are
interested. However It is not shown directly at the top, but below the
menu bar for some reason. Not sure how to fix that.
> </issue_description>
>
> <agent_instructions>Implement this using cookie consent dialog from
https://github.com/orestbida/cookieconsent. The documentation is
available at
https://cookieconsent.orestbida.com/essential/getting-started.html.</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> <comment_new><author>@alshedivat</author><body>
> @hschwane, thanks for pointing this out. It's would be great if you
could send a PR.
>
> To answer your question about positioning, the menu bar has the
absolute position at the top of the page and keeps moving with
scrolling. You can change that behavior in `_config.yml` by setting
`navbar_fixed: false` (see [line
27](https://github.com/alshedivat/al-folio/blob/master/_config.yml#L27)).
If you send a PR with basic functionality, I can help with adjusting the
styles a bit. Thanks!</body></comment_new>
> <comment_new><author>@alshedivat</author><body>
> Just catching up on this discussion.
>
> @hschwane, thanks for providing an implementation based on
`ihavecookies`! I looked through alshedivat/al-folio#223. It seems like
to be able to correctly (un)block different types of cookies (all of
which are third-party cookies) requires adding quite a bit of extra
JavaScript (including adding it directly to posts or pages in some
cases, e.g., when posts embed youtube videos or other external content).
This approach will put some extra burden on contributors and maintainers
of al-folio down the line.
>
> By the way, the dialog from https://www.cookieconsent.com/ is similar
in that sense as it requires to manually add ALL scripts that use
cookies. So, if someone contributes a new feature to al-folio that uses
cookies, the contributor would have to go and update the cookie consent
dialog as well (or edit quite a bit of JS if `ihavecookies` is used).
>
> Thinking about this more, I currently see only three options:
> 1. If we want to have cookie consent as a core part of al-folio (which
can be easily enabled or disabled), it needs to be a service that
automatically identifies and blocks cookies, without putting an extra
burden on the contributors or maintainers. The hosted version of [Cookie
Consent by Osano](https://www.osano.com/features/consent-management) is
an example.
> 2. Another option is to provide a very minimalistic cookie consent
dialog which simply says that the website uses cookies, without an
option to opt-in or opt-out (e.g., see the open-source edition of
[Osano](https://www.osano.com/cookieconsent/download/)).
> 3. Finally, not have cookie consent as part of al-folio, and make the
user responsible for figuring out whether they need a consent dialog and
which service to use.
>
> Let me know what you think.</body></comment_new>
> <comment_new><author>@alshedivat</author><body>
> the best way to add GDPR compliant cookie consent is using
https://github.com/orestbida/cookieconsent</body></comment_new>
> </comments>
>
</details>
> **Custom agent used: customization_agent**
> Expert customization assistant for the al-folio Jekyll academic
website template
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes alshedivat/al-folio#199
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/alshedivat/al-folio/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: george-gca <31376482+george-gca@users.noreply.github.com>
Co-authored-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Auto update markdown TOC
* Improve explanation of create from this template (#3499)
This pull request improves the documentation to clarify the recommended
way to create a new site using the al-folio template, emphasizing the
use of the "Use this template" button instead of forking. It explains
the differences between the two approaches, highlights common pitfalls
with forking, and provides guidance for users who have already forked
the repository.
Documentation improvements regarding repository creation:
* Added a prominent section in `README.md` explaining why "Use this
template" is preferred over forking, including step-by-step instructions
and advice for users who have already forked.
* Updated `QUICKSTART.md` to strongly recommend using the "Use this
template" button, clarified the steps for creating a new repository, and
included tips for users who have already forked by mistake.
* Added a new section in `INSTALL.md` detailing the differences between
using the template and forking, common pitfalls, and best practices for
contributing.
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Update Google Scholar citations
* Added new research blog in README.md (#3522)
* Update Google Scholar citations
* Add link to personal page (laura wagner) in README (#3552)
Adding my personal academic website to the academics list
* Add Fukushima Lab to User community (Labs) (#3559)
This PR adds Fukushima Lab to the **User community** section in
`README.md` under **Labs**. Thank you for maintaining such a great and
inspiring website template.
Added link:
- https://kenji-fukushima-lab.github.io/
Co-authored-by: Kenji Fukushima <kf@MacBookPro.elecom>
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* add vud.org to community list (#3575)
Add vud.org to community list.
* Added website of B. Choi (Update README.md) (#3569)
Hello, please add my academic website to the community page. Thank you
for maintaining this project.
* [Update] add workshop to README.md (#3585)
Add new workshop to README.md
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Add pranavraj575 website to README
* Add deden.id website to README
Please let my website be on the growing list! I'm Deden Habibi Ali
Alfathimy, a researcher in outer space politics, with personal website
https://deden.id using al-folio.
* Upgrade al-folio to v1.0 (#2968)
## Overview
This PR delivers the `v1.0` architecture and runtime upgrade for
`al-folio`.
`al-folio` moves from a monolithic theme repo to a **thin starter +
plugin ecosystem** model, while preserving visual identity and core
behavior.
## What this PR changes
### 1) Starter becomes orchestration-only
`al-folio` is now responsible for:
- starter wiring (`Gemfile`, `_config.yml`)
- sample/demo content
- user-facing docs
- visual regression and cross-plugin integration tests
Component/runtime ownership is moved to dedicated gems.
### 2) Runtime and feature ownership split into plugins
`al_folio_core` now provides shared runtime/layout primitives and
contracts, and delegates feature modules to owning gems.
Key plugin ownership in v1:
- `al_folio_core`: core theme runtime/contracts
- `al_folio_distill`: Distill layouts/runtime
- `al_folio_cv`: CV rendering
- `al_search`: search runtime and modal behavior
- `al_icons`: icon runtime (Font Awesome, Academicons, Scholar Icons)
- `al_cookie`: cookie-consent runtime
- `al_img_tools`: image/gallery/lightbox tooling
- `al_math`: math/TikZ runtime integration
- additional `al-*` plugins for
analytics/charts/citations/comments/newsletter/external posts/upgrade
tooling
### 3) Styling/runtime modernization
- Tailwind-first v1 runtime is established.
- Legacy Bootstrap behavior is isolated behind optional
`al_folio_bootstrap_compat` for migration windows.
- jQuery-dependent runtime paths are removed/replaced in plugin-owned
implementations.
### 4) Test ownership policy is enforced
- `al-folio` keeps only starter-level integration and visual integrity
checks.
- Component correctness tests are owned by the corresponding plugin
repos.
This mirrors runtime ownership and reduces duplication/drift.
### 5) Upgrade and migration workflow
`al_folio_upgrade` is integrated for audit/apply/report migration flows,
including:
- config contract checks
- ownership drift detection
- local override drift audit/diff/acknowledgement workflow
- legacy marker detection
- plugin wiring validation
### 6) Documentation and contributor model for v1
Docs are updated to reflect modular v1 behavior and contribution
routing.
New governance additions include:
- plugin ownership/boundary guidance (`docs/BOUNDARIES.md`)
- plugin naming convention (theme-coupled vs reusable plugin tracks)
- featured-vs-bundled plugin distinction
- plugin catalog source + page (`_data/featured_plugins.yml`,
`_pages/plugins.md`)
- plugin feature proposal issue template
- PR template updates for ownership routing
- agent-facing setup and migration skills
## Compatibility and migration notes
- Plugin integration in starter is via `Gemfile` + `_config.yml`.
- `al-folio` starter intentionally does not use a gemspec in v1.
- Transitional Bootstrap compatibility remains available via
`al_folio_bootstrap_compat`.
- Existing front-matter contracts are preserved where possible; runtime
implementations are now plugin-owned.
- Customized sites can track local override drift with `bundle exec
al-folio upgrade overrides audit` and `.al-folio-overrides.yml`.
## Validation strategy in this PR
- visual parity checks against the v0.16.3 baseline
- starter integration suites (comments, plugin toggles, distill, compat,
upgrade CLI)
- style contract checks and repository linting
## Scope intent
This is the foundational v1 architecture PR.
Post-merge feature work should generally target owning plugin repos
first, with `al-folio` limited to starter wiring, docs, examples, and
integration/visual validation.
_Written by Codex on behalf of @alshedivat._
* Fix broken navbar: stop double-minifying Tailwind CSS in production (#3634)
## Summary
Fixes the broken navigation bar on the live demo
(https://alshedivat.github.io/al-folio/) introduced by the v1.0 upgrade
(#2968), plus two related production/deploy-only issues found while
auditing for the same class of bug.
## Root cause of the navbar break
The v1.0 upgrade made the site **Tailwind-first**. The deploy builds
with `JEKYLL_ENV=production`, which activates **jekyll-minifier**. Its
CSS compressor (`cssminify2`) mangles Tailwind v4 spacing tokens
**inside `calc()`**:
```
calc(var(--spacing)*0) -> calc(var( - - spacing)*0) // invalid
```
`cssminify2` treats the `--` inside `calc(var(--…))` as minus operators
and inserts spaces, producing an invalid custom-property name. This
silently breaks **every** spacing/positioning utility — most visibly
`.fixed-top`, so the fixed navbar is no longer pinned (`top/left/right`
drop out) and renders incorrectly. On the live site this affects 33
`var(--spacing)` references in `tailwind.css`.
It only manifests in **production**: a local `bundle exec jekyll serve`
is development mode (minifier off), and the `visual-regression` workflow
also serves in dev mode — so neither caught it.
### Why this fix
`tailwind.css` is already minified by al_folio_core's Tailwind build,
and `main.css` is compiled by Sass with `style: compressed`.
Re-minifying them with `cssminify2` adds nothing (it actually makes
`tailwind.css` ~315 bytes **larger**) and only introduces this
corruption. So we disable redundant CSS minification, mirroring the
existing `compress_javascript: false` (terser handles JS).
Verified end-to-end:
- The gem source `tailwind.css` has 82 intact `var(--spacing)`;
`cssminify2` corrupts all 82.
- jekyll-minifier (`lib/jekyll-minifier.rb:1061`): `return
output_file(path, content) unless config.compress_css?` — with
`compress_css: false`, `.css` files are written verbatim.
- A real `JEKYLL_ENV=production` build now emits `tailwind.css` with 82
intact `var(--spacing)`, 0 corrupted, and
`.fixed-top{...;position:fixed}` intact.
- PurgeCSS (the next deploy stage) preserves `calc(var(--spacing)*0)`
unchanged.
## Changes
1. **`_config.yml` — `jekyll-minifier.compress_css: false`** (the navbar
fix).
2. **`test/integration_css_minify.sh` + `unit-tests.yml`** — a
regression test that builds in **production mode** (the mode that
exposes this bug class) and asserts no `var( - - )` corruption, intact
`var(--spacing)`, a valid `.fixed-top`, and a non-empty `main.css`.
Passes with the fix; fails without it (83 corruptions). Closes the CI
blind spot that let this ship.
3. **`_config.yml` — drop dead `jekyll-minifier` exclude**
`assets/js/search/*.js`. That is a v0 path; in v1 the search runtime
ships under `assets/al_search/js/...`, so the glob matched nothing.
4. **`purgecss.config.js` — safelist `medium-zoom-overlay` /
`medium-zoom-image--opened`.** These classes are injected at runtime, so
they never appear in the static HTML PurgeCSS scans; their `z-index:999`
overlay rule was being purged on the deployed site, letting the
scroll-progress bar / ToC bleed through a zoomed image. Verified: the
rule survives purge with the safelist and is dropped without it.
## Broader audit — plugin fixes (released + pinned here)
I audited for the same bug class (regressions invisible to dev-mode
builds / leftovers from the v1 jQuery removal). The confirmed
plugin-owned issues were each fixed in their own repo, merged after
green CI, released to RubyGems, and pinned in this PR's `Gemfile`:
- **al_folio_core 1.0.10**
([#18](https://github.com/al-org-dev/al-folio-core/pull/18)) —
`main.css` cache-bust was permanently the empty-string MD5
(`bust_css_cache` globbed a non-existent `assets/_sass`) → stale CSS
after deploys; `bib.liquid` "N more authors" used `$(this)` → threw and
never expanded; `figure.liquid` `onerror` used `$()` → dead broken-image
fallback.
- **al_charts 1.0.1**
([#7](https://github.com/al-org-dev/al-charts/pull/7)) —
`chartjs-setup.js` was jQuery → `chartjs` charts threw `$ is not
defined` and never rendered.
- **al_folio_distill 1.0.2**
([#2](https://github.com/al-org-dev/al-folio-distill/pull/2)) —
`overrides.js` top-level `$(window).on("load")` → distill
footnote/citation theming never applied + console error.
Verified end-to-end with a production build after the pin bumps:
`main.css` now cache-busts to a real hash (`9278fad1…`, not
`d41d8cd9…`), zero jQuery `$(` in the built HTML, and the Tailwind
spacing utilities / `.fixed-top` navbar are intact.
Also noted (not fixed here): the `visual-regression` workflow only
renders in dev mode, so it can't catch production-only CSS regressions —
`test/integration_css_minify.sh` is the immediate guard; a production
screenshot leg would be a fuller backstop.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: expand CLAUDE.md with the v1 plugin-ecosystem architecture (#3635)
## Summary
Expands `CLAUDE.md` from a bare `@AGENTS.md` import into a useful entry
point for coding agents, while **keeping** that import so `AGENTS.md`'s
ownership boundaries, validated command set, and PR-routing rules still
flow in (and stay the short, ecosystem-neutral shared file).
The added content is the cross-repo "big picture" that no single file in
this repo currently documents — gathered by reading the starter
internals plus all 16 `al-*` / `al_folio_*` plugin gems:
- **al_folio_core hub + delegation map** — a `wrapper → tag → gem` table
for every bundled plugin, so a runtime change can be routed to the
owning repo in one lookup.
- **Sibling-repos-on-disk** layout and how to point the `Gemfile` at a
local gem checkout (`path:`) to test a gem fix against the site.
- **Cross-repo invariants** — two-layer feature gating (config flag
*and* front matter), `AssetsGenerator` build-time asset injection, the
`Gemfile` ↔ `_config.yml` plugin-list sync, the v1 config contract
(enforced by core's `:after_init` and `al-folio upgrade audit`),
`.al-folio-overrides.yml` drift tracking, and the time-boxed
bootstrap-compat path.
- **Daily dev loop** that `AGENTS.md` omits (`jekyll serve`, single
integration test, snapshot refresh, upgrade subcommands).
- The v1 Docker `/tmp/_site` rationale and the `style_contract.js`
boundary that fails CI if runtime/build files leak into the starter.
Every specific claim (gem versions, tag names, config keys) is grounded
in the actual repos. Prettier-clean.
> Split out from the navbar-fix PR (#3634) per request; this PR is
docs-only and independent.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix links (#3628)
## Summary
In the "User community" README section several links didn't work
anymore. I updated them where I was able to find a new link from the
same person, and removed the ones where I didn't find a new link.
## Ownership Routing
- [x] I confirmed this PR targets the correct repo based on
`docs/BOUNDARIES.md`.
- [x] This PR only changes starter-owned scope (`al-folio`) **or** I am
porting a routed change and linked the owning repo issue/PR.
## Plugin Ecosystem (if applicable)
- [x] Not applicable
- [ ] This PR proposes a plugin for **featured-only** listing.
- [ ] This PR proposes a plugin for **bundled** starter inclusion.
## Starter Wiring Changes
- [x] Not applicable
- [ ] Updated `Gemfile` dependency wiring.
- [ ] Updated `_config.yml` plugin activation/config.
- [ ] Updated `_data/featured_plugins.yml` metadata.
## Validation
- [x] `npm ci`
- [ ] `bundle exec jekyll build`
- [x] `npm run lint:prettier`
- [x] `npm run lint:style-contract`
- [ ] Integration tests (`test/integration_*.sh`) as needed
- [ ] Visual tests (`npm run test:visual`) as needed
* Fix visual regressions: broken repo stat cards and unstyled af-popover/tooltip (#3636)
## What's broken on the demo site
A full-page screenshot audit of every page on
https://alshedivat.github.io/al-folio/ surfaced two user-visible bugs
introduced or exposed by the v1 upgrade.
### Bug 1 — Repositories page: all stat cards show broken alt-text
(HIGH)
Both external services are currently unavailable:
- `github-readme-stats.vercel.app` → HTTP 503 `DEPLOYMENT_PAUSED`
- `github-profile-trophy.vercel.app` → HTTP 402
Every `<img>` on the repositories page fails to load, rendering as a
list of broken-image alt-text strings. The templates had no `onerror`
fallback.
**Fix (in al_folio_core):**
`onerror="this.closest('.repo').style.display='none'"` on every
stat-card image in `repo.liquid`, `repo_user.liquid`, and
`repo_trophies.liquid`. When a service is unavailable the entire card
hides gracefully; when it comes back up cards render normally.
### Bug 2 — `.af-popover` / `.af-tooltip` completely unstyled (MEDIUM)
`tooltips-setup.js` (active by default, since bootstrap-compat is
disabled) creates `.af-popover` and `.af-tooltip` elements as its
vanilla fallback — for example when hovering the author-info circle icon
(ⓘ) on the publications page. These class names had **no CSS rules at
all** in `al_folio_core`: no `position`, no styling, no `z-index`. The
tooltip/popover appeared as invisible, unpositioned text nodes appended
to `document.body`.
(The theme's `_utilities.scss` only defined `.popover` — Bootstrap's
class — which is irrelevant without bootstrap-compat loaded.)
**Fix (in al_folio_core):** Added `position: absolute`, `z-index:
1070/1080`, and theme-color styling to both classes. The purgecss
safelist in al-folio already protects both names so they survive the
deploy pipeline.
## Changes
- `Gemfile` / `Gemfile.lock`: bump `al_folio_core` 1.0.10 → 1.0.11 ([PR
#19](https://github.com/al-org-dev/al-folio-core/pull/19), now merged
and released)
## Scope
All other pages screenshotted look correct. No other CSS/layout
regressions were found beyond these two. The screenshot audit also
confirmed:
- The `var(--spacing)` Tailwind fix from #3634 is working correctly in
production.
- `main.css` cache-bust hash (`9278fad1…`) is stable and non-empty.
- All blog posts, CV, teaching, people, projects, books pages render as
expected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Add a link to my lab website in user community section (#3645)
Add a link to my lab website in the user community of README.
## Summary
Many thanks to the authors and contributors of this repo. I'm glad to
add my lab's website in the user community section of README.
## Ownership Routing
- [x] I confirmed this PR targets the correct repo based on
`docs/BOUNDARIES.md`.
- [ ] This PR only changes starter-owned scope (`al-folio`) **or** I am
porting a routed change and linked the owning repo issue/PR.
Owning repo (if not starter): <!-- e.g., al-org-dev/al-folio-core -->
Related issue/PR: <!-- link -->
## Plugin Ecosystem (if applicable)
- [x] Not applicable
- [ ] This PR proposes a plugin for **featured-only** listing.
- [ ] This PR proposes a plugin for **bundled** starter inclusion.
If plugin-related, provide:
- Plugin repo URL:
- Gem name:
- Jekyll plugin id:
- Compatibility (`al_folio_min`/`al_folio_max`):
- Demo page/post path:
- Maintainer contact:
## Starter Wiring Changes
- [x] Not applicable
- [ ] Updated `Gemfile` dependency wiring.
- [ ] Updated `_config.yml` plugin activation/config.
- [ ] Updated `_data/featured_plugins.yml` metadata.
## Validation
- [ ] `npm ci`
- [ ] `bundle exec jekyll build`
- [ ] `npm run lint:prettier`
- [ ] `npm run lint:style-contract`
- [ ] Integration tests (`test/integration_*.sh`) as needed
- [ ] Visual tests (`npm run test:visual`) as needed
## Notes
Compatibility, migration implications, and follow-ups:
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Bump nokogiri from 1.19.3 to 1.19.4 (#3653)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.19.3
to 1.19.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/sparklemotion/nokogiri/releases">nokogiri's
releases</a>.</em></p>
<blockquote>
<h2>v1.19.4 / 2026-06-18</h2>
<h3>Security</h3>
<ul>
<li>[CRuby] (Low) Fixed a possible invalid memory read when
<code>XML::Node#initialize_copy_with_args</code> is called with an
argument that is not a <code>Node</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-g9g8-vgvw-g3vf">GHSA-g9g8-vgvw-g3vf</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when an
<code>XML::XPathContext</code> is used after its source document has
been garbage collected. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-p67v-3w7g-wjg7">GHSA-p67v-3w7g-wjg7</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free during XInclude
processing via <code>Node#do_xinclude</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wfpw-mmfh-qq69">GHSA-wfpw-mmfh-qq69</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when
<code>Document#root=</code> is assigned a non-element node. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wjv4-x9w8-wm3h">GHSA-wjv4-x9w8-wm3h</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when setting an
attribute value via <code>XML::Attr#value=</code> or
<code>#content=</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-phwj-rprq-35pp">GHSA-phwj-rprq-35pp</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a null pointer dereference when methods are
called on uninitialized wrapper objects (e.g. via
<code>allocate</code>); these now raise instead of crashing the process.
See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-9cv2-cfxc-v4v2">GHSA-9cv2-cfxc-v4v2</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when
<code>Document#encoding=</code> raises an exception. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5v8h-3h3q-446p">GHSA-5v8h-3h3q-446p</a>
for more information.</li>
<li>[CRuby] (Medium) Fixed an out-of-bounds read in
<code>XML::NodeSet#[]</code> (alias <code>#slice</code>) when given a
large negative index. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5prr-v3j2-97mh">GHSA-5prr-v3j2-97mh</a>
for more information.</li>
<li>[JRuby] (Low) <code>XML::Schema</code> now enforces the
<code>NONET</code> parse option, which Nokogiri enables by default. It
was not enforced on JRuby, so a schema parsed with default options could
still fetch external resources over the network, potentially enabling
SSRF or XXE attacks and bypassing the mitigation for CVE-2020-26247. See
<a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-8678-w3jw-xfc2">GHSA-8678-w3jw-xfc2</a>
for more information.</li>
</ul>
<!-- raw HTML omitted -->
<pre><code>1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f
nokogiri-1.19.4-aarch64-linux-gnu.gem
35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af
nokogiri-1.19.4-aarch64-linux-musl.gem
a301313e38bb065d68239e79734bcd6f56fb6efaacebde29e9abf2a4735340ca
nokogiri-1.19.4-arm-linux-gnu.gem
588923c101bcfa78869734d247d25b598674323e7f22474fc468f6e5647311eb
nokogiri-1.19.4-arm-linux-musl.gem
a46db9853286e6597b36ebc6953817d15acf3a299583eb3f89fdc6f91dd63527
nokogiri-1.19.4-arm64-darwin.gem
ce04b9e268c9626852231a48b49128ed52034f1ccb39484a6da3875491cd709e
nokogiri-1.19.4-java.gem
051da97b8eccfdb5444fed40246a35e10d7298b9efe759b4cd25455ea04c587e
nokogiri-1.19.4-x64-mingw-ucrt.gem
7fd17057d3e1f00e9954a74b3cd76595d3d4a5ef233b7ed9599047c204f70551
nokogiri-1.19.4-x86_64-darwin.gem
379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a
nokogiri-1.19.4-x86_64-linux-gnu.gem
17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b
nokogiri-1.19.4-x86_64-linux-musl.gem
50c951611c92bca05c51411aef45f1cbc50f2821c4802758c5c6d34696533ab5
nokogiri-1.19.4.gem
</code></pre>
<!-- raw HTML omitted -->
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md">nokogiri's
changelog</a>.</em></p>
<blockquote>
<h2>v1.19.4 / 2026-06-18</h2>
<h3>Security</h3>
<ul>
<li>[CRuby] (Low) Fixed a possible invalid memory read when
<code>XML::Node#initialize_copy_with_args</code> is called with an
argument that is not a <code>Node</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-g9g8-vgvw-g3vf">GHSA-g9g8-vgvw-g3vf</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when an
<code>XML::XPathContext</code> is used after its source document has
been garbage collected. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-p67v-3w7g-wjg7">GHSA-p67v-3w7g-wjg7</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free during XInclude
processing via <code>Node#do_xinclude</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wfpw-mmfh-qq69">GHSA-wfpw-mmfh-qq69</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when
<code>Document#root=</code> is assigned a non-element node. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wjv4-x9w8-wm3h">GHSA-wjv4-x9w8-wm3h</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when setting an
attribute value via <code>XML::Attr#value=</code> or
<code>#content=</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-phwj-rprq-35pp">GHSA-phwj-rprq-35pp</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a null pointer dereference when methods are
called on uninitialized wrapper objects (e.g. via
<code>allocate</code>); these now raise instead of crashing the process.
See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-9cv2-cfxc-v4v2">GHSA-9cv2-cfxc-v4v2</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when
<code>Document#encoding=</code> raises an exception. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5v8h-3h3q-446p">GHSA-5v8h-3h3q-446p</a>
for more information.</li>
<li>[CRuby] (Medium) Fixed an out-of-bounds read in
<code>XML::NodeSet#[]</code> (alias <code>#slice</code>) when given a
large negative index. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5prr-v3j2-97mh">GHSA-5prr-v3j2-97mh</a>
for more information.</li>
<li>[JRuby] (Low) <code>XML::Schema</code> now enforces the
<code>NONET</code> parse option, which Nokogiri enables by default. It
was not enforced on JRuby, so a schema parsed with default options could
still fetch external resources over the network, potentially enabling
SSRF or XXE attacks and bypassing the mitigation for CVE-2020-26247. See
<a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-8678-w3jw-xfc2">GHSA-8678-w3jw-xfc2</a>
for more information.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/sparklemotion/nokogiri/commit/8cfb9daae9ee4a0837508eab43c40fbc8c4138c9"><code>8cfb9da</code></a>
version bump to v1.19.4</li>
<li><a
href="https://github.com/sparklemotion/nokogiri/commit/a856d1e46bda04ef47a0bd2b9eefe86df1eb0bb2"><code>a856d1e</code></a>
fix: JRuby NONET bypass in XML::Schema (v1.19.x) (<a
href="https://redirect.github.com/sparklemotion/nokogiri/issues/3639">#3639</a>)</li>
<li><a
href="https://github.com/sparklemotion/nokogiri/commit/6a0aa1e7042ea58e10db713d498…
kastnerp
added a commit
that referenced
this pull request
Sep 9, 2026
* Update dogan.md
* Team Updates
* Team Updates
* Update thach.md
* Update gomez.md
* GitHub profile autoinclude
Update page.liquid
.
* GitHub autoinclude
* Update yang.md
* fixed run files
* Update gt-arch-7014.md
* Update gt-arch-7014.md
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* feat: add Code tab and GitHub repo cards
* feat: add Code tab and GitHub repo cards
* Update li.md
* Update join.md
* Update Google Scholar citations
* Add news posts for Sina defense and CHHS talk
* Update Google Scholar citations
* Update Google Scholar citations
* Update remote_include URL in thach.md (#37)
* Fix repository page layout
* Improve repository card title overflow
* Restore repository card design
* Update almaian.md
* Update _base.scss
* Update almaian.md
* .
* Update repo.liquid
* Update karadag.md
* Add Shen visit news post
* Normalize image asset paths
* Prevent team avatar footer overlap
* Add Cypress thesis defense news post
* Add Jimmy team profile (#39)
* Jimmy Miao Zhang
* Jimmy Miao Zhang Profile Photo
* Revise Jimmy's profile details and image
Updated profile information for Jimmy Miao.
* Update and rename jimmy.md to miao.md
* Update miao.md
* Update Google Scholar citations
* Update Google Scholar citations
* Create announcement_43.md
* Add MT projects for Benjamin Shih and Joseph Aerathu
* Fix video rendering on Joseph Aerathu project page
* Add project links to team pages
* Add CP-GNI2024-Symposium-Enriching-geospatial-building-datasets project (#41)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update title to 'Jimmy Miao Zhang' (#40)
* Update Google Scholar citations
* Update papers.bib with missing code links (#43)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update Google Scholar citations
* Update about.liquid
* Add Karadag 2026 publication (#44)
* Add Karadag 2026 urban wind simulation publication
- Added the BibTeX entry for `KARADAG2026107614` to `_bibliography/papers.bib`.
- Associated the publication with the `cfdgan-compressed.gif` preview image.
- Added the `bibtex_show` field to the new entry.
- Added `2026` to `years_papers` in `_pages/research/children/publications.md` so the newly added publication is rendered on the website.
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Add specific karadag image to publication
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Change publication preview image to abstract screenshot
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update karadag_abstract.png
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Fix formatting of year fields in _bibliography/papers.bib (#46)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update Google Scholar citations
* Dynamically pull Sina Rahimi's PhD README in project page (#47)
Replaced the hardcoded source link in `_projects/PhD-SinaRahimi.md` with a Liquid remote_include block that fetches and displays the actual GitHub README.md content.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update Google Scholar citations
* Update Google Scholar citations
* fix: switch repo cards to working github-readme-stats deployment (#49)
Public instance github-readme-stats.vercel.app returns 503
DEPLOYMENT_PAUSED, breaking all repo card images on /code/.
Point at the author's working deployment alias instead.
Co-authored-by: Patrick Kastner <1919773+kastnerp@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Add new display categories in theses.md (#48)
* Add new display categories in theses.md
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Add new display categories in theses.md
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Integrate new projects and update bibtex
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Integrate new projects and update bibtex
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update bibtex fields and add macadThesis24
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Remove macadThesis24
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: kastnerp <1919773+kastnerp@users.noreply.github.com>
* Update Google Scholar citations
* Add Best Poster Award details to Maryam SimBuild 2026 post
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Add SimBuild 2026 award photo and certificate to Maryam post
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Update Google Scholar citations
* Update socials.yml
* Update Google Scholar citations
* Update to al-folio v1.1 (v0 → v1 gem architecture migration) (#50)
* Added support for helping agents (#3379)
Since a lot of our users don't have a coding background and given
recently development with AI agents, I decided to try to add support for
specialized agents in our repository. They were created following
[agents.md](https://agents.md/) "specifications" and are currently 2:
- `customize-agent` - to help new users with access to GitHub Copilot
customize their site
- `docs-agent` - to help us keep the documentation always updated with
the latest changes in our code
I don't really know how useful they'll actually be, but I think most of
our users might actually benefit from the `customize-agent`, so it is
worth a shot.
<img width="852" height="1043" alt="image"
src="https://github.com/user-attachments/assets/e8390f1a-cec3-42a8-b01e-26d658ea78e8"
/>
Edit: also added a link to a [Code Wiki to our
repository](https://codewiki.google/github.com/alshedivat/al-folio) and
[DeepWiki](https://deepwiki.com/alshedivat/al-folio). This allows any
user to chat online with AIs (Gemini and Devin) about our repository.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Auto update markdown TOC
* Fix bib / code layout bug (#3387)
Resolve #3370
Resolve #3380
Based on the
[comment](https://github.com/alshedivat/al-folio/issues/3370#issuecomment-3565962058)
of @MarkusThill, I created a bugfix that solved the issue on my website.
Hope that fixes it in general; thus the PR :) However, I'm not an expert
for scss .. so handle with care :)
* Fix: bibliography month persists to subsequent entries without month (#3391)
Fixes #3386 (the part about the wrong months; the other part (layouting
of bibtex) is fixed in #3387)
## Summary
- Fixes incorrect month shown for bibliography entries that do not
specify a `month` in BibTeX.
- Ensures `month`/`year` do not persist between entries in
`_layouts/bib.liquid`.
## Root Cause
- In Liquid, captured variables persist across iterations if not
reinitialized.
- `entrymonth` and `entryyear` were only set when
`entry.month`/`entry.year` existed, causing values from a previous entry
to leak into the next one when those fields were missing.
## Changes
- Reinitialize date-related variables per entry before conditional
captures:
## Behavior
- Before: Entries without a `month` could display the previous entry's
month.
- After: Entries without a `month` display only the `year`; entries with
a `month` display the correct month and year.
<img width="1956" height="918" alt="image"
src="https://github.com/user-attachments/assets/7a9682e7-55ab-43b7-8f82-f638d14ce08e"
/>
* Fixed 1 px first load issue (#3416)
Fix #3164
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Added support for default categories and tags for external posts (#3417)
Based on discussion #3393.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Add link to personal GitHub page on academics section in README (#3400)
* Add auto-orient flag to Imagemagick config (#3409)
Currently, images generated by Imagemagick do not respect the
orientation of the source image. By adding the auto-orient flag, the
images are the correct orientation.
Before
<img width="920" height="562" alt="image"
src="https://github.com/user-attachments/assets/73f59d7f-b6c5-468a-9023-0f0457a53a3c"
/>
After
<img width="947" height="621" alt="image"
src="https://github.com/user-attachments/assets/2f24de99-2e84-4052-8d0f-945acdad81e4"
/>
* Update deps (#3418)
Closes #3402
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Added new line to README badges
* Changed maintainers urls to https
* Updated prettier (#3420)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Fix typo in Bootstrap small column class usage (#3421)
This PR fixes a recurring typo in multiple Liquid templates where the
Bootstrap class `cl-sm` is used instead of `col-sm`.
Because of this typo, the `col-sm` styling was not being applied. All
instances have been corrected.
* Update Google Scholar citations
* Make external service URLs configurable for repository page (#3422)
## Description
This PR makes the URLs for external services used on the repository page
configurable in `_config.yml`. This allows users to self-host these
services for better reliability, privacy, and customization.
## Changes
- Added `external_services` configuration section in `_config.yml` with:
- `github_readme_stats_url` (default:
`https://github-readme-stats.vercel.app`)
- `github_profile_trophy_url` (default:
`https://github-profile-trophy.vercel.app`)
- Updated repository template files to use configurable URLs:
- `_includes/repository/repo_user.liquid`
- `_includes/repository/repo.liquid`
- `_includes/repository/repo_trophies.liquid`
- Added documentation in `CUSTOMIZE.md` explaining:
- Why self-hosting is recommended (default services may have
availability issues)
- How to configure custom service URLs
- Links to the service repositories for deployment instructions
## Resolves
Resolves #3388 - This makes it possible to configure self-hosted
versions of these services, giving users full control over the external
services used for displaying GitHub statistics and trophies.
## Testing
- Verified that default configuration still works with original service
URLs
- Confirmed that URLs are properly interpolated in all template files
- Documentation clearly explains the configuration options
* Auto update markdown TOC
* Remove link to sam-bieberich.github.io (#3425)
Removed a link to sam-bieberich.github.io from the README.
* Add link to personal GitHub page on academics section in README (#3424)
* Add j1yoo.github.io to User community (#3427)
Hi! I'd like to add my academic website to the User community section.
**Website:** https://j1yoo.github.io/
This PR adds a single star link to the Academics row in the User
community table.
Thank you for creating and maintaining this beautiful theme!
Co-authored-by: Jaewon Yoo <jwyoo4@gmail.com>
* add filtered BibTeX keywords (#3403)
add `dimensions, eprint` and `pmid` to the filtered keywords
* Add HAL button (#3404)
Adds a HAL button in the same spirit as the arXiv button.
- add HAL button to `_layouts/bib.liquid`
- add `hal` to the filtered keywords in `_config.yml`
- add `hal` to the documentation in `CUSTOMIZE.md`
* Improved collections section in CUSTOMIZE guide (#3431)
Improved section based on comments from #2369.
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Add zhoji.github.io to User community in README.md (#3433)
Adding my personal website for the al-folio community :) Thanks for
creating such a cool template!
* Changed code to use plugin to handle 3rd party libraries downloads (#3435)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Changed to use cache bust plugin (#3436)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Update deps (#3437)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Changed to use jekyll-socials plugin (#3439)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Updated deps and deploy version (#3440)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Fixed dates in book-shelf (#3446)
Fixes #3443.
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Updated deps to fix issue with jekyll-socials (#3447)
Fixes #3445
Signed-off-by: George Araújo <george.gcac@gmail.com>
* ⚡ Optimize Google Scholar Citations Regex Definition (#3449)
💡 **What:** Moved the regex definition `/Cited by (\d+[,\d]*)/` from the
method scope to a class-level constant `CITED_BY_REGEX`.
🎯 **Why:** To improve code cleanliness and avoid potential re-definition
of the regex object in every method call (or loop), adhering to best
practices.
📊 **Measured Improvement:**
* **Baseline:** The regex was defined as a literal inside the `render`
method, which is called for each tag usage.
* **Optimization:** The regex is now defined once as a constant.
* **Note:** Performance benchmarks were not possible in the current
environment due to missing Ruby runtime. However, this is a standard
Ruby optimization that improves maintainability and theoretically avoids
object allocation overhead in older Ruby versions or complex scenarios.
Modern Ruby optimizes literals well, but the constant approach is
cleaner and DRYer.
---
*PR created automatically by Jules for task
[10688912524063334698](https://jules.google.com/task/10688912524063334698)
started by @alshedivat*
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Refactor: Use Liquid filter to find home page title (#3448)
Refactored the script in _scripts/search.liquid.js to use a more
efficient Liquid 'where' filter to find the home page title. This
replaces an inefficient for loop that iterated through all site pages.
---
*PR created automatically by Jules for task
[5748098109809984605](https://jules.google.com/task/5748098109809984605)
started by @alshedivat*
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* Revert "Refactor: Use Liquid filter to find home page title" (#3451)
Reverts alshedivat/al-folio#3448
* Updated jekyll-archives-v2 (#3460)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Add course schedule feature to teaching page (#2258) (#3147)
Implements the course schedule feature requested in issue
#[2258](https://github.com/alshedivat/al-folio/issues/2258).
This PR adds a new course schedule feature to the al-folio theme,
allowing academics to easily create and display structured course
information.
**Changes:**
- Added a `courses` collection to organize and display academic courses
- Created course layout and display templates with responsive design
- Implemented organization by year and term with automatic sorting
- Added support for weekly schedule with topics and course materials
- Simplified documentation with a README for course creation
This feature makes it easier for academics to showcase their teaching
materials with a consistent, organized display of course schedules,
helping users create professional teaching pages without custom
implementation.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Add calendar iframe and togglAdd calendar iframe and toggle buttone button (#3144)
### Description
This PR adds a Google Calendar integration feature as described in issue
#872. Users can embed their own calendar using an iframe configured via
`_config.yml`, and the calendar is toggleable through a responsive
button. This component is styled to visually blend into the theme and
supports responsive display across desktop and mobile.
### Changes
- Added `calendar.liquid` in `_includes`
- Modified `about.md` to include the toggleable calendar block
- Introduced `calendar` config section in `_config.yml`
- Appended calendar-related styles in `_sass/_base.scss`
### Configuration
To enable this feature, add the following to `_config.yml`:
```yaml
calendar:
enabled: true
calendar_id: your_calendar_id@group.calendar.google.com
timezone: UTC
style: "border:0; width:100%; height:600px;"
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: dodo <349507644@qq.com>
Co-authored-by: George <31376482+george-gca@users.noreply.github.com>
Co-authored-by: George Araújo <george.gcac@gmail.com>
* Update Google Scholar citations
* Updated jekyll-socials to latest version (#3464)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Add smsnoBin77 link to README (#3473)
Add a new link to the README for smsnoBin77.
* Unify jsonresume and RenderCV CVs solutions (#3462)
Fixes #2787 as an alternative to #2969. It was getting too cumbersome to
have 2 different data sources for CV and also a lot of different layout
files, so I decided to unify them all.
Main changes:
- synchronized the information inside RenderCV (`_data/cv.yml`) and
JSONResume (`assets/json/resume.json`)
- unified layout files for CV information
- added the option to set the "data source" in the CV page
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* chore: render the latest CV
* Rendercv missing commits (#3475)
Signed-off-by: George Araújo <george.gcac@gmail.com>
* chore: render the latest CV
* Update Google Scholar citations
* Update SASS syntax in base (non-font) files (#3281)
Partially fixes issue #3256 by updating SASS syntax in main SCSS files.
To fully address the issue, FontAwesome should be updated to `v7.x` and
Tabler to `v3.30` or higher (see Tabler fix
[here](https://github.com/tabler/tabler-icons/pull/1256)), where the
SCSS has been fixed.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Improve readme, add site-wide CSP (#3485)
This pull request significantly expands and clarifies the documentation
for the al-folio Jekyll theme, focusing on improved file structure
explanations, enhanced quick reference guides, and the addition of a
comprehensive analytics setup guide. The changes make it easier for
users and contributors to understand the project organization, available
features, and configuration options, especially regarding CV formats,
teaching pages, and analytics integration.
**Key documentation and structure improvements:**
*Expanded file and collection structure:*
- The file structure documentation in
`.github/agents/customize.agent.md` and `.github/agents/docs.agent.md`
now details all major directories, including new and existing
collections such as `_books/`, `_teachings/`, `_scripts/`, `_plugins/`,
and expanded `assets/` subdirectories. It also covers new configuration
and utility files, making it easier for users to locate and understand
the purpose of each file or folder.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L24-R66)
[[2]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L17-R58)
*Documentation and quick reference enhancements:*
- The quick reference table in `.github/agents/customize.agent.md` has
been updated to include new actions like adding teaching pages, setting
up analytics, improving SEO, and ensuring accessibility, with more
precise documentation links.
- The documentation map now lists all major guides (e.g.,
`QUICKSTART.md`, `INSTALL.md`, `TROUBLESHOOTING.md`, `ACCESSIBILITY.md`,
`ANALYTICS.md`, `SEO.md`), providing a clearer overview of available
resources.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L58-R110)
[[2]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L17-R58)
**Feature and configuration documentation updates:**
*CV/resume format guidance:*
- The CV documentation now clarifies that users can maintain both
RenderCV and JSONResume formats simultaneously, with clear instructions
on switching between them and deleting unused files if desired.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L139-R185)
[[2]](diffhunk://#diff-52f2a9488bfe4177d1f1d01120859dad0b3e2d087283ded68f72d47b4f183391L291-R291)
*Teaching pages and new collections:*
- Adds documentation for the new `_teachings/` collection, including
required frontmatter and support for course materials, as well as
updates to enable/disable teaching and books pages via `_config.yml`.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L180-R252)
[[2]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L24-R66)
*Analytics integration:*
- Introduces a new `ANALYTICS.md` guide with detailed setup instructions
for Google Analytics, privacy-friendly alternatives (Plausible, Pirsch,
Openpanel, GoAccess), GDPR considerations, and a comparison table to
help users choose the right analytics provider.
- The configuration documentation now references analytics setup and
related configuration options.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L180-R252)
[[2]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L479-R550)
These updates collectively make the documentation more comprehensive,
actionable, and user-friendly for both new and advanced users.
**References:**
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L24-R66)
[[2]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L58-R110)
[[3]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L139-R185)
[[4]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L180-R252)
[[5]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L479-R550)
[[6]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L17-R58)
[[7]](diffhunk://#diff-0967e840631a541bb95e057e1c6d4884274cf56d5a217d7fee2eb7223b6b4c0dR1-R268)
[[8]](diffhunk://#diff-52f2a9488bfe4177d1f1d01120859dad0b3e2d087283ded68f72d47b4f183391L291-R291)
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Auto update markdown TOC
* Added copilot instructions, AGENTS.md, improved README files (#3486)
This pull request introduces several documentation improvements and adds
comprehensive Copilot and agent instruction files to the al-folio
repository. The most significant changes are the addition of
repository-wide and path-specific Copilot instructions, updates to agent
documentation to reference these instructions, and improvements to the
documentation structure and clarity regarding file purposes and
workflows.
**Copilot and Agent Instruction Enhancements:**
- Added a new `.github/copilot-instructions.md` file providing detailed,
repository-wide setup, build, CI/CD, troubleshooting, and file format
guidance for Copilot coding agents.
- Introduced `.github/instructions/bibtex-bibliography.instructions.md`
with specific instructions for editing and validating BibTeX files,
including custom keywords, formatting rules, and integration with
Jekyll-Scholar.
- Updated agent documentation files (`customize.agent.md`,
`docs.agent.md`) to reference the new Copilot instruction files and
explain their purpose and usage for both repository-wide and
path-specific scenarios.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L57-R65)
[[2]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L107-R122)
[[3]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L49-R51)
[[4]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L106-R137)
**Documentation Structure and Clarity Improvements:**
- Clarified and reorganized the documentation file list in agent files,
removing references to deprecated or merged files (e.g.,
`MAINTENANCE.md`, `ACCESSIBILITY.md`) and updating descriptions to
reflect current usage.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L57-R65)
[[2]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L21-R21)
[[3]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L106-R137)
- Enhanced documentation on the purpose and application of each
documentation file, and added detailed explanations of Copilot
instruction files and their role in project development.
**Workflow and Validation Updates:**
- Updated references and descriptions for GitHub Actions workflows in
agent documentation to include the Copilot environment setup and clarify
pre-commit and CI/CD requirements.
[[1]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L57-R65)
[[2]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L49-R51)
- Corrected references for accessibility guidance, now directing users
to `TROUBLESHOOTING.md` instead of the removed `ACCESSIBILITY.md`.
These changes collectively improve the onboarding experience for both
human contributors and AI agents, ensuring consistent adherence to
project conventions and reducing errors.
**References:**
[[1]](diffhunk://#diff-227c2c26cb2ee0ce0f46a320fc48fbcbdf21801a57f59161b1d0861e8aad55f5R1-R253)
[[2]](diffhunk://#diff-6fd2827fb8d9c2dd6dc973572201853487ecbbd1120b00425d4f1c21dfdcf35fR1-R174)
[[3]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L57-R65)
[[4]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L107-R122)
[[5]](diffhunk://#diff-15864f2655921f50a97689076e3b8feba0da320463750845be6a76eb2e30bfe4L550-R562)
[[6]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L21-R21)
[[7]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L49-R51)
[[8]](diffhunk://#diff-961a46180ce568ce43c20bf7129dc5e4926a9aa4e0d7bc19926ca5ee3ff95cd0L106-R137)
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Auto update markdown TOC
* docs: correct email configuration location in QUICKSTART.md (#3489)
Fixes #3488
Updates `QUICKSTART.md` to correctly point to `_data/socials.yml` for
email configuration, as the `email` field is not present in
`_config.yml`.
* fix(devcontainer): remove broken yarn apt source to fix build (#3490)
This change introduces a Dockerfile to the devcontainer configuration
that removes the broken Yarn repository from `/etc/apt/sources.list.d/`.
This prevents `apt-get update` from failing due to an expired or missing
GPG key for the Yarn repository.
Fixes #3487
* Improve AGENTS.md structure
Removed duplicate quick links for coding agents and customization.
* fix: CV rendering failure without Volunteer field (#3479)
Fixes #3478
* fix tikzjax (#3477)
Fixes #3216 – TikZJax not working.
1. Changing SHA simply doesn't work, `window.tikzjax` is undefined and
it doesn't render anything.
2. I switched to the JS distributed by
[benrbray/tikzjax](https://github.com/benrbray/tikzjax/tree/develop),
added under `assets.js` to prevent future issues.
3. Documents now require to start with `\begin{document}`, should be a
simple fix.
<img width="789" height="341" alt="Screenshot 2026-01-24 at 1 10 39 PM"
src="https://github.com/user-attachments/assets/8272471d-df94-4118-a726-00ed09dcf1e8"
/>
<img width="780" height="380" alt="Screenshot 2026-01-24 at 1 06 13 PM"
src="https://github.com/user-attachments/assets/11284661-de15-4d57-a1d9-4959f562f826"
/>
* Fix #2598, shift to last_modified_at instead of last_updated. (#3493)
Use `last_modified_at` rather than `last_updated`. So that the
jekyll-sitemap plugin automatically looks for the standard
`last_modified_at` front matter field to generate the `<lastmod>` tag in
your `sitemap.xml`.
It fixes [#2598](https://github.com/alshedivat/al-folio/issues/2598)
Also, it preserves backward compatibility, as the updated metadata logic
prioritizes the `page.last_modified_at`, and defaults to
`page.last_updated`.
* Making Gemini and Claude configuration files point to AGENTS.md (#3494)
This pull request updates project documentation to clarify and
standardize the development workflow, Git practices, and troubleshooting
resources. The main changes include adding a dedicated Git workflow
guide and reorganizing the `AGENTS.md` file for better clarity and
usability.
**Documentation and Workflow Improvements:**
* Added a new `.github/GIT_WORKFLOW.md` file detailing commit message
conventions, types, and best practices for staging and ignoring files.
* Reorganized and clarified the pre-commit checklist and local
development instructions in `AGENTS.md`, emphasizing Docker usage and
proper code formatting.
* Updated the section on configuration and troubleshooting in
`AGENTS.md` to better direct users to relevant resources and removed
redundant or outdated instructions.
[[1]](diffhunk://#diff-a54ff182c7e8acf56acfd6e4b9c3ff41e2c41a31c9b211b2deb9df75d9a478f9L57-R58)
[[2]](diffhunk://#diff-a54ff182c7e8acf56acfd6e4b9c3ff41e2c41a31c9b211b2deb9df75d9a478f9L100-R74)
**Configuration and Context Updates:**
* Added a `.gemini/settings.json` file to define context files for
Gemini agent operations, ensuring relevant documentation is available
for automation tools.
* Created `CLAUDE.md` file pointing to `AGENTS.md`.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Enhance documentation for GitHub Copilot agents
Added CLAUDE.md file for AI assistant integration and updated Copilot agents description.
* Fix Gemini settings
* Added information about creating custom metadata for collections
* Update Google Scholar citations
* Add GDPR-compliant cookie consent with analytics blocking (#3492)
Implements cookie consent using vanilla-cookieconsent v3 to comply with
GDPR requirements. Analytics scripts are blocked until user consent is
obtained.
## Changes
**Library Integration**
- Added `vanilla-cookieconsent@3.1.0` to `_config.yml` third-party
libraries with SRI hashes
- Created `_scripts/cookie-consent-setup.js` with consent modal and
settings configuration
- Added CSS/JS includes in `_includes/head.liquid` and
`_includes/scripts.liquid`
**Analytics Blocking**
- Modified analytics scripts in `scripts.liquid` and
`distill_scripts.liquid` to use conditional `type="text/plain"
data-category="analytics"` when consent is disabled
- Blocks Google Analytics, Cronitor, Pirsch, and OpenPanel until consent
granted
- Library automatically converts blocked scripts to executable on user
acceptance
**Configuration**
- Added `enable_cookie_consent` flag (default: `false`)
- Cookie categories: `necessary` (always on), `analytics` (optional)
- 182-day cookie expiration, auto-clear on rejection
## Implementation
```liquid
{% if site.enable_cookie_consent %}
<script type="text/plain" data-category="analytics" async src="...gtag.js"></script>
{% else %}
<script async src="...gtag.js"></script>
{% endif %}
```
Enable in `_config.yml`:
```yaml
enable_cookie_consent: true
```
## Screenshots
**Consent Modal**

**Settings Modal**

> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `cdn.jsdelivr.net`
> - Triggering command: `/usr/bin/curl curl -s REDACTED` (dns block)
> - `cookieconsent.orestbida.com`
> - Triggering command:
`/home/REDACTED/work/_temp/ghcca-node/node/bin/node
/home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps
/home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js`
(dns block)
> - `medium.com`
> - Triggering command: `/usr/local/bin/ruby ruby
/usr/local/bundle/bin/bundle exec jekyll serve --watch --port=8080
--host=0.0.0.0 --livereload --verbose --trace --force_polling s
6_64-linux /etc/locale.gen by/backward -binutils_2.44-3grep .deb eb
/systemd-sysctl` (dns block)
> - `publish.twitter.com`
> - Triggering command: `/usr/local/bin/ruby ruby
/usr/local/bundle/bin/bundle exec jekyll serve --watch --port=8080
--host=0.0.0.0 --livereload --verbose --trace --force_polling lude��
lude/ruby-4.0.0//run/containerd/io.containerd.runtime.v2.task/moby/a4760212ce4eda97e32b6dfa4d3ea/usr/sbin/iptables
r/runc-log.json f8_range lude r-strong E r/wc7in709a54d7hshow` (dns
block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/alshedivat/al-folio/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>GDPR compliant cookie consent dialog</issue_title>
> <issue_description>Hi,
>
> since I am from Europe and want my site to be accessed by EU citizens
I need to ask users if they are ok with the use of cookies. Adding a
dialogue by default that that asks the user before any cookies /
localStorage are used would be nice.
>
> I have integrated the dialog from
[https://www.cookieconsent.com/](https://www.cookieconsent.com/) on [my
website](http://hschwane.github.io) and am happy to file a PR if you are
interested. However It is not shown directly at the top, but below the
menu bar for some reason. Not sure how to fix that.
> </issue_description>
>
> <agent_instructions>Implement this using cookie consent dialog from
https://github.com/orestbida/cookieconsent. The documentation is
available at
https://cookieconsent.orestbida.com/essential/getting-started.html.</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> <comment_new><author>@alshedivat</author><body>
> @hschwane, thanks for pointing this out. It's would be great if you
could send a PR.
>
> To answer your question about positioning, the menu bar has the
absolute position at the top of the page and keeps moving with
scrolling. You can change that behavior in `_config.yml` by setting
`navbar_fixed: false` (see [line
27](https://github.com/alshedivat/al-folio/blob/master/_config.yml#L27)).
If you send a PR with basic functionality, I can help with adjusting the
styles a bit. Thanks!</body></comment_new>
> <comment_new><author>@alshedivat</author><body>
> Just catching up on this discussion.
>
> @hschwane, thanks for providing an implementation based on
`ihavecookies`! I looked through alshedivat/al-folio#223. It seems like
to be able to correctly (un)block different types of cookies (all of
which are third-party cookies) requires adding quite a bit of extra
JavaScript (including adding it directly to posts or pages in some
cases, e.g., when posts embed youtube videos or other external content).
This approach will put some extra burden on contributors and maintainers
of al-folio down the line.
>
> By the way, the dialog from https://www.cookieconsent.com/ is similar
in that sense as it requires to manually add ALL scripts that use
cookies. So, if someone contributes a new feature to al-folio that uses
cookies, the contributor would have to go and update the cookie consent
dialog as well (or edit quite a bit of JS if `ihavecookies` is used).
>
> Thinking about this more, I currently see only three options:
> 1. If we want to have cookie consent as a core part of al-folio (which
can be easily enabled or disabled), it needs to be a service that
automatically identifies and blocks cookies, without putting an extra
burden on the contributors or maintainers. The hosted version of [Cookie
Consent by Osano](https://www.osano.com/features/consent-management) is
an example.
> 2. Another option is to provide a very minimalistic cookie consent
dialog which simply says that the website uses cookies, without an
option to opt-in or opt-out (e.g., see the open-source edition of
[Osano](https://www.osano.com/cookieconsent/download/)).
> 3. Finally, not have cookie consent as part of al-folio, and make the
user responsible for figuring out whether they need a consent dialog and
which service to use.
>
> Let me know what you think.</body></comment_new>
> <comment_new><author>@alshedivat</author><body>
> the best way to add GDPR compliant cookie consent is using
https://github.com/orestbida/cookieconsent</body></comment_new>
> </comments>
>
</details>
> **Custom agent used: customization_agent**
> Expert customization assistant for the al-folio Jekyll academic
website template
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes alshedivat/al-folio#199
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/alshedivat/al-folio/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Signed-off-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: george-gca <31376482+george-gca@users.noreply.github.com>
Co-authored-by: George Araújo <george.gcac@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Auto update markdown TOC
* Improve explanation of create from this template (#3499)
This pull request improves the documentation to clarify the recommended
way to create a new site using the al-folio template, emphasizing the
use of the "Use this template" button instead of forking. It explains
the differences between the two approaches, highlights common pitfalls
with forking, and provides guidance for users who have already forked
the repository.
Documentation improvements regarding repository creation:
* Added a prominent section in `README.md` explaining why "Use this
template" is preferred over forking, including step-by-step instructions
and advice for users who have already forked.
* Updated `QUICKSTART.md` to strongly recommend using the "Use this
template" button, clarified the steps for creating a new repository, and
included tips for users who have already forked by mistake.
* Added a new section in `INSTALL.md` detailing the differences between
using the template and forking, common pitfalls, and best practices for
contributing.
Signed-off-by: George Araújo <george.gcac@gmail.com>
* Auto update markdown TOC
* Update Google Scholar citations
* Added new research blog in README.md (#3522)
* Update Google Scholar citations
* Add link to personal page (laura wagner) in README (#3552)
Adding my personal academic website to the academics list
* Add Fukushima Lab to User community (Labs) (#3559)
This PR adds Fukushima Lab to the **User community** section in
`README.md` under **Labs**. Thank you for maintaining such a great and
inspiring website template.
Added link:
- https://kenji-fukushima-lab.github.io/
Co-authored-by: Kenji Fukushima <kf@MacBookPro.elecom>
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* add vud.org to community list (#3575)
Add vud.org to community list.
* Added website of B. Choi (Update README.md) (#3569)
Hello, please add my academic website to the community page. Thank you
for maintaining this project.
* [Update] add workshop to README.md (#3585)
Add new workshop to README.md
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Add pranavraj575 website to README
* Add deden.id website to README
Please let my website be on the growing list! I'm Deden Habibi Ali
Alfathimy, a researcher in outer space politics, with personal website
https://deden.id using al-folio.
* Upgrade al-folio to v1.0 (#2968)
## Overview
This PR delivers the `v1.0` architecture and runtime upgrade for
`al-folio`.
`al-folio` moves from a monolithic theme repo to a **thin starter +
plugin ecosystem** model, while preserving visual identity and core
behavior.
## What this PR changes
### 1) Starter becomes orchestration-only
`al-folio` is now responsible for:
- starter wiring (`Gemfile`, `_config.yml`)
- sample/demo content
- user-facing docs
- visual regression and cross-plugin integration tests
Component/runtime ownership is moved to dedicated gems.
### 2) Runtime and feature ownership split into plugins
`al_folio_core` now provides shared runtime/layout primitives and
contracts, and delegates feature modules to owning gems.
Key plugin ownership in v1:
- `al_folio_core`: core theme runtime/contracts
- `al_folio_distill`: Distill layouts/runtime
- `al_folio_cv`: CV rendering
- `al_search`: search runtime and modal behavior
- `al_icons`: icon runtime (Font Awesome, Academicons, Scholar Icons)
- `al_cookie`: cookie-consent runtime
- `al_img_tools`: image/gallery/lightbox tooling
- `al_math`: math/TikZ runtime integration
- additional `al-*` plugins for
analytics/charts/citations/comments/newsletter/external posts/upgrade
tooling
### 3) Styling/runtime modernization
- Tailwind-first v1 runtime is established.
- Legacy Bootstrap behavior is isolated behind optional
`al_folio_bootstrap_compat` for migration windows.
- jQuery-dependent runtime paths are removed/replaced in plugin-owned
implementations.
### 4) Test ownership policy is enforced
- `al-folio` keeps only starter-level integration and visual integrity
checks.
- Component correctness tests are owned by the corresponding plugin
repos.
This mirrors runtime ownership and reduces duplication/drift.
### 5) Upgrade and migration workflow
`al_folio_upgrade` is integrated for audit/apply/report migration flows,
including:
- config contract checks
- ownership drift detection
- local override drift audit/diff/acknowledgement workflow
- legacy marker detection
- plugin wiring validation
### 6) Documentation and contributor model for v1
Docs are updated to reflect modular v1 behavior and contribution
routing.
New governance additions include:
- plugin ownership/boundary guidance (`docs/BOUNDARIES.md`)
- plugin naming convention (theme-coupled vs reusable plugin tracks)
- featured-vs-bundled plugin distinction
- plugin catalog source + page (`_data/featured_plugins.yml`,
`_pages/plugins.md`)
- plugin feature proposal issue template
- PR template updates for ownership routing
- agent-facing setup and migration skills
## Compatibility and migration notes
- Plugin integration in starter is via `Gemfile` + `_config.yml`.
- `al-folio` starter intentionally does not use a gemspec in v1.
- Transitional Bootstrap compatibility remains available via
`al_folio_bootstrap_compat`.
- Existing front-matter contracts are preserved where possible; runtime
implementations are now plugin-owned.
- Customized sites can track local override drift with `bundle exec
al-folio upgrade overrides audit` and `.al-folio-overrides.yml`.
## Validation strategy in this PR
- visual parity checks against the v0.16.3 baseline
- starter integration suites (comments, plugin toggles, distill, compat,
upgrade CLI)
- style contract checks and repository linting
## Scope intent
This is the foundational v1 architecture PR.
Post-merge feature work should generally target owning plugin repos
first, with `al-folio` limited to starter wiring, docs, examples, and
integration/visual validation.
_Written by Codex on behalf of @alshedivat._
* Fix broken navbar: stop double-minifying Tailwind CSS in production (#3634)
## Summary
Fixes the broken navigation bar on the live demo
(https://alshedivat.github.io/al-folio/) introduced by the v1.0 upgrade
(#2968), plus two related production/deploy-only issues found while
auditing for the same class of bug.
## Root cause of the navbar break
The v1.0 upgrade made the site **Tailwind-first**. The deploy builds
with `JEKYLL_ENV=production`, which activates **jekyll-minifier**. Its
CSS compressor (`cssminify2`) mangles Tailwind v4 spacing tokens
**inside `calc()`**:
```
calc(var(--spacing)*0) -> calc(var( - - spacing)*0) // invalid
```
`cssminify2` treats the `--` inside `calc(var(--…))` as minus operators
and inserts spaces, producing an invalid custom-property name. This
silently breaks **every** spacing/positioning utility — most visibly
`.fixed-top`, so the fixed navbar is no longer pinned (`top/left/right`
drop out) and renders incorrectly. On the live site this affects 33
`var(--spacing)` references in `tailwind.css`.
It only manifests in **production**: a local `bundle exec jekyll serve`
is development mode (minifier off), and the `visual-regression` workflow
also serves in dev mode — so neither caught it.
### Why this fix
`tailwind.css` is already minified by al_folio_core's Tailwind build,
and `main.css` is compiled by Sass with `style: compressed`.
Re-minifying them with `cssminify2` adds nothing (it actually makes
`tailwind.css` ~315 bytes **larger**) and only introduces this
corruption. So we disable redundant CSS minification, mirroring the
existing `compress_javascript: false` (terser handles JS).
Verified end-to-end:
- The gem source `tailwind.css` has 82 intact `var(--spacing)`;
`cssminify2` corrupts all 82.
- jekyll-minifier (`lib/jekyll-minifier.rb:1061`): `return
output_file(path, content) unless config.compress_css?` — with
`compress_css: false`, `.css` files are written verbatim.
- A real `JEKYLL_ENV=production` build now emits `tailwind.css` with 82
intact `var(--spacing)`, 0 corrupted, and
`.fixed-top{...;position:fixed}` intact.
- PurgeCSS (the next deploy stage) preserves `calc(var(--spacing)*0)`
unchanged.
## Changes
1. **`_config.yml` — `jekyll-minifier.compress_css: false`** (the navbar
fix).
2. **`test/integration_css_minify.sh` + `unit-tests.yml`** — a
regression test that builds in **production mode** (the mode that
exposes this bug class) and asserts no `var( - - )` corruption, intact
`var(--spacing)`, a valid `.fixed-top`, and a non-empty `main.css`.
Passes with the fix; fails without it (83 corruptions). Closes the CI
blind spot that let this ship.
3. **`_config.yml` — drop dead `jekyll-minifier` exclude**
`assets/js/search/*.js`. That is a v0 path; in v1 the search runtime
ships under `assets/al_search/js/...`, so the glob matched nothing.
4. **`purgecss.config.js` — safelist `medium-zoom-overlay` /
`medium-zoom-image--opened`.** These classes are injected at runtime, so
they never appear in the static HTML PurgeCSS scans; their `z-index:999`
overlay rule was being purged on the deployed site, letting the
scroll-progress bar / ToC bleed through a zoomed image. Verified: the
rule survives purge with the safelist and is dropped without it.
## Broader audit — plugin fixes (released + pinned here)
I audited for the same bug class (regressions invisible to dev-mode
builds / leftovers from the v1 jQuery removal). The confirmed
plugin-owned issues were each fixed in their own repo, merged after
green CI, released to RubyGems, and pinned in this PR's `Gemfile`:
- **al_folio_core 1.0.10**
([#18](https://github.com/al-org-dev/al-folio-core/pull/18)) —
`main.css` cache-bust was permanently the empty-string MD5
(`bust_css_cache` globbed a non-existent `assets/_sass`) → stale CSS
after deploys; `bib.liquid` "N more authors" used `$(this)` → threw and
never expanded; `figure.liquid` `onerror` used `$()` → dead broken-image
fallback.
- **al_charts 1.0.1**
([#7](https://github.com/al-org-dev/al-charts/pull/7)) —
`chartjs-setup.js` was jQuery → `chartjs` charts threw `$ is not
defined` and never rendered.
- **al_folio_distill 1.0.2**
([#2](https://github.com/al-org-dev/al-folio-distill/pull/2)) —
`overrides.js` top-level `$(window).on("load")` → distill
footnote/citation theming never applied + console error.
Verified end-to-end with a production build after the pin bumps:
`main.css` now cache-busts to a real hash (`9278fad1…`, not
`d41d8cd9…`), zero jQuery `$(` in the built HTML, and the Tailwind
spacing utilities / `.fixed-top` navbar are intact.
Also noted (not fixed here): the `visual-regression` workflow only
renders in dev mode, so it can't catch production-only CSS regressions —
`test/integration_css_minify.sh` is the immediate guard; a production
screenshot leg would be a fuller backstop.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: expand CLAUDE.md with the v1 plugin-ecosystem architecture (#3635)
## Summary
Expands `CLAUDE.md` from a bare `@AGENTS.md` import into a useful entry
point for coding agents, while **keeping** that import so `AGENTS.md`'s
ownership boundaries, validated command set, and PR-routing rules still
flow in (and stay the short, ecosystem-neutral shared file).
The added content is the cross-repo "big picture" that no single file in
this repo currently documents — gathered by reading the starter
internals plus all 16 `al-*` / `al_folio_*` plugin gems:
- **al_folio_core hub + delegation map** — a `wrapper → tag → gem` table
for every bundled plugin, so a runtime change can be routed to the
owning repo in one lookup.
- **Sibling-repos-on-disk** layout and how to point the `Gemfile` at a
local gem checkout (`path:`) to test a gem fix against the site.
- **Cross-repo invariants** — two-layer feature gating (config flag
*and* front matter), `AssetsGenerator` build-time asset injection, the
`Gemfile` ↔ `_config.yml` plugin-list sync, the v1 config contract
(enforced by core's `:after_init` and `al-folio upgrade audit`),
`.al-folio-overrides.yml` drift tracking, and the time-boxed
bootstrap-compat path.
- **Daily dev loop** that `AGENTS.md` omits (`jekyll serve`, single
integration test, snapshot refresh, upgrade subcommands).
- The v1 Docker `/tmp/_site` rationale and the `style_contract.js`
boundary that fails CI if runtime/build files leak into the starter.
Every specific claim (gem versions, tag names, config keys) is grounded
in the actual repos. Prettier-clean.
> Split out from the navbar-fix PR (#3634) per request; this PR is
docs-only and independent.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix links (#3628)
## Summary
In the "User community" README section several links didn't work
anymore. I updated them where I was able to find a new link from the
same person, and removed the ones where I didn't find a new link.
## Ownership Routing
- [x] I confirmed this PR targets the correct repo based on
`docs/BOUNDARIES.md`.
- [x] This PR only changes starter-owned scope (`al-folio`) **or** I am
porting a routed change and linked the owning repo issue/PR.
## Plugin Ecosystem (if applicable)
- [x] Not applicable
- [ ] This PR proposes a plugin for **featured-only** listing.
- [ ] This PR proposes a plugin for **bundled** starter inclusion.
## Starter Wiring Changes
- [x] Not applicable
- [ ] Updated `Gemfile` dependency wiring.
- [ ] Updated `_config.yml` plugin activation/config.
- [ ] Updated `_data/featured_plugins.yml` metadata.
## Validation
- [x] `npm ci`
- [ ] `bundle exec jekyll build`
- [x] `npm run lint:prettier`
- [x] `npm run lint:style-contract`
- [ ] Integration tests (`test/integration_*.sh`) as needed
- [ ] Visual tests (`npm run test:visual`) as needed
* Fix visual regressions: broken repo stat cards and unstyled af-popover/tooltip (#3636)
## What's broken on the demo site
A full-page screenshot audit of every page on
https://alshedivat.github.io/al-folio/ surfaced two user-visible bugs
introduced or exposed by the v1 upgrade.
### Bug 1 — Repositories page: all stat cards show broken alt-text
(HIGH)
Both external services are currently unavailable:
- `github-readme-stats.vercel.app` → HTTP 503 `DEPLOYMENT_PAUSED`
- `github-profile-trophy.vercel.app` → HTTP 402
Every `<img>` on the repositories page fails to load, rendering as a
list of broken-image alt-text strings. The templates had no `onerror`
fallback.
**Fix (in al_folio_core):**
`onerror="this.closest('.repo').style.display='none'"` on every
stat-card image in `repo.liquid`, `repo_user.liquid`, and
`repo_trophies.liquid`. When a service is unavailable the entire card
hides gracefully; when it comes back up cards render normally.
### Bug 2 — `.af-popover` / `.af-tooltip` completely unstyled (MEDIUM)
`tooltips-setup.js` (active by default, since bootstrap-compat is
disabled) creates `.af-popover` and `.af-tooltip` elements as its
vanilla fallback — for example when hovering the author-info circle icon
(ⓘ) on the publications page. These class names had **no CSS rules at
all** in `al_folio_core`: no `position`, no styling, no `z-index`. The
tooltip/popover appeared as invisible, unpositioned text nodes appended
to `document.body`.
(The theme's `_utilities.scss` only defined `.popover` — Bootstrap's
class — which is irrelevant without bootstrap-compat loaded.)
**Fix (in al_folio_core):** Added `position: absolute`, `z-index:
1070/1080`, and theme-color styling to both classes. The purgecss
safelist in al-folio already protects both names so they survive the
deploy pipeline.
## Changes
- `Gemfile` / `Gemfile.lock`: bump `al_folio_core` 1.0.10 → 1.0.11 ([PR
#19](https://github.com/al-org-dev/al-folio-core/pull/19), now merged
and released)
## Scope
All other pages screenshotted look correct. No other CSS/layout
regressions were found beyond these two. The screenshot audit also
confirmed:
- The `var(--spacing)` Tailwind fix from #3634 is working correctly in
production.
- `main.css` cache-bust hash (`9278fad1…`) is stable and non-empty.
- All blog posts, CV, teaching, people, projects, books pages render as
expected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Add a link to my lab website in user community section (#3645)
Add a link to my lab website in the user community of README.
## Summary
Many thanks to the authors and contributors of this repo. I'm glad to
add my lab's website in the user community section of README.
## Ownership Routing
- [x] I confirmed this PR targets the correct repo based on
`docs/BOUNDARIES.md`.
- [ ] This PR only changes starter-owned scope (`al-folio`) **or** I am
porting a routed change and linked the owning repo issue/PR.
Owning repo (if not starter): <!-- e.g., al-org-dev/al-folio-core -->
Related issue/PR: <!-- link -->
## Plugin Ecosystem (if applicable)
- [x] Not applicable
- [ ] This PR proposes a plugin for **featured-only** listing.
- [ ] This PR proposes a plugin for **bundled** starter inclusion.
If plugin-related, provide:
- Plugin repo URL:
- Gem name:
- Jekyll plugin id:
- Compatibility (`al_folio_min`/`al_folio_max`):
- Demo page/post path:
- Maintainer contact:
## Starter Wiring Changes
- [x] Not applicable
- [ ] Updated `Gemfile` dependency wiring.
- [ ] Updated `_config.yml` plugin activation/config.
- [ ] Updated `_data/featured_plugins.yml` metadata.
## Validation
- [ ] `npm ci`
- [ ] `bundle exec jekyll build`
- [ ] `npm run lint:prettier`
- [ ] `npm run lint:style-contract`
- [ ] Integration tests (`test/integration_*.sh`) as needed
- [ ] Visual tests (`npm run test:visual`) as needed
## Notes
Compatibility, migration implications, and follow-ups:
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Update Google Scholar citations
* Bump nokogiri from 1.19.3 to 1.19.4 (#3653)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.19.3
to 1.19.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/sparklemotion/nokogiri/releases">nokogiri's
releases</a>.</em></p>
<blockquote>
<h2>v1.19.4 / 2026-06-18</h2>
<h3>Security</h3>
<ul>
<li>[CRuby] (Low) Fixed a possible invalid memory read when
<code>XML::Node#initialize_copy_with_args</code> is called with an
argument that is not a <code>Node</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-g9g8-vgvw-g3vf">GHSA-g9g8-vgvw-g3vf</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when an
<code>XML::XPathContext</code> is used after its source document has
been garbage collected. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-p67v-3w7g-wjg7">GHSA-p67v-3w7g-wjg7</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free during XInclude
processing via <code>Node#do_xinclude</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wfpw-mmfh-qq69">GHSA-wfpw-mmfh-qq69</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when
<code>Document#root=</code> is assigned a non-element node. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wjv4-x9w8-wm3h">GHSA-wjv4-x9w8-wm3h</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when setting an
attribute value via <code>XML::Attr#value=</code> or
<code>#content=</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-phwj-rprq-35pp">GHSA-phwj-rprq-35pp</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a null pointer dereference when methods are
called on uninitialized wrapper objects (e.g. via
<code>allocate</code>); these now raise instead of crashing the process.
See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-9cv2-cfxc-v4v2">GHSA-9cv2-cfxc-v4v2</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when
<code>Document#encoding=</code> raises an exception. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5v8h-3h3q-446p">GHSA-5v8h-3h3q-446p</a>
for more information.</li>
<li>[CRuby] (Medium) Fixed an out-of-bounds read in
<code>XML::NodeSet#[]</code> (alias <code>#slice</code>) when given a
large negative index. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5prr-v3j2-97mh">GHSA-5prr-v3j2-97mh</a>
for more information.</li>
<li>[JRuby] (Low) <code>XML::Schema</code> now enforces the
<code>NONET</code> parse option, which Nokogiri enables by default. It
was not enforced on JRuby, so a schema parsed with default options could
still fetch external resources over the network, potentially enabling
SSRF or XXE attacks and bypassing the mitigation for CVE-2020-26247. See
<a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-8678-w3jw-xfc2">GHSA-8678-w3jw-xfc2</a>
for more information.</li>
</ul>
<!-- raw HTML omitted -->
<pre><code>1269fb644a6de405057a53dd5c762b1209b43ca7424f839454d3dbc677c31a8f
nokogiri-1.19.4-aarch64-linux-gnu.gem
35c65b9ce72b3bb03207bdbe7067915019dc18c1b9b59139684bd6690fdd01af
nokogiri-1.19.4-aarch64-linux-musl.gem
a301313e38bb065d68239e79734bcd6f56fb6efaacebde29e9abf2a4735340ca
nokogiri-1.19.4-arm-linux-gnu.gem
588923c101bcfa78869734d247d25b598674323e7f22474fc468f6e5647311eb
nokogiri-1.19.4-arm-linux-musl.gem
a46db9853286e6597b36ebc6953817d15acf3a299583eb3f89fdc6f91dd63527
nokogiri-1.19.4-arm64-darwin.gem
ce04b9e268c9626852231a48b49128ed52034f1ccb39484a6da3875491cd709e
nokogiri-1.19.4-java.gem
051da97b8eccfdb5444fed40246a35e10d7298b9efe759b4cd25455ea04c587e
nokogiri-1.19.4-x64-mingw-ucrt.gem
7fd17057d3e1f00e9954a74b3cd76595d3d4a5ef233b7ed9599047c204f70551
nokogiri-1.19.4-x86_64-darwin.gem
379fae440b28915e3f19d752ce2dcf8465ed2b2fbefd2a7ca0dd497bc981a06a
nokogiri-1.19.4-x86_64-linux-gnu.gem
17dfb7c1fa194ae02fbf7c51a7afc8d278045ab3fdacfd86f91d02d7b274470b
nokogiri-1.19.4-x86_64-linux-musl.gem
50c951611c92bca05c51411aef45f1cbc50f2821c4802758c5c6d34696533ab5
nokogiri-1.19.4.gem
</code></pre>
<!-- raw HTML omitted -->
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md">nokogiri's
changelog</a>.</em></p>
<blockquote>
<h2>v1.19.4 / 2026-06-18</h2>
<h3>Security</h3>
<ul>
<li>[CRuby] (Low) Fixed a possible invalid memory read when
<code>XML::Node#initialize_copy_with_args</code> is called with an
argument that is not a <code>Node</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-g9g8-vgvw-g3vf">GHSA-g9g8-vgvw-g3vf</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when an
<code>XML::XPathContext</code> is used after its source document has
been garbage collected. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-p67v-3w7g-wjg7">GHSA-p67v-3w7g-wjg7</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free during XInclude
processing via <code>Node#do_xinclude</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wfpw-mmfh-qq69">GHSA-wfpw-mmfh-qq69</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when
<code>Document#root=</code> is assigned a non-element node. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-wjv4-x9w8-wm3h">GHSA-wjv4-x9w8-wm3h</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when setting an
attribute value via <code>XML::Attr#value=</code> or
<code>#content=</code>. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-phwj-rprq-35pp">GHSA-phwj-rprq-35pp</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a null pointer dereference when methods are
called on uninitialized wrapper objects (e.g. via
<code>allocate</code>); these now raise instead of crashing the process.
See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-9cv2-cfxc-v4v2">GHSA-9cv2-cfxc-v4v2</a>
for more information.</li>
<li>[CRuby] (Low) Fixed a possible use-after-free when
<code>Document#encoding=</code> raises an exception. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5v8h-3h3q-446p">GHSA-5v8h-3h3q-446p</a>
for more information.</li>
<li>[CRuby] (Medium) Fixed an out-of-bounds read in
<code>XML::NodeSet#[]</code> (alias <code>#slice</code>) when given a
large negative index. See <a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-5prr-v3j2-97mh">GHSA-5prr-v3j2-97mh</a>
for more information.</li>
<li>[JRuby] (Low) <code>XML::Schema</code> now enforces the
<code>NONET</code> parse option, which Nokogiri enables by default. It
was not enforced on JRuby, so a schema parsed with default options could
still fetch external resources over the network, potentially enabling
SSRF or XXE attacks and bypassing the mitigation for CVE-2020-26247. See
<a
href="https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-8678-w3jw-xfc2">GHSA-8678-w3jw-xfc2</a>
for more information.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/sparklemotion/nokogiri/commit/8cfb9daae9ee4a0837508eab43c40fbc8c4138c9"><code>8cfb9da</code></a>
version bump to v1.19.4</li>
<li><a
href="https://github.com/sparklemotion/nokogiri/commit/a856d1e46bda04ef47a0bd2b9eefe86df1eb0bb2"><code>a856d1e</code></a>
fix: JRuby NONET bypass in XML::Schema (v1.19.x) (<a
href="https://redirect.github.com/sparklemotion/nokogiri/issues/3639">#3639</a>)</li>
<li><a
href="https://github.com/sparklemotion/nokogiri/commit/6a0aa1e7042ea58e10db713…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What this is
Updates the site to al-folio v1.1.
Heads-up on scope: this is not a version bump. This fork was last synced against a
pre-v1.0 al-folio, from the era when layouts, includes and styles lived in this
repo. al-folio v1.x moved all of that into a family of gems (
al_folio_coreplusal_*plugins), so getting to v1.1 means going through the v0 → v1 architecturemigration. The v1.1 release notes assume you are already on v1.0 and only need to
bump
Gemfilepins — that path does not apply to us.Merged from upstream tag
v1.1(119 commits). 290 files changed, mostly deletions:the local theme is gone and comes from gems now.
Why now
v1.1 is a security release. Three fixes we currently do not have:
al_img_tools1.0.3polyfill.ioremoved from the MathJax path (June 2024 supply-chain takeover)al_math1.0.2al_folio_distill1.0.3al_folio.distill.allow_remote_loaderis set tofalse, which is what actuallyopts us into the Distill hardening.
Overrides we keep
In v1.x a local file at a gem-owned path acts as an override. We had 14 customised
theme files; 8 survive as real overrides, the rest turned out to be unnecessary.
_includes/figure.liquidstylethrough_includes/footer.liquidal_analyticsships Google/Cloudflare/Simple/Openpanel/Pirsch, but no Umami provider_includes/header.liquidsite.logo.*_includes/repository/repo.liquidshow_owner=false; our repos span three orgs and we keepgithub_usersunset so the "GitHub users" block on/code/stays hidden_layouts/about.liquid_layouts/bib.liquidpublications/preview dir, DOI button suppressed_layouts/page.liquidassets/css/main.scss@use "custom"Each was rebased onto the v1 gem version of the file rather than carried over
verbatim, so we are not shipping pre-v1 markup against v1 CSS.
Overrides we dropped
_includes/repository/repo_user.liquidexternal_services.github_readme_stats_url), and v1's defaultgithub-stats-extendedis the maintained fork — the old public instance is why the cards had been blank_includes/social.liquid(7.6 KB)linkedin_companycustom entry in_data/socials.yml.jekyll-socialshard-codeslinkedin_username→/in/<user>, but it renders unknown keys straight fromurl/title/logo, which gives us the company URL and thelinkedin-inicon with no template override_sass/_base.scss,_sass/_themes.scss_sass/_custom.scss, including the.theme-aware-logorules. The obsolete#light-toggle-*rules are gone — v1 renders the tri-state theme toggle itselfBootstrap utilities v1 dropped
Pre-v1 al-folio loaded
bootstrap.min.cssandmdb.min.cssfrom a CDN. v1dropped both for
al_folio_core's Tailwind layer, which reimplements many of thesame class names — some with different semantics. Two visual regressions came
out of this and are fixed in
_sass/_custom.scss:Home page logo. The hero logo comes from the org profile README, pulled in by
{% remote_include %}in_pages/about.md, as<img src="assets/img/cd/…svg" class="img-fluid theme-aware-logo">. Thatsrcisrelative to that repo and 404s here — the image is only ever visible because
.theme-aware-logo { content: url(…) }swaps in a local wordmark. Because the classlives in a remote file, grepping this repo for it finds nothing, so an earlier pass
of this branch mistook it for dead CSS and dropped it. Restored for dark, light and
system.
Team page rendered as boxed cards.
_includes/team_member.liquidis writtenagainst Bootstrap 4 + MDB:
.h-100height: 100%.card.card-body.p-2→ 8px1.25remoutranks.p-2.card-titlePinned to the pre-migration computed values under a new
.team-memberhook. Thoseutility names appear nowhere else in the repo.
Also restored site-wide, at the values Bootstrap 4 served, because neither
al_folio_corenor the compat gem ships them:.text-muted(51 uses),.bg-transparent,.border-0, and the.row-cols-*family — the team grid needsrow-cols-lg-5for its 5-across layout.Verified against the live site with matching computed styles: card background
transparent, no shadow,
card-title20px/400,card-body8px padding, columnsflex: 0 0 20%,text-muted#6c757d, and the logo resolving to the whitewordmark in dark/system and black in light.
Other changes
_pages/code.mdpassesrepository=repo.id— our_data/repositories.ymluses theobject form, and fixing the caller beats overriding the gem include.
feedjiraandhttpartydropped: unused._plugins/github-profile-readme.rbusesstdlib
open-uri._books/,3_project.md) stays deleted.teachingcollection stays singular. Upstream renamed it toteachingsin v1,but renaming would change every
/teaching/...URL, so it is kept deliberately —there is a comment in
_config.ymlsaying so.compat.bootstrap.enabledstaysfalse: our content leans on Bootstrap classesheavily (105×
z-depth-1, 76×row, 41×col-sm-10), butal_folio_core'sTailwind layer already defines them, so the compat gem is not needed.
secrets.PAT || github.tokenfallback.Verification
Built in Docker on
ruby:3.3(3.3.12) — local Ruby here is 2.6, the site needs 3.3.bundle exec jekyll build— clean, 25.9sbundle exec al-folio upgrade audit— 0 blocking, 9 non-blocking (8 were theunacknowledged overrides, now recorded in
.al-folio-overrides.yml; the 9th isbelow)
al_img_tools 1.0.3,al_math 1.0.2,al_folio_distill 1.0.3,al_folio_core 1.0.12. Swiper resolves to 12.1.2with matching SRI hashes.
Checked in the generated HTML: navbar wordmark renders, LinkedIn points at the
company page with the
linkedin-inicon and no/in/URL survives anywhere,repository cards use
github-stats-extendedwithshow_owner=false, publicationpreviews resolve from
assets/img/publications/, the Umami beacon is present,team-profile-contentis applied, and nopolyfill.ioreference remains.Three things the verification turned up, all fixed in the second commit:
altrendered "Sustainable Urban Systems Lab Urban Systems Lab" — thefilter chain appended the name parts even when
site.titlewas set. Pre-existingbug, fixed since the file was being rewritten anyway.
test/harness in the starter but does not exclude it, so thePlaywright specs and shell scripts were being published to the live site. Added
to
exclude:.legacy_data_toggleat_layouts/bib.liquid:142.al_folio_core's ownbib.liquidhas the identicaldata-toggle="popover"at the same line — the audit only flags ours becauseoverriding the file brings it into the scanned tree. Left as-is so future diffs
against upstream stay clean.
What still needs a human
The build passing does not mean it looks right. Worth clicking through before merge:
/publications/— preview images resolve fromassets/img/publications/, DOI buttons still suppressed, altmetric/dimensions badges/team/and an individual member page — portrait float + clearfix, GitHub README embed/code/— repository cards actually render (they were blank on the old stats host)/teaching/— the singular collection still resolves.fa-half-sun-mooninstead of the old Tabler iconOne deliberate visual change: the search button now shows v1's
ctrl khint and aFont Awesome magnifying glass, where we previously showed a bare Tabler icon. v1
dropped Tabler; keeping it would have meant a larger override for no functional gain.
Easy to revert in
_includes/header.liquidif you dislike it.Follow-ups, not in this PR
_layouts/profiles_new.liquidis dead — no page references it._teaching/gt-arch-6242.mdhand-writes<swiper-container>markup, but nothingloads Swiper on that page, so the slider renders as inert custom elements. This is
not a migration regression — pre-v1 al-folio never injected Swiper here either
(the merge base has no swiper wiring at all).
al_img_toolsgates the assets onpage front matter, so it likely just needs the right key adding.
bundle exec al-folio upgrade overrides auditon gem bumps;.al-folio-overrides.ymlrecords the reviewed upstream checksums.🤖 Generated with Claude Code