Merge remote-tracking branch 'gh/main'

This commit is contained in:
Florent Guiotte 2026-02-18 16:59:30 +01:00
commit 0b852e1d52
412 changed files with 71121 additions and 18383 deletions

View File

@ -1,7 +1,5 @@
{ {
"files": [ "files": ["README.md"],
"README.md"
],
"imageSize": 100, "imageSize": 100,
"commit": false, "commit": false,
"contributorsPerLine": 7, "contributorsPerLine": 7,
@ -17,29 +15,30 @@
"login": "alshedivat", "login": "alshedivat",
"name": "Maruan", "name": "Maruan",
"avatar_url": "https://avatars.githubusercontent.com/u/2126561?v=4", "avatar_url": "https://avatars.githubusercontent.com/u/2126561?v=4",
"profile": "http://maruan.alshedivat.com", "profile": "https://maruan.alshedivat.com",
"contributions": [ "contributions": ["design", "code"]
"design",
"code"
]
}, },
{ {
"login": "rohandebsarkar", "login": "rohandebsarkar",
"name": "Rohan Deb Sarkar", "name": "Rohan Deb Sarkar",
"avatar_url": "https://avatars.githubusercontent.com/u/50144004?v=4", "avatar_url": "https://avatars.githubusercontent.com/u/50144004?v=4",
"profile": "http://rohandebsarkar.github.io", "profile": "https://rohandebsarkar.github.io",
"contributions": [ "contributions": ["code"]
"code"
]
}, },
{ {
"login": "pourmand1376", "login": "pourmand1376",
"name": "Amir Pourmand", "name": "Amir Pourmand",
"avatar_url": "https://avatars.githubusercontent.com/u/32064808?v=4", "avatar_url": "https://avatars.githubusercontent.com/u/32064808?v=4",
"profile": "https://amirpourmand.ir", "profile": "https://amirpourmand.ir",
"contributions": [ "contributions": ["code"]
"code" },
] {
"login": "george-gca",
"name": "George",
"avatar_url": "https://avatars.githubusercontent.com/u/31376482?v=4",
"profile": "https://george-gca.github.io/",
"contributions": ["code"]
} }
] ],
"commitConvention": "angular"
} }

7
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,7 @@
FROM mcr.microsoft.com/devcontainers/jekyll
# Fix: Remove the broken Yarn repository from the apt sources.
# This prevents 'apt-get update' from failing due to the missing GPG key.
# (Yarn is already provided by the dev container features/nvm, so this system repo is unnecessary)
# See issue #3487
RUN rm -f /etc/apt/sources.list.d/yarn.list

View File

@ -0,0 +1,34 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/jekyll
{
"name": "Jekyll",
// Using a Dockerfile to fix the broken Yarn repository. See issue #3487.
"build": {
"dockerfile": "Dockerfile"
},
// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
"ghcr.io/rocker-org/devcontainer-features/apt-packages:1": {
"packages": "build-essential,imagemagick,inotify-tools,jupyter-nbconvert,procps,ruby-full,zlib1g-dev"
},
"ghcr.io/devcontainers-extra/features/prettier:1.0.2": {}
},
// Optionally: run jekyll serve automatically on container entering using the Docker entrypoint
"postAttachCommand": "./bin/entry_point.sh",
"customizations": {
"vscode": {
"extensions": ["esbenp.prettier-vscode", "sissel.shopify-liquid", "yzhang.markdown-all-in-one"],
"settings": {
// use prettier code formatter as default formatter
"editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.configPath": ".prettierrc",
"editor.formatOnSave": true
}
}
},
"remoteUser": "vscode"
}

3
.dockerignore Normal file
View File

@ -0,0 +1,3 @@
_site/
.git/
assets/

15
.gemini/settings.json Normal file
View File

@ -0,0 +1,15 @@
{
"context": {
"fileName": [
"AGENTS.md",
".github/copilot-instructions.md",
".github/agents/customize.agent.md",
".github/agents/docs.agent.md",
".github/instructions/**/*.md",
"CUSTOMIZE.md",
"INSTALL.md",
"TROUBLESHOOTING.md",
"QUICKSTART.md"
]
}
}

24
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,24 @@
# Template taken from https://github.com/v8/v8/blob/master/.git-blame-ignore-revs.
#
# This file contains a list of git hashes of revisions to be ignored by git blame. These
# revisions are considered "unimportant" in that they are unlikely to be what you are
# interested in when blaming. Most of these will probably be commits related to linting
# and code formatting.
#
# Instructions:
# - Only large (generally automated) reformatting or renaming CLs should be
# added to this list. Do not put things here just because you feel they are
# trivial or unimportant. If in doubt, do not put it on this list.
# - Precede each revision with a comment containing the PR title and number.
# For bulk work over many commits, place all commits in a block with a single
# comment at the top describing the work done in those commits.
# - Only put full 40-character hashes on this list (not short hashes or any
# other revision reference).
# - Append to the bottom of the file (revisions should be in chronological order
# from oldest to newest).
# - Because you must use a hash, you need to append to this list in a follow-up
# PR to the actual reformatting PR that you are trying to ignore.
# Format all the code using prettier.io. (#2048, #2062)
beb6f27d596e753014cb9bff1939e5f78d66431c
2d34024961c3a3d27d6fd18ce06a551657983234

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Force LF line endings, needed for Docker to work on Windows
*.sh text eol=lf

12
.github/FUNDING.yml vendored
View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: alshedivat
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # ['https://www.buymeacoffee.com/TkFxuKo']

47
.github/GIT_WORKFLOW.md vendored Normal file
View File

@ -0,0 +1,47 @@
# Git Workflow
This document outlines the conventions for using Git and writing commit messages in this project.
## Commit Message Format
All commit messages should follow this format:
```
<type>: <subject>
<body (optional)>
```
**Types:**
- `feat`: A new feature
- `fix`: A bug fix
- `docs`: Documentation only changes
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, etc.)
- `config`: Changes to configuration files
- `chore`: Changes to the build process or auxiliary tools and libraries
**Examples:**
```
feat: Add dark mode toggle button to header
fix: Correct baseurl in project site configuration
docs: Update INSTALL.md with Docker troubleshooting
style: Format all Liquid templates with Prettier
config: Enable blog section in _config.yml
chore: Update Jekyll dependencies with bundle update --all
```
## Staging Changes
**Always `git add` files explicitly.** Do not stage everything with `git add .` unless you are certain of what's being committed. Check `git status` first to review your changes.
## What NOT to Commit
**Always obey the project's [`.gitignore`](../.gitignore) file.** It prevents the accidental commit of:
- Build outputs (`_site/`, `.jekyll-cache/`)
- Dependencies (`node_modules/`, `vendor/`)
- OS-specific files (`.DS_store`)
- Editor temporary files (`.idea/`, `.swp`, `.swo`)
- Secrets and API keys (never commit credentials)

102
.github/ISSUE_TEMPLATE/1_bug_report.yml vendored Normal file
View File

@ -0,0 +1,102 @@
name: 🐛 Report a bug
description: Any errors.
labels: ["needs triage", "bug"]
body:
- type: markdown
attributes:
value: >
Before you go any further. Is this really a **🐛 bug**?
If it's a question about how al-folio works, have a look at our [documentation](https://github.com/alshedivat/al-folio/blob/main/README.md),
[frequently asked questions](https://github.com/alshedivat/al-folio/blob/main/FAQ.md),
[past questions](https://github.com/alshedivat/al-folio/discussions/categories/q-a),
or [ask a question](https://github.com/alshedivat/al-folio/discussions/new?category=q-a).
- type: checkboxes
id: requirements
attributes:
label: Have you checked that your issue isn't already filed?
description: >
Please check if somebody else has already filed the same issue.
If you find a similar issue, please add a 👍 reaction or comment on the original post.
options:
- label: I read through [FAQ](https://github.com/alshedivat/al-folio/blob/main/FAQ.md) and searched through the [past issues](https://github.com/alshedivat/al-folio/issues), none of which addressed my issue.
required: true
- label: Yes, I have checked that this issue isn't already filed.
required: true
- type: input
attributes:
label: Bug description
description: A description of the 🐛 bug.
placeholder: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: How to reproduce the bug
description: Provide steps to reproduce the 🐛 bug.
placeholder: |
Include steps to reproduce, the expected behaviour, and the actual behaviour.
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true
- type: textarea
attributes:
label: Error messages and logs
description: >
Provide any error messages and/or logs
placeholder: "Copy the complete error messages and logs"
value: |
```
The error message you got, with the full traceback if available. Please paste it between these triple backticks.
```
validations:
required: false
- type: dropdown
id: os
attributes:
label: What operating system are you using?
description: select all OSs where you have experienced this issue
multiple: true
options:
- Linux
- Mac
- Windows
- Not applicable (e.g. you're using GitHub Pages or other hosting)
validations:
required: true
- type: dropdown
id: environment
attributes:
label: Where are you seeing the problem on?
description: select all environments where you have experienced this issue
multiple: true
options:
- "Running locally with Docker (docker compose)"
- "Running locally with Docker (devcontainer)"
- "Running locally without Docker"
- "Deployed site"
validations:
required: true
- type: textarea
attributes:
label: More info
description: Add any other info about the issue here.
placeholder: |
Add any other context about the problem here, such as versions of the libraries if running without docker, screenshots, links to the deployed site, etc.
validations:
required: false
- type: markdown
attributes:
value: "**Happy coding!**"

View File

@ -0,0 +1,56 @@
name: 🚀 Feature request
description: Propose a feature for this project
labels: ["needs triage", "enhancement"]
body:
- type: markdown
attributes:
value: >
Before you go any further, are you sure that this feature is not already implemented?
If it's a question about how al-folio works, have a look at our [documentation](https://github.com/alshedivat/al-folio/blob/main/README.md),
[frequently asked questions](https://github.com/alshedivat/al-folio/blob/main/FAQ.md),
[past questions](https://github.com/alshedivat/al-folio/discussions/categories/q-a),
or [ask a question](https://github.com/alshedivat/al-folio/discussions/new?category=q-a).
- type: checkboxes
id: requirements
attributes:
label: Have you checked that your feature request isn't already filed?
description: >
Please check if somebody else has already filed the same 🚀 feature request.
If you find a similar feature request, please add a 👍 reaction or comment on the original post.
options:
- label: I read through [FAQ](https://github.com/alshedivat/al-folio/blob/main/FAQ.md) and searched through the [past issues](https://github.com/alshedivat/al-folio/issues), none of which addressed my feature request.
required: true
- label: Yes, I have checked that this feature request isn't already filed.
required: true
- type: textarea
attributes:
label: Description & Motivation
description: A clear and concise description of the 🚀 feature proposal
placeholder: |
Please outline the motivation for the proposal.
Is your feature request related to a problem? e.g., I'm always frustrated when [...].
If this is related to another GitHub issue, please link it here
- type: textarea
attributes:
label: Pitch
description: A clear and concise description of what you want to happen.
validations:
required: false
- type: textarea
attributes:
label: Alternatives
description: A clear and concise description of any alternative solutions or features you've considered, if any.
validations:
required: false
- type: textarea
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here.
validations:
required: false

View File

@ -1,38 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Acknowledge the following**
- [ ] I carefully read and followed the [Getting Started](https://github.com/alshedivat/al-folio#getting-started) guide.
- [ ] I read through [FAQ](https://github.com/alshedivat/al-folio#faq) and searched through the [past issues](https://github.com/alshedivat/al-folio/issues), none of which addressed my issue.
- [ ] The issue I am raising is a potential bug in al-folio and not just a usage question. <br> [For usage questions, please post in the [Discussions](https://github.com/alshedivat/al-folio/discussions) instead of raising an issue.]
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**System (please complete the following information):**
- OS: [e.g. iOS]
- Browser (and its version) [e.g. chrome, safari]
- Jekyll version [e.g. 3.8.7]
- Ruby version [e.g. 2.6.5]
**Additional context**
Add any other context about the problem here.

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: ❓ Ask a Question
url: https://github.com/alshedivat/al-folio/discussions/categories/q-a
about: Ask and answer al-folio related questions.
- name: 📖 Read the documentation
url: https://github.com/alshedivat/al-folio/blob/main/README.md
about: Please consult the documentation before opening any issues!

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

596
.github/agents/customize.agent.md vendored Normal file
View File

@ -0,0 +1,596 @@
---
name: customization_agent
description: Expert customization assistant for the al-folio Jekyll academic website template
---
You are an expert customization assistant for the al-folio Jekyll academic website template.
## Your Role
- You specialize in helping users customize their al-folio academic website
- You have deep knowledge of Jekyll, Liquid templating, YAML configuration, and the al-folio project structure
- **Many users are academics without coding experience** you explain technical concepts in plain language
- You guide users through customizations step-by-step and apply changes directly to their repository
- Your task: help users personalize their academic website by modifying configuration files, adding content, and customizing the theme
- You translate technical requirements into clear, actionable instructions that anyone can follow
## Project Knowledge
- **Tech Stack:** Jekyll 4.x, Liquid templating, Ruby, YAML, Markdown, SCSS/SASS, JavaScript
- **Build System:** Jekyll with Bundler for dependency management
- **Deployment:** GitHub Pages (automated via GitHub Actions)
- **File Structure:**
- `_config.yml` Main site configuration (URL, metadata, theme colors, enabled features)
- `_data/` YAML data files:
- `cv.yml` CV/resume in RenderCV format
- `socials.yml` Social media links and configuration
- `repositories.yml` GitHub repositories to display
- `coauthors.yml` Coauthor information and links
- `venues.yml` Publication venue abbreviations
- `citations.yml` Citation counts and metrics
- `_pages/` Site pages (About, Blog, Projects, Publications, CV, Teaching, Profiles, etc.)
- `_posts/` Blog posts in Markdown (format: `YYYY-MM-DD-title.md`)
- `_projects/` Project pages in Markdown
- `_news/` News/announcement items
- `_books/` Book review pages
- `_teachings/` Teaching/course pages
- `_bibliography/papers.bib` Publications in BibTeX format
- `_sass/` SCSS/SASS stylesheets (colors, themes, layout)
- `_scripts/` Helper scripts for development and utilities
- `_plugins/` Custom Jekyll plugins for extended functionality
- `_includes/` Liquid template components:
- `_includes/cv/` Unified CV component renderers (awards, education, experience, skills, languages, certificates, references, projects, interests, etc.)
- `_includes/repository/` Repository display components
- Core components: header, footer, navigation, metadata, scripts, etc.
- `assets/` Static assets:
- `assets/img/` Images and profile pictures
- `assets/pdf/` PDF files (papers, posters, slides, etc.)
- `assets/json/` JSON files (resume.json in JSONResume format, table_data.json)
- `assets/rendercv/` RenderCV configuration and generated PDFs
- `assets/css/`, `assets/js/` Custom stylesheets and scripts
- `assets/bibliography/` BibTeX-related assets
- `assets/fonts/`, `assets/webfonts/` Font files
- `assets/libs/` Third-party JavaScript libraries
- `assets/audio/`, `assets/video/`, `assets/jupyter/`, `assets/plotly/`, `assets/html/` Multimedia and embedded content
- `.devcontainer/` Development container configuration for VS Code
- `.github/` GitHub-specific configuration:
- `.github/workflows/` GitHub Actions for deployment, CI/CD, CV PDF generation, link checking, code quality, and Copilot environment setup
- `.github/agents/` AI agent configuration files
- `.github/instructions/` Path-specific Copilot custom instructions for different file types
- `.github/ISSUE_TEMPLATE/` GitHub issue templates
- `.pre-commit-config.yaml` Pre-commit hooks configuration
- `bin/` Executable scripts and utilities
- `package.json`, `purgecss.config.js` Node.js dependencies and build tools
- `Gemfile`, `Gemfile.lock`, `.ruby-version` Ruby dependencies and version
- Documentation files: `README.md`, `INSTALL.md`, `CUSTOMIZE.md`, `FAQ.md`, `CONTRIBUTING.md`, `QUICKSTART.md`, `ANALYTICS.md`, `SEO.md`, `TROUBLESHOOTING.md`
- `robots.txt` SEO and crawler configuration
- `Dockerfile`, `docker-compose.yml`, `docker-compose-slim.yml` Docker configuration
## Community Context & Issue/Discussion References
Users may reference community discussions, issues, or past questions from the **al-folio repository** (https://github.com/alshedivat/al-folio):
- **GitHub Issues** Issues (#123) provide context about reported problems or feature requests in the al-folio project
- **Discussions** Discussion threads contain relevant customization questions from the al-folio community
- **Pull Requests** PRs may demonstrate similar customizations to the al-folio template
**Important considerations when using this context:**
- Users may or may not provide links accept descriptions or issue numbers without requiring explicit links
- **Always assume references are to the al-folio repository** when checking for issue/discussion information online, search within https://github.com/alshedivat/al-folio, not other repositories
- **Always check the date** when considering information from issues or discussions the al-folio codebase evolves, and solutions posted months or years ago may be outdated
- If a user references an old discussion/issue, verify the suggestion against the current code and documentation before recommending it
- Use this information to understand patterns and common questions, but prioritize current best practices
- If a customization request matches a pattern from previous discussions in al-folio, acknowledge it while ensuring your solution reflects the current state of the project
## Essential Documentation References
You have access to the complete documentation for al-folio:
1. **README.md** Overview, features, community examples, installation basics
2. **QUICKSTART.md** Quick start guide for getting up and running
3. **INSTALL.md** Installation, deployment, and Docker setup instructions
4. **CUSTOMIZE.md** Comprehensive customization guide covering:
- Configuration in `_config.yml`
- CV information (RenderCV and JSONResume formats)
- Creating pages, blog posts, projects, news items, and teaching pages
- Publications and BibTeX management
- Theme colors and styling
- Social media setup
- Search and analytics configuration
- Removing unwanted content
- Font and spacing customization
- Newsletter setup
- Google Calendar integration
5. **FAQ.md** Frequently asked questions and common solutions
6. **TROUBLESHOOTING.md** Troubleshooting guide for common issues
7. **CONTRIBUTING.md** Guidelines for contributing to the project
8. **ANALYTICS.md** Analytics and tracking configuration
9. **SEO.md** Search engine optimization guide
## Custom Instructions Context
This repository maintains custom instruction files (in `.github/instructions/` and `.github/copilot-instructions.md`) to guide Copilot agents when working with specific file types. These instructions provide:
- **Build process and requirements** Docker setup, Ruby/Python versions, dependency management
- **Project-specific conventions** File naming, frontmatter specifications, directory organization
- **Validation procedures** Prettier formatting, Jekyll build testing, syntax checking
- **Common patterns and examples** How to modify configuration, create content, and implement features
- **Common pitfalls and workarounds** Solutions to frequent issues like YAML syntax errors, CSS/JS not loading, broken links
When helping users, reference these instructions to ensure recommendations align with project conventions and best practices. You have access to these files and should use them as authoritative guidance for accurate, consistent advice.
## Commands You Can Use
**Development (local testing):**
```bash
# Using Docker (recommended)
docker compose pull
docker compose up
# Site available at http://localhost:8080
# Legacy method (requires Ruby, Bundler, Python)
bundle install
bundle exec jekyll serve
# Site available at http://localhost:4000
```
**Build and deployment:**
```bash
# Using Docker (recommended)
docker compose pull
docker compose up --build
# Output automatically served at http://localhost:8080
# Legacy method (requires Ruby, Bundler)
bundle exec jekyll build
# Output in _site/ directory
# Deploy happens automatically via GitHub Actions on push to main branch
```
**Code formatting:**
```bash
# Format code with Prettier
npx prettier . --write
```
## Common Customization Tasks
### 1. Basic Site Information
**Files:** `_config.yml`, `_pages/about.md`
- Change site title, author name, description
- Set URL and baseurl for deployment
- Update contact information
- Modify footer text
### 2. Social Media & Contact
**Files:** `_data/socials.yml`, `_config.yml`
- Add/update social media links (GitHub, Twitter/X, LinkedIn, Google Scholar, etc.)
- Configure email display with obfuscation
- Enable/disable social links in navbar vs. footer
### 3. About Page Content
**Files:** `_pages/about.md`, `assets/img/prof_pic.jpg`
- Update biography and profile picture
- Customize news section visibility
- Configure selected publications display
### 4. CV/Resume
**Files:** `_data/cv.yml` (RenderCV format), `assets/json/resume.json` (JSONResume format), `assets/rendercv/` (configuration)
- **Choose your format:** Users can maintain either RenderCV (`_data/cv.yml`) or JSONResume (`assets/json/resume.json`), or both simultaneously
- **RenderCV (recommended):** Human-readable YAML format with automatic PDF generation via GitHub Actions, customizable styling via `assets/rendercv/` config files (`design.yaml`, `locale.yaml`, `settings.yaml`)
- **JSONResume:** Standard JSON format compatible with other tools and services
- **Using both formats:** Users can keep both files and switch which one displays using the `cv_format` frontmatter variable in `_pages/cv.md` (options: `rendercv` or `jsonresume`)
- **Single format:** To use only one format, optionally delete the unused file (both are supported equally well)
### 5. Publications
**Files:** `_bibliography/papers.bib`, `_data/venues.yml`, `_data/coauthors.yml`
- Add publications in BibTeX format to `papers.bib`
- Configure author highlighting in `_config.yml` (`scholar:last_name`, `scholar:first_name`)
- Add venue abbreviations and coauthor links
- Include PDFs in `assets/pdf/`
- Add custom fields: `abstract`, `pdf`, `code`, `website`, `slides`, `poster`, etc.
### 6. Blog Posts
**Files:** `_posts/YYYY-MM-DD-title.md`
- Create new posts with naming pattern: `YYYY-MM-DD-title.md`
- Add frontmatter: layout, title, date, description, tags, categories
- Use Markdown for content
- Support for math (MathJax), code highlighting, images, videos
### 7. Projects
**Files:** `_projects/*.md`
- Create project pages in `_projects/` directory
- Add frontmatter: layout, title, description, img, importance
- Support for categories and horizontal/grid display
### 8. News/Announcements
**Files:** `_news/*.md`
- Add inline announcements or news with links
- Automatically displayed on home page
### 9. Teaching Pages
**Files:** `_teachings/*.md`
- Create course and teaching pages in `_teachings/` directory
- Add frontmatter: layout, title, description, academic_year, type
- Support for course schedules and materials
### 10. Theme Colors
**Files:** `_sass/_themes.scss`, `_sass/_variables.scss`
- Change `--global-theme-color` variable in `_sass/_themes.scss`
- Available theme colors defined in `_sass/_variables.scss`
- Enable/disable dark mode in `_config.yml` (`enable_darkmode`)
### 11. GitHub Repositories Display
**Files:** `_data/repositories.yml`, `_pages/repositories.md`
- Add GitHub usernames and repository names
- Displayed with stats and trophies on repositories page
### 12. Enable/Disable Features
**File:** `_config.yml`
- Toggle features: Google Analytics, comments (Giscus), related posts, tooltips, medium zoom, search
- Enable/disable pages: blog, projects, publications, repositories, teaching, books
- Configure navbar, footer, and navigation
- Configure analytics services (Google Analytics, Cronitor, Pirsch, OpenPanel)
- Configure newsletter and contact options
## Code Style Standards
**YAML formatting (in `_config.yml` and `_data/*.yml`):**
```yaml
# ✅ Good - proper indentation, clear structure
first_name: Jane
middle_name: Marie
last_name: Doe
email: jane@example.com
```
**Markdown frontmatter (for posts, pages, projects):**
```markdown
---
layout: post
title: My Research Project
date: 2024-11-21
description: A fascinating study on machine learning
tags: ml ai research
categories: research
---
Your content here in Markdown format.
```
**BibTeX entries (in `_bibliography/papers.bib`):**
```bibtex
@article{einstein1905,
title={Zur Elektrodynamik bewegter K{\"o}rper},
author={Einstein, Albert},
journal={Annalen der Physik},
volume={322},
number={10},
pages={891--921},
year={1905},
publisher={Wiley Online Library},
pdf={relativity.pdf},
abstract={This paper introduces the theory of special relativity.},
selected={true}
}
```
**Directory and file naming:**
- Blog posts: `YYYY-MM-DD-descriptive-title.md` (e.g., `2024-11-21-new-research.md`)
- Projects: `descriptive-name.md` (e.g., `quantum-computing-project.md`)
- Images: `descriptive-name.jpg/png` in `assets/img/`
- PDFs: `descriptive-name.pdf` in `assets/pdf/`
## Customization Examples
**Example 1: Changing site title and author**
```yaml
# In _config.yml
title: My Academic Website
first_name: Jane
middle_name: Marie
last_name: Doe
email: jane.doe@university.edu
```
**Example 2: Adding a new blog post**
Create `_posts/2024-11-21-my-first-post.md`:
```markdown
---
layout: post
title: My First Research Blog Post
date: 2024-11-21 14:00:00
description: Sharing insights from my latest research
tags: research machine-learning
categories: research
---
This is my first blog post discussing my research in machine learning...
```
**Example 3: Customizing theme color**
In `_sass/_themes.scss`:
```scss
// Change from purple to blue
:root {
--global-theme-color: #{$blue-color};
--global-theme-color-dark: #{$blue-color-dark};
}
```
**Example 4: Adding social media links**
In `_data/socials.yml`:
```yaml
- name: Twitter
link: https://twitter.com/username
icon: fa-brands fa-twitter
enabled: true
- name: GitHub
link: https://github.com/username
icon: fa-brands fa-github
enabled: true
- name: LinkedIn
link: https://linkedin.com/in/username
icon: fa-brands fa-linkedin
enabled: true
```
## Step-by-Step Workflow
When helping users customize their site:
1. **Understand the request** Ask clarifying questions if needed; never assume technical knowledge
- If the user mentions a relevant issue, discussion, or past question, listen for context but don't require them to provide a link
2. **Review related issues/discussions** If a user references or describes a related issue/discussion, acknowledge the context but verify currency
- Example: "I see this relates to discussion #123. Let me verify the current approach and address your specific needs."
- Caveat: "That discussion is from 2021; let me check if the approach still applies with our current codebase."
3. **Identify affected files** Determine which files need modification
4. **Explain the change clearly** Describe what you'll do, where the file is located, and why this change matters
5. **Apply changes** Use file editing tools to make modifications
6. **Verify syntax** Ensure YAML/Markdown/BibTeX syntax is correct
7. **Provide clear next steps** Explain how to preview changes in beginner-friendly terms (e.g., "After I make this change, you can see it by...")
8. **Anticipate questions** Address potential confusion before users encounter it; reference related discussions if applicable
9. **Use plain language** Avoid or explain technical jargon; prioritize clarity over verbosity
## Testing Before Deployment
Always guide users to test changes locally before pushing to GitHub:
**Local Testing Steps:**
1. **Run locally with Docker** (recommended):
```bash
docker compose pull
docker compose up
```
Then open `http://localhost:8080` in your browser
2. **Wait for rebuild** After making changes to files, wait 5-10 seconds for Jekyll to rebuild the site. You'll see output in the terminal indicating the rebuild is complete.
3. **Check for errors** Look at the terminal output for any error messages (YAML syntax errors, missing files, BibTeX parsing issues, etc.).
4. **Verify visually** Manually navigate through your site:
- Check that pages load without errors
- Verify text displays correctly
- Ensure images are visible
- Test navigation links
- Check that your changes appear as expected
5. **Test on different pages** If you modified:
- `_config.yml` Check the entire site (affects global settings)
- Blog posts Check the blog page and individual post
- Publications Check the publications page
- CV/Resume Check the about page
- Social links Check header and footer
6. **Only then push to GitHub** Once everything looks good locally, commit and push:
```bash
git add .
git commit -m "Describe your changes"
git push
```
**Why this matters:** Catching errors locally saves time and prevents broken content from going live. Most issues are easy to spot in the local preview.
## Common Mistakes to Avoid
Help users avoid these frequent errors:
### YAML Configuration Errors
- **Deleting `baseurl:` instead of leaving it empty** For personal sites, the line must exist but be empty:
```yaml
baseurl: # ✅ Correct - empty value
# ❌ Wrong - deleted entirely
```
- **Incorrect indentation in `_config.yml`** YAML is very sensitive to spacing. Use spaces, not tabs. Each nested item should be indented by exactly 2 spaces.
- **Unquoted special characters** Some characters need quotes:
```yaml
description: "My site: Research & Teaching" # ✅ Correct
description: My site: Research & Teaching # ❌ May cause errors
```
### Blog Posts & Content
- **Wrong filename format** Must be `YYYY-MM-DD-title.md` (e.g., `2024-01-15-my-post.md`). If the format is wrong, the post won't appear.
- **Missing required frontmatter** Every post needs:
```markdown
---
layout: post
title: My Post Title
date: 2024-01-15
---
```
- **Incorrect date format** Use `YYYY-MM-DD` in filename and `YYYY-MM-DD HH:MM:SS` (or just `YYYY-MM-DD`) in frontmatter.
### Publications & BibTeX
- **BibTeX syntax errors** Common mistakes:
- Missing commas between fields
- Unmatched braces `{}`
- Invalid characters in entry keys
- Check existing entries in `_bibliography/papers.bib` as examples
- **Author names not matching** If you set `scholar:last_name: [Einstein]` but your BibTeX has "A. Einstein", it won't highlight. Names must match exactly (considering variations defined in `_data/coauthors.yml`)
### Media & Assets
- **Incorrect file paths** Use consistent paths:
- Images: `assets/img/my-image.jpg`
- PDFs: `assets/pdf/my-paper.pdf`
- Test that links work by opening them in the browser during local preview
- **Large unoptimized images** Compress images before adding them (tools: TinyPNG, ImageOptim). Large images slow down your site.
### Deployment Issues
- **Not checking GitHub Actions status** After pushing, wait 4-5 minutes and check the **Actions** tab in your repository. If the build failed, you'll see error messages there.
- **Modifying the `gh-pages` branch directly** Never edit this branch. It's auto-generated by GitHub Actions. All changes go to `main`.
- **Not refreshing your browser cache** If you pushed changes but don't see them, try:
- Hard refresh: `Ctrl+Shift+R` (Windows/Linux) or `Cmd+Shift+R` (Mac)
- Clear browser cache
- Wait a few more minutes for deployment to complete
### Configuration Mismatches
- **`url` and `baseurl` not matching your site type**:
- Personal site: `url: https://username.github.io`, `baseurl:` (empty)
- Project site: `url: https://username.github.io`, `baseurl: /repo-name/`
- External domain: Set `url` to your actual domain
- **Inconsistent settings in `_config.yml`** If you change author name in one place, update it everywhere it appears
## Boundaries
- ✅ **Always do:**
- Modify configuration files (`_config.yml`, `_data/*.yml`)
- Create/edit content files (posts, pages, projects, news)
- Update BibTeX bibliography
- Customize SCSS/SASS theme files
- Add images and PDFs to appropriate directories
- Explain changes and their impact
- Reference official documentation when helpful
- ⚠️ **Ask first:**
- Major structural changes to the template
- Removing core functionality or pages
- Modifying GitHub Actions workflows
- Changes that might break deployment
- Adding external dependencies or plugins
- 🚫 **Never do:**
- Delete `.github/workflows/` files without explicit request
- Modify `Gemfile` or `package.json` without understanding implications
- Add sensitive information (API keys, passwords, personal data)
- Edit auto-generated files in `_site/` or `gh-pages` branch
- Make changes that violate the MIT license terms
- Modify Docker configuration without Docker expertise
## Important Notes
- All changes should be made to the **main** (or **source**) branch, NEVER to `gh-pages`
- The `gh-pages` branch is auto-generated by GitHub Actions
- Changes take ~4-5 minutes to deploy via GitHub Actions after pushing to main
- Local preview with Docker runs on `http://localhost:8080`
- The site auto-rebuilds locally when files change (may take a few seconds)
- Always ensure `url` and `baseurl` are correctly set in `_config.yml` for deployment
- For personal sites: `url: https://username.github.io` and `baseurl:` (empty)
- For project sites: `url: https://username.github.io` and `baseurl: /repo-name/`
## Quick Reference Map
| User wants to... | Files to modify | Key documentation |
| ----------------------- | ------------------------------------------------------------------- | ---------------------------------- |
| Change personal info | `_config.yml`, `_pages/about.md` | CUSTOMIZE.md § Configuration |
| Add profile picture | `assets/img/prof_pic.jpg` | CUSTOMIZE.md § About page |
| Update CV | `_data/cv.yml` (RenderCV) or `assets/json/resume.json` (JSONResume) | CUSTOMIZE.md § Modifying CV |
| Add publications | `_bibliography/papers.bib` | CUSTOMIZE.md § Adding publications |
| Add blog post | `_posts/YYYY-MM-DD-title.md` | CUSTOMIZE.md § Blog posts |
| Create project | `_projects/name.md` | CUSTOMIZE.md § Projects |
| Add news item | `_news/announcement.md` | CUSTOMIZE.md § Adding news |
| Add teaching page | `_teachings/course.md` | CUSTOMIZE.md § Teaching collection |
| Change theme color | `_sass/_themes.scss` | CUSTOMIZE.md § Theme color |
| Add social links | `_data/socials.yml` | CUSTOMIZE.md § Social media |
| Set up analytics | `_config.yml` | CUSTOMIZE.md & ANALYTICS.md |
| Enable/disable features | `_config.yml` | CUSTOMIZE.md § Configuration |
| Remove pages | Delete from `_pages/`, update nav | CUSTOMIZE.md § Removing content |
| Fix deployment issues | `_config.yml` (url/baseurl) | FAQ.md, INSTALL.md |
| Test changes locally | Docker setup | INSTALL.md § Docker |
| Debug broken site | Check GitHub Actions, local preview output | TROUBLESHOOTING.md, FAQ.md |
| Add custom page | Create `_pages/name.md`, update nav | CUSTOMIZE.md § Creating pages |
| Customize fonts/spacing | `_sass/_variables.scss` | CUSTOMIZE.md § Customization |
| Improve SEO | `_config.yml`, `robots.txt` | SEO.md |
| Ensure accessibility | Check markup, alt text, contrast | TROUBLESHOOTING.md |
## Using Community Context in Your Responses
When users reference issues or discussions:
1. **Accept information without requiring links** Don't demand that users track down and share issue/discussion URLs
- ❌ Avoid: "Please provide the link to the discussion so I can help you."
- ✅ Do this: "Let me help based on what you've described. If you remember any details from the discussion, that would be helpful."
2. **Verify information against current code** Assume advice from older discussions might be outdated
- Example: "You mentioned a solution from an older discussion. Let me check if that still applies with the current version..."
- Be prepared to offer updated guidance if the codebase has changed
3. **Acknowledge patterns while providing current guidance** Show you understand the context but prioritize current best practices
- Example: "I see why that approach was suggested before. With our current code, here's the recommended way to do this..."
4. **Mention when discussions are particularly relevant** If a recent discussion is very relevant, you can mention it
- Example: "This is similar to what was discussed in #67 (from December 2024), which is still the best approach."
5. **Suggest sharing solutions** If a user's question or your solution would help the community, encourage them to update or create discussions
- Example: "If this solution works for you, consider sharing it in the discussions—it might help others with similar customizations."
## Response Style
- Be direct, patient, and actionable assume the user may be unfamiliar with coding concepts
- Show the exact file path and changes needed, explaining where to find files in plain language
- Provide code snippets ready to copy-paste, with clear instructions on what to change
- Always explain the "why" in simple terms help users understand what they're doing, not just follow steps blindly
- When using technical terms (like "YAML", "Markdown", "frontmatter", "repository"), briefly explain what they mean
- Break complex tasks into small, numbered steps that are easy to follow
- Reference documentation sections when they provide additional useful detail
- Reference related issues or discussions when they provide relevant context or solutions
- After making changes, clearly explain how to preview (local) or deploy (push to GitHub) in beginner-friendly terms
- Anticipate common questions or confusion points and address them proactively

215
.github/agents/docs.agent.md vendored Normal file
View File

@ -0,0 +1,215 @@
---
name: docs_agent
description: Documentation specialist for al-folio Jekyll theme
---
You are a documentation specialist for the al-folio Jekyll theme project.
## Your role
- You maintain clear, concise documentation for this Jekyll-based academic portfolio theme
- You write for academics and researchers who may not have a coding background
- You explain technical concepts in plain language, avoiding jargon whenever possible
- Your primary task: update and maintain documentation in root-level markdown files that anyone can understand
## Project knowledge
- **Tech Stack:** Jekyll 4.x (Ruby-based static site generator), Liquid templating, YAML configuration, SCSS/CSS, JavaScript, Docker
- **Key Dependencies:** jekyll-scholar, jekyll-archives-v2, jekyll-paginate-v2, MathJax, Bootstrap, Prettier, pre-commit hooks
- **File Structure:**
- `_config.yml` Main Jekyll configuration file
- `*.md` (root) Documentation files: `README.md`, `INSTALL.md`, `CUSTOMIZE.md`, `FAQ.md`, `CONTRIBUTING.md`, `QUICKSTART.md`, `ANALYTICS.md`, `SEO.md`, `TROUBLESHOOTING.md`
- `_pages/` Website pages (Markdown with frontmatter)
- `_posts/` Blog posts
- `_projects/`, `_news/`, `_books/`, `_teachings/` Jekyll collections
- `_layouts/` Liquid layouts for different page types
- `_includes/` Liquid template components:
- `_includes/cv/` Unified CV component renderers (awards, education, experience, skills, languages, certificates, references, projects, interests, publications, etc.)
- `_includes/repository/` Repository display components
- Core includes: header, footer, metadata, scripts, etc.
- `_sass/` SCSS stylesheets
- `_data/` YAML data files:
- `cv.yml` CV/resume in RenderCV format
- `socials.yml` Social media links
- `repositories.yml` GitHub repositories
- `coauthors.yml` Coauthor information
- `venues.yml` Publication venue abbreviations
- `citations.yml` Citation metrics
- `_plugins/` Custom Jekyll plugins for extended functionality
- `_bibliography/` BibTeX files for publications
- `assets/` Static assets:
- `assets/json/` JSON files (resume.json in JSONResume format, table_data.json)
- `assets/rendercv/` RenderCV configuration files and generated PDFs
- `assets/img/`, `assets/pdf/` Images and PDFs
- `assets/css/`, `assets/js/` Custom stylesheets and scripts
- `assets/fonts/`, `assets/webfonts/` Font files
- `assets/bibliography/`, `assets/libs/` Support files
- `assets/audio/`, `assets/video/`, `assets/jupyter/`, `assets/plotly/`, `assets/html/` Multimedia and embedded content
- `.github/` GitHub configuration:
- `.github/workflows/` GitHub Actions (deployment, CI/CD, CV PDF generation, link checking, code quality, Copilot environment setup)
- `.github/agents/` AI agent configuration files (customize.agent.md, docs.agent.md)
- `.github/instructions/` Path-specific Copilot custom instructions for different file types
- `.github/ISSUE_TEMPLATE/` GitHub issue templates
- `_scripts/` Helper scripts and utilities
- `bin/` Executable scripts
- `.devcontainer/` Development container configuration
- `.pre-commit-config.yaml` Pre-commit hooks for code quality
- `Dockerfile`, `docker-compose.yml`, `docker-compose-slim.yml` Docker configuration
- `Gemfile`, `Gemfile.lock`, `.ruby-version` Ruby dependencies
- `package.json` Node.js dependencies
## Documentation standards
**Keep it simple:**
- Be direct and concise; avoid unnecessary examples unless they clarify significantly different use cases
- Each section should answer: "What is this?" and "How do I use it?"
- Use bullet points for unordered lists; use numbered lists for sequential steps or when order matters
**Prefer references over repetition:**
- Link to existing files instead of duplicating content
- Good: "See the configuration options in `_config.yml`"
- Bad: Copying the entire YAML structure into docs
- Link to official library documentation for third-party tools
- Example: "For Jekyll basics, see [Jekyll documentation](https://jekyllrb.com/docs/)"
- When referencing code files, use inline code formatting with backticks: `_config.yml`, `_pages/about.md`
**Point users to source code:**
- Reference well-documented configuration files rather than repeating their content
- Example: "Configure your deployment settings in `_config.yml`. For Docker deployment, see `docker-compose.yml`"
- When explaining CV features, point to both data sources: "The CV page is generated from `_data/cv.yml` (RenderCV format) or `assets/json/resume.json` (JSONResume format), which are kept in sync. A GitHub Actions workflow automatically generates a PDF from the RenderCV data."
**Avoid UI descriptions:**
- Don't draw or describe visual UI elements with Markdown
- Don't document button locations, menu items, or visual layouts that may change
- Focus on conceptual understanding and file-based configuration
- Good: "Enable dark mode by setting `enable_darkmode: true` in `_config.yml`"
- Bad: "Click the moon icon in the top right corner to toggle dark mode"
**Code style:**
- Use triple backticks with language identifiers for code blocks: `bash`, `yaml`, `ruby`, `liquid`, `html`
- For file paths, use inline code: `` `_config.yml` ``
- Keep code examples minimal and focused on the specific feature being explained
**Structure:**
- Use clear section headers with `##` or `###`
- Include a table of contents for longer documents (use `<!--ts-->` and `<!--te-->` markers for auto-generation)
- Group related information together
- Put important warnings or notes in blockquotes: `> Note: ...` or `> Warning: ...`
## Documentation file purposes
- `ANALYTICS.md` Analytics and tracking configuration options
- `CONTRIBUTING.md` Guidelines for contributors and development
- `CUSTOMIZE.md` Comprehensive customization guide (configuration, adding content, styling, CV management, publications)
- `FAQ.md` Frequently asked questions and common issues
- `INSTALL.md` Installation and deployment instructions (Docker, GitHub Pages, local setup, upgrading)
- `QUICKSTART.md` Get started in 5 minutes (repository setup, personalization, deployment)
- `README.md` Project overview, features showcase, community examples, quick start links
- `SEO.md` Search engine optimization guide
- `TROUBLESHOOTING.md` Detailed troubleshooting guide for deployment, build, styling, and feature issues
## GitHub Copilot Custom Instructions
This repository includes custom instruction files to enhance GitHub Copilot's effectiveness when working with specific file types. These files are located in `.github/instructions/` and `.github/copilot-instructions.md`:
**Main Instructions:**
- `.github/copilot-instructions.md` Repository-wide guidance including tech stack versions, Docker build process, project layout, CI/CD pipelines, common pitfalls, and file format specifications
**Path-Specific Instructions (applies to files matching specific patterns):**
- `.github/instructions/liquid-templates.instructions.md` (applies to `**/*.liquid`) Guidance for Liquid templating, common patterns, validation, and testing
- `.github/instructions/yaml-configuration.instructions.md` (applies to `_config.yml,_data/**/*.yml`) Guidance for YAML syntax, feature flags, BibTeX keywords, and configuration best practices
- `.github/instructions/bibtex-bibliography.instructions.md` (applies to `**/*.bib,_bibliography/**`) Guidance for BibTeX entry syntax, custom keywords, field specifications, and publication frontmatter
- `.github/instructions/markdown-content.instructions.md` (applies to content collections) Guidance for creating content in `_books/`, `_news/`, `_pages/`, `_posts/`, `_projects/`, and `_teachings/` with appropriate frontmatter and formatting
- `.github/instructions/javascript-scripts.instructions.md` (applies to `_scripts/**/*.js`) Guidance for JavaScript and Liquid+JavaScript hybrid files, ES6 patterns, and script debugging
**Environment Setup:**
- `.github/workflows/copilot-setup-steps.yml` GitHub Actions workflow that pre-configures the Copilot environment with Ruby 3.3.5, Python 3.13, Node.js, ImageMagick, and nbconvert before agent execution
These instruction files help Copilot agents understand project-specific conventions, build requirements, validation procedures, and common patterns without requiring them to explore the codebase.
## Writing style
- **Audience:** Many users are academics without coding experience; explain technical terms when you must use them
- **Tone:** Patient, encouraging, and straightforward; treat every reader as intelligent but possibly unfamiliar with web development
- **Clarity:** One concept per paragraph; use numbered lists for multi-step processes to make them easy to follow
- **Examples:** Provide real, concrete examples from the repository; show exactly what to type or where to click
- **Accessibility:** When mentioning technical terms (e.g., "YAML", "frontmatter", "repository"), briefly explain what they mean in context
## Typical tasks
1. **Update configuration documentation** when `_config.yml` changes
2. **Document new features** added to the theme (new layouts, plugins, customization options)
3. **Document CV workflow** Explain how users choose between RenderCV and JSONResume formats, how to switch formats using frontmatter, and how optional automatic PDF generation works via GitHub Actions
4. **Clarify installation steps** when deployment methods or dependencies change
5. **Update troubleshooting** in FAQ when common issues arise
6. **Maintain consistency** across all documentation files
## Common Technical Terms & Explanations
For academics and non-technical readers, explain these terms briefly on first use:
**Web/Jekyll Terms:**
- **Jekyll** A "static site generator" that converts your Markdown files and templates into a complete website. Think of it as a tool that takes your content and automatically formats it into web pages.
- **Frontmatter** Metadata at the top of a file (between `---` lines) that tells Jekyll how to process the file. Example: title, date, author.
- **Liquid** A templating language that Jekyll uses to dynamically generate pages. You'll see it in `_layouts/` and `_includes/` files with `{% %}` syntax.
- **Markdown** A simple text format for writing content. Much easier than HTML. Files use `.md` extension.
**Configuration Terms:**
- **YAML** A human-readable format for storing configuration data. Uses colons and indentation. Examples in `_config.yml`, `_data/` files.
- **Configuration file** `_config.yml` contains all the settings that control how your site looks and behaves (like site title, author name, theme color).
**Content Organization:**
- **Collection** A group of similar content items. al-folio uses collections for `_posts/` (blog posts), `_projects/`, `_news/`, etc.
- **Repository** The folder containing all your website code and content. Stored on GitHub for version control and deployment.
- **Deployment** The process of publishing your site so it's accessible on the internet (via GitHub Pages or other hosting).
**Publication-Related:**
- **BibTeX** A standardized format for storing publication metadata (title, authors, year, etc.). Used in `_bibliography/papers.bib`.
- **Publication frontmatter** Custom fields you add to BibTeX entries (like `pdf:`, `code:`, `slides:`) to add extra links and features to your publications page.
**When to explain:** If a document uses a technical term that readers might not know, briefly explain it in parentheses or a footnote the first time it appears:
```markdown
Jekyll uses **Liquid** (a templating language that generates dynamic content)
to process your files located in `_layouts/` and `_includes/`.
```
## Boundaries
- ✅ **Always do:**
- Update documentation files (`*.md` in root directory)
- Keep documentation in sync with actual code and configuration
- Use existing documentation style and structure (or improve it with patterns from this agent)
- Link to source files and official documentation
- Test commands and instructions before documenting them
- Explain technical terms using the common terms reference provided
- Preserve existing table of contents markers (`<!--ts-->` and `<!--te-->`
- ⚠️ **Ask first:**
- Major restructuring of documentation organization
- Adding entirely new documentation files
- Changing the documentation format or style guide
- Removing sections that may still be relevant
- 🚫 **Never do:**
- Modify source code files (`_layouts/`, `_includes/`, `_sass/`, etc.)
- Edit `_config.yml` or other configuration files
- Change GitHub Actions workflows in `.github/workflows/`
- Modify Jekyll plugins in `_plugins/`
- Commit without testing documentation examples
- Delete existing documentation without replacement
- Add executable code that runs automatically
- Include placeholder text like "TODO" or "Coming soon" without an issue tracking it

253
.github/copilot-instructions.md vendored Normal file
View File

@ -0,0 +1,253 @@
# Copilot Coding Agent Instructions
## Repository Overview
**al-folio** is a simple, clean, and responsive [Jekyll](https://jekyllrb.com/) theme for academics and researchers. It enables users to create professional portfolio and blog websites with minimal configuration. The repository serves both as a template and as a reference implementation.
- **Type:** Jekyll static site generator template
- **Target Users:** Academics, researchers, and professionals
- **Key Features:** CV display, publication bibliography, blog posts, projects, news/announcements, course listings
## Tech Stack & Versions
**Core Technologies:**
- **Jekyll:** v4.x (Ruby static site generator)
- **Ruby:** 3.3.5 (primary CI/CD version), 3.2.2 (some workflows)
- **Python:** 3.13 (for nbconvert, jupyter notebook support)
- **Node.js:** Latest (for purgecss and prettier)
- **Docker:** Uses prebuilt image `amirpourmand/al-folio:v0.16.3` (Ruby slim-based)
**Build Dependencies (from Gemfile):**
- `classifier-reborn` Related posts calculation
- `jekyll-archives-v2` Archive page generation
- `jekyll-jupyter-notebook` Jupyter notebook embedding
- `jekyll-minifier` CSS/JS minification
- `jekyll-paginate-v2` Pagination
- `jekyll-scholar` Bibliography management
- `jekyll-tabs` Tab UI components
- `jekyll-toc` Table of contents generation
- `jemoji` Emoji support
- Multiple other specialized jekyll plugins
**Code Quality Tools:**
- **Prettier:** v3.8.0+ with `@shopify/prettier-plugin-liquid` Code formatter (mandatory for PRs)
- **Purgecss:** CSS purification for production builds
## Building & Local Development
### Docker (Recommended Approach)
**Always use Docker for local development.** This ensures consistency with CI/CD and avoids Ruby/Python environment issues.
**Initial Setup:**
```bash
docker compose pull # Pull prebuilt image
docker compose up # Start development server
# Site runs at http://localhost:8080
```
**Rebuilding with Updated Dependencies:**
```bash
docker compose up --build # Rebuilds Docker image from Dockerfile
docker compose up --force-recreate # Forces complete rebuild
```
**For slim Docker image (if image size is critical):**
```bash
docker compose -f docker-compose-slim.yml up
```
**If Docker build fails:**
- Check disk space and available RAM
- Kill any existing jekyll processes: `docker compose down`
- For M1/M2 Mac: Ensure Docker Desktop is up-to-date
- Linux users may need Docker group permissions: `sudo usermod -aG docker $USER` (then logout/login)
### Bundle/Jekyll (Legacy, Use Docker Instead)
```bash
bundle install # Install Ruby gems
pip install jupyter # Install Python dependencies
bundle exec jekyll serve --port 4000 # Run at http://localhost:4000
```
### Important Build Requirements
- **ImageMagick must be installed** Required for image processing plugins
- Docker: Installed automatically
- Local: `sudo apt-get install imagemagick` (Linux) or `brew install imagemagick` (Mac)
- **nbconvert must be upgraded before build** `pip3 install --upgrade nbconvert`
- **Always set JEKYLL_ENV=production for production builds** Required for CSS/JS minification
## Project Layout & Key Files
### Root Directory Structure
- `_bibliography/papers.bib` BibTeX bibliography for publications
- `_config.yml` **Primary configuration file** (title, author, URLs, baseurl, feature flags)
- `_data/` YAML data files (socials.yml, coauthors.yml, cv.yml, citations.yml, venues.yml, repositories.yml)
- `_includes/` Reusable Liquid template components
- `_layouts/` Page layout templates (about.liquid, post.liquid, bib.liquid, distill.liquid, cv.liquid, etc.)
- `_news/` News/announcement entries
- `_pages/` Static pages (about.md, cv.md, publications.md, projects.md, teaching.md, etc.)
- `_posts/` Blog posts (format: YYYY-MM-DD-title.md)
- `_projects/` Project showcase entries
- `_sass/` SCSS stylesheets
- `_scripts/` JavaScript files for functionality
- `_teachings/` Course and teaching entries
- `assets/img/` Images, profile pictures
- `docker-compose.yml` Docker compose configuration
- `Dockerfile` Docker image definition
- `Gemfile` & `Gemfile.lock` Ruby dependency specifications
- `package.json` Node.js dependencies (prettier only)
- `purgecss.config.js` PurgeCSS configuration for production CSS optimization
### Configuration Priority
When making changes:
1. **Always start with `_config.yml`** for site-wide settings
2. **Feature flags are in `_config.yml`** Look for `enabled: true/false` options
3. **Social media links:** `_data/socials.yml`
4. **Content data:** Respective `_data/*.yml` files
5. **Styling:** `_sass/` directory (uses SCSS)
## CI/CD Pipeline & Validation
### GitHub Workflows (in `.github/workflows/`)
- **deploy.yml** Main deployment workflow (runs on push/PR to main/master)
- Sets up Ruby 3.3.5, Python 3.13
- Installs imagemagick, nbconvert
- Runs `bundle exec jekyll build` with JEKYLL_ENV=production
- Runs purgecss for CSS optimization
- Commits built site to gh-pages branch
- **Triggers on:** Changes to site files, assets, config (NOT documentation files alone)
- **prettier.yml** Code formatting validation (mandatory)
- Runs prettier on all files
- **Fails PRs if code is not properly formatted**
- Generates HTML diff artifact on failure
- Must install prettier locally to avoid failures: `npm install prettier @shopify/prettier-plugin-liquid`
- **broken-links.yml, broken-links-site.yml** Link validation
- **axe.yml** Accessibility testing
- **codeql.yml** Security scanning
- **update-citations.yml** Automatic citation updates
- **render-cv.yml** CV rendering from RenderCV format
### Pre-commit Requirements
**You must run these locally before pushing:**
1. **Prettier formatting (mandatory):**
```bash
npm install --save-dev prettier @shopify/prettier-plugin-liquid
npx prettier . --write
```
2. **Local build test with Jekyll:**
```bash
docker compose pull && docker compose up
# Let it build (wait 30-60 seconds)
# Visit http://localhost:8080 and verify site renders correctly
# Exit with Ctrl+C
```
3. **Or run full build simulation:**
```bash
docker compose up --build
bundle exec jekyll build
# Check for errors in output
```
## Common Pitfalls & Workarounds
### YAML Syntax Errors in \_config.yml
- **Problem:** Special characters (`:`, `&`, `#`) in values cause parse errors
- **Solution:** Quote string values: `title: "My: Cool Site"`
- **Debug:** Run locally to see detailed error: `bundle exec jekyll build`
### "Unknown tag 'toc'" Error on Deployment
- **Problem:** Deploy succeeds locally but fails on GitHub Actions
- **Cause:** Jekyll plugins don't load properly
- **Solution:** Verify gh-pages branch is set as deployment source in Settings → Pages
### CSS/JS Not Loading After Deploy
- **Problem:** Site loads but has no styling
- **Cause:** Incorrect `url` and `baseurl` in `_config.yml`
- **Fix:**
- Personal site: `url: https://username.github.io`, `baseurl:` (empty)
- Project site: `url: https://username.github.io`, `baseurl: /repo-name/`
- Clear browser cache (Ctrl+Shift+Del or private browsing)
### Prettier Formatting Failures
- **Problem:** PR fails prettier check after local builds passed
- **Solution:** Run prettier before committing:
```bash
npx prettier . --write
git add . && git commit -m "Format code with prettier"
```
### Port 8080 or 4000 Already in Use
- **Docker:** `docker compose down` then `docker compose up`
- **Ruby:** Kill process: `lsof -i :4000 | grep LISTEN | awk '{print $2}' | xargs kill`
### Related Posts Errors ("Zero vectors cannot be normalized")
- **Cause:** Empty blog posts or posts with only stop words confuse classifier-reborn
- **Solution:** Add meaningful content to posts, or set `related_posts: false` in post frontmatter
## File Format Specifications
### Blog Post Frontmatter (\_posts/)
```yaml
---
layout: post
title: Post Title
date: YYYY-MM-DD
categories: category-name
---
```
### Project Frontmatter (\_projects/)
```yaml
---
layout: page
title: Project Name
description: Short description
img: /assets/img/project-image.jpg
importance: 1
---
```
### BibTeX Format (papers.bib)
- Standard BibTeX format
- al-folio supports custom keywords: `pdf`, `code`, `preview`, `doi`, etc.
- Check CUSTOMIZE.md for custom bibtex keyword documentation
## Trust These Instructions
This guidance documents the tested, working build process and project structure. **Trust these instructions and only perform additional searches if:**
1. Specific information contradicts what you observe in the codebase
2. You need implementation details beyond what's documented
3. Error messages reference features or files not mentioned here
The instructions are designed to reduce unnecessary exploration and allow you to focus on code changes.

View File

@ -0,0 +1,174 @@
---
applyTo: "**/*.bib,_bibliography/**"
excludeAgent: "code-review"
---
# BibTeX Bibliography Instructions
## BibTeX Format Basics
The al-folio repository uses BibTeX for managing publications. All entries are stored in `_bibliography/papers.bib`.
### Standard BibTeX Entry Types
```bibtex
@article{key,
title={Title},
author={Author, A. and Author, B.},
journal={Journal Name},
volume={10},
pages={1--20},
year={2023},
publisher={Publisher Name}
}
@inproceedings{key,
title={Title},
author={Author, A.},
booktitle={Proceedings of Conference},
year={2023}
}
@book{key,
title={Book Title},
author={Author, A.},
publisher={Publisher Name},
year={2023}
}
```
## al-folio Custom BibTeX Keywords
Beyond standard BibTeX fields, al-folio supports custom keywords for rich publications display:
### Available Custom Keywords
- **abstract:** Full abstract text (multi-line text in curly braces)
- **award:** Award or distinction (`award: Best Paper Award`)
- **code:** URL to source code repository (`code: https://github.com/user/repo`)
- **dimensions:** Dimensions badge ID for citation metrics
- **doi:** Digital Object Identifier (`doi: 10.1234/example`)
- **html:** URL to full text or project page (`html: https://example.com`)
- **pdf:** URL or path to PDF file (`pdf: /assets/papers/2023-paper.pdf`)
- **poster:** URL to conference poster (`poster: /assets/posters/poster.pdf`)
- **preview:** URL to preview image (`preview: /assets/img/papers/paper-preview.jpg`)
- **selected:** Boolean to feature on publications page (`selected: true`)
- **slides:** URL to presentation slides (`slides: /assets/slides/2023.pdf`)
### Example Entry with Custom Keywords
```bibtex
@article{smith2023important,
title={Important Research},
author={Smith, John and Doe, Jane},
journal={Nature},
volume={100},
pages={1--10},
year={2023},
publisher={Nature Publishing Group},
abstract={This is the full abstract text. It can span multiple lines.},
pdf={smith2023.pdf},
code={https://github.com/example/repo},
preview={smith2023.jpg},
doi={10.1234/nature.12345},
selected={true}
}
```
## Formatting Rules
### Key Considerations
1. **Unique keys:** Each entry must have a unique key (first parameter)
2. **Author names:** Separate multiple authors with `and`
3. **Curly braces:** Protect capitalized words in titles with `{Curly Braces}` to preserve capitalization
4. **Special characters:** Use LaTeX escape sequences (`{\`e}`for é,`{\~n}` for ñ)
5. **URLs:** Place URLs in `{curly braces}` to prevent issues
6. **Alphabetical order:** Keep entries alphabetically sorted by key
### Common Mistakes to Avoid
- ❌ `author=Smith, John` → ✅ `author={Smith, John}`
- ❌ `journal=Science` → ✅ `journal={Science}` or `journal = "Science"`
- ❌ `title=Deep Learning` (loses capitalization) → ✅ `title={Deep Learning}` or `title={{D}eep {L}earning}`
- ❌ `pdf=http://...` → ✅ `pdf={http://...}`
## Jekyll-Scholar Integration
The `jekyll-scholar` plugin processes BibTeX and generates bibliography pages.
### How it Works
1. Entries in `_bibliography/papers.bib` are read
2. Pages marked with `layout: bib` render the bibliography
3. Posts/pages can reference entries using `{% cite key %}`
4. Custom keywords control what displays on publication entries
### Displaying Publications
In pages/posts, use:
- `{% cite key %}` Cite an entry inline
- `{% bibliography %}` Display full bibliography
## File Paths in BibTeX
When using `pdf`, `poster`, `preview`, or similar fields:
- **PDF files:** Use just the filename (automatically resolved to `assets/pdf/`)
- Example: `pdf={smith2023.pdf}` → resolves to `assets/pdf/smith2023.pdf`
- **Preview images:** Use just the filename (automatically resolved to `assets/img/publication_preview/`)
- Example: `preview={smith2023.jpg}` → resolves to `assets/img/publication_preview/smith2023.jpg`
- **Absolute URLs:** Include full URL for external resources
- Example: `code={https://github.com/user/repo}`
- Example: `html={https://example.com/paper}`
## Validation
### Before Committing BibTeX Changes
1. **Syntax check:** Verify no unclosed braces or quotes
2. **Build test:**
```bash
docker compose down
docker compose up
# Check output for "ERROR" or "Invalid bibtex"
# Publications should render at http://localhost:8080/publications/
```
3. **Publication page:** Open publications page and verify entries display correctly
### Common BibTeX Build Errors
- `Invalid bibtex reference 'key'` Key doesn't exist in papers.bib
- `Unmatched braces` Missing closing brace in entry
- `Unknown entry type` Entry type (after @) is misspelled
- `PDF not found` Path in pdf field is incorrect
## Editing and Maintenance
### Adding New Entries
1. Add entry to `_bibliography/papers.bib`
2. Use consistent key naming (e.g., `LastnameYear` or `Lastname2023details`)
3. Ensure all required fields are present
4. Test build: `docker compose up`
### Modifying Existing Entries
- Can change any BibTeX field without breaking Jekyll
- Adding custom keywords (pdf, code, etc.) enriches display
- Test build after modifications to verify display
### Removing Entries
- Delete or comment out (prefix with `%`) the entire entry
- No broken reference check needed; Jekyll-Scholar handles missing keys gracefully
## Trust These Instructions
When working with BibTeX:
- Follow the standard format shown in examples above
- Always test locally with `docker compose up` after changes
- Check the publications page at http://localhost:8080/publications to verify display
- Only search for additional details if encountering error messages not mentioned here

View File

@ -0,0 +1,248 @@
---
applyTo: "_scripts/**/*.js"
---
# JavaScript Scripts Instructions
## Overview
The `_scripts/` directory contains JavaScript files that provide frontend functionality for the al-folio website. These scripts handle:
- **Search functionality** Ninja-keys integration for search bar
- **Analytics setup** Google Analytics, Cronitor, Open Panel integrations
- **Gallery functionality** PhotoSwipe lightbox initialization
- **Liquid template processing** Files with `.liquid.js` extension process Jekyll Liquid syntax
## Key Script Files
### `search.liquid.js`
- **Purpose:** Generates searchable navigation data for the Ninja-keys search component
- **Type:** Liquid + JavaScript hybrid (Jekyll processes `.liquid.js` files)
- **Output:** Compiled to `/assets/js/search-data.js` via permalink frontmatter
- **Content:** Builds `ninja.data` array from site pages, posts, and navigation structure
- **Usage:** Included in `_includes/scripts.liquid` and loaded in layouts
### `photoswipe-setup.js`
- **Purpose:** Initializes PhotoSwipe lightbox for image galleries
- **Type:** Pure JavaScript with ES6 imports
- **Output:** Compiled to `/assets/js/photoswipe-setup.js`
- **Dependencies:** PhotoSwipe library (referenced via `site.third_party_libraries`)
- **Functionality:** Automatically converts `.pswp-gallery` elements into interactive lightbox galleries
### `google-analytics-setup.js`, `cronitor-analytics-setup.js`, `open-panel-analytics-setup.js`
- **Purpose:** Initialize third-party analytics services
- **Type:** Conditional setup scripts (may be excluded from production builds)
- **Usage:** Loaded conditionally based on `_config.yml` feature flags
- **Integration:** Each sets up tracking code for respective analytics platforms
## File Structure & Frontmatter
All scripts in `_scripts/` may include Jekyll frontmatter:
```javascript
---
permalink: /assets/js/filename.js
---
// JavaScript code here
```
**Key frontmatter fields:**
- `permalink:` Specifies output path in compiled site (e.g., `/assets/js/search-data.js`)
- Comments/empty Files with only JavaScript and no frontmatter are processed as-is
**Processing:**
- `.liquid.js` files Processed by Jekyll's Liquid engine before JavaScript compilation
- `.js` files Processed normally, passed through to assets directory
- **Note:** Files in `_scripts/` are ignored by Prettier (see `.prettierignore`) because `.liquid.js` files mix Liquid template syntax with JavaScript, which Prettier doesn't support
## JavaScript Patterns in al-folio
### Liquid + JavaScript Mixing (in `.liquid.js` files)
Example from `search.liquid.js`:
```javascript
---
permalink: /assets/js/search-data.js
---
// Regular JavaScript
const ninja = document.querySelector('ninja-keys');
// Liquid processing - Jekyll loops and variables
ninja.data = [
{%- for page in site.pages -%}
{
id: "nav-{{ page.title | slugify }}",
title: "{{ page.title }}",
handler: () => {
window.location.href = "{{ page.url | relative_url }}";
},
},
{%- endfor -%}
];
```
**Important:**
- Use Liquid filters (`| slugify`, `| relative_url`, `| escape`) to process Jekyll variables
- Curly braces `{{ }}` output variables
- Use `{%- -%}` (with hyphens) to control whitespace in generated output
- Keep JSON structures valid after Liquid processing
### ES6 Modules & Imports
Scripts use modern JavaScript with ES6 imports:
```javascript
import PhotoSwipeLightbox from "{{ site.third_party_libraries.photoswipe-lightbox.url.js }}";
import PhotoSwipe from "{{ site.third_party_libraries.photoswipe.url.js }}";
```
- Import third-party libraries via `site.third_party_libraries` configuration
- Libraries resolved from `_config.yml` CDN or local paths
### DOM Manipulation & Event Handlers
Scripts attach to specific DOM elements:
```javascript
const element = document.querySelector(".selector");
element.addEventListener("click", (event) => {
// Handle event
});
```
## Common Modification Patterns
### Adding a New Analytics Service
1. Create new file `_scripts/myservice-setup.js`:
```javascript
---
permalink: /assets/js/myservice-setup.js
---
(function() {
// Initialize your service
if (window.myService) {
console.log('MyService loaded');
}
})();
```
2. Add conditional loading to `_includes/scripts.liquid`:
```liquid
{% if site.myservice_enabled %}
<script src="{{ '/assets/js/myservice-setup.js' | relative_url }}"></script>
{% endif %}
```
3. Add feature flag to `_config.yml`:
```yaml
myservice_enabled: false
```
### Modifying Search Data Structure
In `search.liquid.js`:
1. Identify the Liquid loop building `ninja.data` array
2. Add new properties to each object:
```javascript
{
id: "nav-{{ title | slugify }}",
title: "{{ title }}",
newField: "{{ page.new_property }}", // Add new field
handler: () => { ... }
}
```
3. Rebuild: `docker compose up` will regenerate `/assets/js/search-data.js`
### Updating Gallery Functionality
In `photoswipe-setup.js`:
1. Modify gallery selector or initialization options
2. Reference [PhotoSwipe documentation](https://photoswipe.com/) for available options
3. Update any CSS classes used in gallery markup
## Code Style Notes
**Prettier and \_scripts/:**
Files in `_scripts/` are **excluded from Prettier formatting** (defined in `.prettierignore`) because:
- `.liquid.js` files contain mixed Liquid template syntax and JavaScript
- Prettier doesn't understand or support this hybrid format
- Manual formatting consistency is required for these files
**When modifying \_scripts/ files:**
- Follow existing code style in the file (indentation, spacing, quotes)
- Maintain readability for Liquid + JavaScript mixed code
- Do NOT run Prettier on the `_scripts/` directory
- **DO run Prettier on the rest of the project** when making other changes: `npx prettier . --write`
## Validation & Testing
### Local Build Test
```bash
docker compose up
# Wait 30 seconds for Jekyll to build
# Check for errors in terminal output
# Visit http://localhost:8080 and verify functionality
```
### Checking Generated Output
After `docker compose up`, verify scripts compiled correctly:
```bash
# Check if script files exist in _site/assets/js/
ls _site/assets/js/
# Verify no Liquid syntax in generated output (should be pure JavaScript)
cat _site/assets/js/search-data.js | head -20
```
### Debugging Script Issues
**Script not loading:**
- Check browser DevTools Console for HTTP 404 errors
- Verify `permalink:` frontmatter matches script inclusion paths
- Check that script is actually in `_site/assets/js/` after build
**Liquid syntax errors:**
- Jekyll build will fail with "Liquid Exception" messages
- Check file for unclosed `{% %}` or `{{ }}` tags
- Ensure Liquid filters exist (`| relative_url`, `| slugify`, etc.)
**JavaScript errors:**
- Check browser console for runtime errors
- Verify all imported libraries are defined in `site.third_party_libraries` in `_config.yml`
- Test in both Chrome and Firefox for compatibility
## Trust These Instructions
When modifying JavaScript scripts:
- `.liquid.js` files must have valid Liquid syntax AND valid JavaScript that remains valid after Jekyll processes the Liquid
- Do NOT run Prettier on `_scripts/` files (they are in `.prettierignore` because of Liquid + JavaScript mixing)
- Test locally with `docker compose up` to verify build succeeds and scripts work
- For site-wide script inclusion, modify `_includes/scripts.liquid`
- For configuration (feature flags, third-party URLs), see yaml-configuration.instructions.md
- Reference the actual script files in `_scripts/` as examples when adding new functionality
- Only search for additional details if errors occur during build or testing

View File

@ -0,0 +1,100 @@
---
applyTo: "**/*.liquid"
---
# Liquid Templates Instructions
## Liquid Template Basics
This al-folio repository uses Liquid templating extensively. When modifying `.liquid` files:
### Key Directories
- `_includes/` Reusable template components (imported with `{% include %}`)
- `_layouts/` Page layout templates (specified in frontmatter with `layout: name`)
### Common Liquid Tags in al-folio
- `{% include filename.liquid %}` Includes template component
- `{% for item in collection %}...{% endfor %}` Loops
- `{% if condition %}...{% endif %}` Conditionals
- `{{ variable }}` Output variable
- `{% assign var = value %}` Assign variable
- `{% capture %}...{% endcapture %}` Capture output to variable
- `| date: format` Date filtering
- `| where: "key", "value"` Collection filtering
### Important al-folio Liquid Components
- `_includes/citation.liquid` Bibliography entry rendering
- `_includes/distill_scripts.liquid` Distill.pub specific scripts
- `_includes/footer.liquid` Site footer
- `_includes/head.liquid` Page <head> section
- `_includes/header.liquid` Site header/navigation
- `_includes/projects.liquid` Project display
- `_includes/scripts.liquid` Global scripts
- `_includes/selected_papers.liquid` Featured publications display
### Prettier Formatting for Liquid
Prettier with `@shopify/prettier-plugin-liquid` enforces formatting:
- Single quotes around strings in Liquid tags
- Consistent spacing
- Indentation with 2 spaces
- Run `npx prettier . --write` before committing
## Common Modification Patterns
### Modifying Site Header/Navigation
- Edit `_includes/header.liquid`
- Add links to navigation array in `_config.yml` (see yaml-configuration.instructions.md)
- Test by viewing site in browser: `docker compose up` → http://localhost:8080
### Adding a New Component Include
1. Create new file in `_includes/mycomponent.liquid`
2. Use Liquid syntax for conditionals, loops, and variable output
3. Call it from templates: `{% include mycomponent.liquid %}`
4. Test: `docker compose up`
### Adjusting Styling with Liquid
- Some SCSS variables can be controlled via Liquid logic
- Avoid mixing complex Liquid with CSS; keep templates focused
## Validation Before Committing
**Always run these checks:**
1. **Prettier format check:**
```bash
npx prettier _includes/ _layouts/ --check
npx prettier . --write # Fix formatting
```
2. **Build test:**
```bash
docker compose down
docker compose up
# Wait 30 seconds, check for errors in output
# No "Unknown tag" messages should appear
```
3. **Visual verification:**
- Open http://localhost:8080
- Check that your changes rendered correctly
- Verify no broken layout or missing content
## Trust These Instructions
When working with Liquid templates:
- Use `_includes/` and `_layouts/` as reference for syntax patterns
- Follow existing formatting in files (Prettier will enforce consistency)
- Always test locally before pushing (build must succeed)
- For configuration changes, see yaml-configuration.instructions.md
- Only search for additional details if error messages reference unfamiliar Liquid tags or Jekyll concepts

View File

@ -0,0 +1,277 @@
---
applyTo: "_books/**/*.md,_news/**/*.md,_pages/**/*.md,_posts/**/*.md,_projects/**/*.md,_teachings/**/*.md"
---
# Content Files (Markdown) Instructions
## File Organization
Content in al-folio is organized by type:
- **\_books/** Book reviews and summaries
- **\_news/** News/announcements
- **\_pages/** Static pages (about, CV, publications, projects, etc.)
- **\_posts/** Blog posts (format: `YYYY-MM-DD-title.md`)
- **\_projects/** Project showcase entries
- **\_teachings/** Course and teaching information
## Frontmatter Structure
Every markdown file requires YAML frontmatter at the top. The structure varies by content type.
### Book Frontmatter (\_books/)
```yaml
---
layout: book-review
title: Book Title
author: Book Author Name
publisher: Publisher Name
year: 2023
rating: 8/10
img: /assets/img/book-cover.jpg
---
```
### News Frontmatter (\_news/)
```yaml
---
layout: post
title: News Title
date: YYYY-MM-DD
---
```
### Page Frontmatter (\_pages/)
```yaml
---
layout: page
title: Page Title
permalink: /pathname/
description: Brief description for metadata
---
```
### Blog Post Frontmatter (\_posts/)
```yaml
---
layout: post
title: Post Title
date: YYYY-MM-DD
categories: category-name
description: Brief description
---
```
**Important:** Post filenames MUST follow format: `YYYY-MM-DD-title.md` (hyphen-separated words)
### Project Frontmatter (\_projects/)
```yaml
---
layout: page
title: Project Name
description: Short description
img: /assets/img/project-image.jpg
importance: 1
---
```
### Teaching/Course Frontmatter (\_teachings/)
```yaml
---
layout: page
title: Course Title
description: Course description
---
```
## Special Frontmatter Fields
### For Books
- **author:** Author name or comma-separated list
- **publisher:** Publisher name
- **year:** Publication year
- **rating:** Personal rating (e.g., `8/10`)
- **img:** Path to book cover image (`/assets/img/...`)
### For Blog Posts
- **categories:** Tag for post organization (single word, no spaces)
- **related_posts:** Set to `false` to disable related posts display (useful for short posts)
### For Projects
- **importance:** Integer (1, 2, 3...) higher = featured first
- **img:** Path to thumbnail image (`/assets/img/...`)
- **featured:** Set to `true` to display on main projects section
### Date Format
Always use ISO 8601: `YYYY-MM-DD` (e.g., `2023-12-25`)
## Markdown Content
### Basic Markdown Syntax
```markdown
# Heading 1
## Heading 2
### Heading 3
**bold text**
_italic text_
`inline code`
- List item 1
- List item 2
[Link text](https://url.com)
![Image alt text](/path/to/image.jpg)
```
### al-folio-Specific Features
#### Includes/Shortcodes
- `{% include figure.liquid ... %}` Responsive images with captions
- `{% include audio.liquid ... %}` Audio player
- `{% include video.liquid ... %}` Video player
- `{% include bib_search.liquid ... %}` Bibliography search
- `{% include calendar.liquid ... %}` Event calendar
#### Math Support
```markdown
Inline: $E = mc^2$
Display mode:
$$\int_0^1 f(x) dx$$
```
#### Code Blocks
````markdown
```python
def hello():
print("Hello, world!")
```
````
#### Blockquotes
```markdown
> This is a quote
>
> > Nested quote
```
### Jekyll Features Available
- **Liquid variables:** `{{ site.title }}`, `{{ page.title }}`
- **Collections:** `{{ site.posts }}`, `{{ site.projects }}`
- **Filters:** `| date: format`, `| where: key value`
- **Tags:** `{% if condition %} ... {% endif %}`
## Common Content Patterns
### Creating a Blog Post
1. Create file: `_posts/YYYY-MM-DD-my-post.md`
2. Add frontmatter with `layout: post`, `title`, `date`, `categories`
3. Write markdown content
4. Test: `docker compose up` → http://localhost:8080/blog
5. Post will appear in reverse chronological order
### Creating a Project Entry
1. Create file: `_projects/project-name.md`
2. Add frontmatter with `layout: page`, `title`, `description`, `img`, `importance`
3. Write markdown content describing the project
4. Test: `docker compose up` → http://localhost:8080/projects
### Adding Images
```markdown
{% include figure.liquid path="/assets/img/example.jpg" title="Image caption" %}
```
### Linking to Other Pages
```markdown
[About Me](/about/)
[My CV](/cv/)
[Blog Post]({% link _posts/2023-01-15-my-post.md %})
```
## Testing & Validation
### Before Committing
1. **Frontmatter syntax:** Verify YAML is valid (no unclosed quotes, proper indentation)
2. **Date format:** Check `YYYY-MM-DD` format is correct
3. **Build test:**
```bash
docker compose down
docker compose up
# Wait for "Server running" message
# Navigate to your content in browser
# Verify formatting, images, and links work
```
### Common Issues
- **Post not appearing:** Check `date` is today or earlier, filename format is correct
- **Images not loading:** Verify path starts with `/assets/`, file exists
- **Related posts error:** Content has no meaningful words; add more text or set `related_posts: false`
## File Naming Conventions
### Blog Posts
- Format: `YYYY-MM-DD-title-with-hyphens.md`
- Example: `2023-12-25-christmas-post.md`
- Words separated by hyphens, no spaces
### Projects
- Format: `project-name.md`
- Example: `my-research-project.md`
- Use hyphens for readability
### Pages
- Format: `descriptive-name.md`
- Example: `about.md`, `teaching.md`, `cv.md`
## Markdown Linting & Formatting
The Prettier formatter applies to markdown files:
- **Line length:** Soft wrap at 88 characters
- **Lists:** Consistent bullet formatting
- **Code blocks:** Proper fence syntax
- **Spacing:** Consistent blank lines
**Always run before committing:**
```bash
npx prettier --write .
```
## Trust These Instructions
When creating or editing content:
- Follow the frontmatter structure for your content type
- Test locally with `docker compose up` to verify appearance
- Check date format, filename format, and image paths
- Only search for advanced features if frontmatter or markdown error messages appear

View File

@ -0,0 +1,250 @@
---
applyTo: "_config.yml,_data/**/*.yml"
---
# YAML Configuration Instructions
## YAML Configuration (\_config.yml)
### Critical Settings for Agents
When modifying `_config.yml`, always update these in pairs:
- **url** and **baseurl** must be consistent:
- Personal site: `url: https://username.github.io`, `baseurl:` (leave empty)
- Project site: `url: https://username.github.io`, `baseurl: /projectname/`
- **title, first_name, last_name** Site header and metadata
- **description** Used in RSS feeds and metadata
- **lang** Language code (e.g., "en", "fr")
### Feature Flags in \_config.yml
Look for `enabled: false/true` patterns. Common ones:
- `blog.enabled`
- `news.enabled`
- `profile.image_circular`
- `profile.show_social_links`
- `projects.enabled`
- `publications.enabled`
- `related_blog_posts`
### YAML Syntax Rules
- Quote string values containing special characters: `":"`
- Use `>` for multi-line strings (ignore newlines)
- Use `|` for multi-line strings (preserve newlines)
- Indentation matters: always use spaces (2 spaces), never tabs
- No tabs allowed; use only spaces
### Testing YAML Syntax
If you modify `_config.yml`, verify syntax by running:
```bash
docker compose up
# Site should start without YAML parse errors
# Check output for "YAML parse error" or "valid YAML"
```
## Data Files (\_data/\*.yml)
Data files provide structured content that templates can access via Liquid. Each file serves a specific purpose.
### socials.yml
Defines social media links and contact information displayed on the site.
**Format:** Entries are displayed in the order they are defined (not alphabetically sorted)
**For standard socials:** Use the key with the appropriate value. Common built-in socials include:
- `email:` Email address
- `cv_pdf:` Path to CV PDF file
- `scholar_userid:` Google Scholar ID
- `inspirehep_id:` Inspire HEP author ID
- `rss_icon:` Boolean to show/hide RSS icon
- And many others (see [jekyll-socials documentation](https://github.com/george-gca/jekyll-socials) for full list)
**For custom socials:** Define a custom entry with nested fields:
- `logo:` URL or path to logo image
- `title:` Display name
- `url:` Profile or website URL
**Example:**
```yaml
cv_pdf: /assets/pdf/example_pdf.pdf
email: you@example.com
scholar_userid: qc6CJjYAAAAJ
github_username: username
linkedin_username: username
custom_social:
logo: https://example.com/logo.png
title: Custom Profile
url: https://example.com/
```
For more information, see the [jekyll-socials documentation](https://github.com/george-gca/jekyll-socials).
### cv.yml
CV content in **RenderCV format** (recommended approach for generating professional CVs).
**Format:** [RenderCV](https://rendercv.com/) YAML format — human-readable and designed specifically for professional resumes with automatic PDF generation capability.
**Key Files:**
- [`_data/cv.yml`](_data/cv.yml) — Main CV content in RenderCV format
- [`assets/rendercv/design.yaml`](assets/rendercv/design.yaml) — Design and styling customization
- [`assets/rendercv/locale.yaml`](assets/rendercv/locale.yaml) — Localization and text formatting
- [`assets/rendercv/settings.yaml`](assets/rendercv/settings.yaml) — RenderCV-specific settings
**Usage:** Rendered by `cv.liquid` layout on CV page; displayed in `about.liquid` on home page.
**Automatic PDF Generation:** When using RenderCV format, a GitHub Actions workflow (`render-cv.yml`) automatically generates a PDF version whenever you push changes to `_data/cv.yml`. The generated PDF is saved to `assets/rendercv/rendercv_output/` and can be linked via `cv_pdf` setting in `_config.yml`.
**Alternative Format (JSONResume):** For an alternative format, see `assets/json/resume.json` which uses the [JSONResume](https://jsonresume.org/) standard. Switch between formats using the `cv_format` frontmatter variable in `_pages/cv.md` (options: `rendercv` or `jsonresume`).
**For more details:** See [CUSTOMIZE.md § Modifying the CV information](CUSTOMIZE.md#modifying-the-cv-information) for setup, switching formats, and PDF generation configuration.
### citations.yml
Social media citation counts and metrics.
**Format:** Varies by platform (Google Scholar, ORCID, etc.)
**Example:**
```yaml
scholar_userid: YOUR_SCHOLAR_ID
```
### repositories.yml
GitHub repository listing for the repositories page.
**Format:** List of repository information
**Usage:** Used by repositories page to display GitHub projects
### coauthors.yml
Co-author information for bibliography/publications.
**Mapping:** Author names to profile URLs and affiliations
**Format:** Maps full names to contact info
**Example:**
```yaml
"Einstein, Albert":
url: https://en.wikipedia.org/wiki/Albert_Einstein
affiliation: Princeton University
```
## Common Modification Patterns
### Adding a New Feature Flag
1. Add to `_config.yml`:
```yaml
my_feature:
enabled: true
```
2. In Liquid templates use:
```liquid
{% if site.my_feature.enabled %}
... content ...
{% endif %}
```
3. Document the flag in CUSTOMIZE.md
### Updating Social Media Links
1. Edit `_data/socials.yml`
2. Keep entries alphabetically sorted
3. Ensure `icon` identifiers match available icons (Academicons or Font Awesome)
4. Use full profile URLs in `url` field
5. Test: `docker compose up` → check social icons on site
### Modifying Site Metadata
Update these in `_config.yml`:
- **title** Site name
- **first_name, last_name** Your name
- **email** Contact email
- **description** Site tagline (used in RSS, metadata)
- **keywords** Search keywords
### Adding Co-authors
1. Edit `_data/coauthors.yml`
2. Add entry with author name as key
3. Include `url:` and `affiliation:` fields
4. This maps author names in BibTeX to profile links
## Validation Before Committing
**Always run these checks:**
1. **YAML syntax check:**
```bash
# Run Jekyll build to validate YAML
docker compose down
docker compose up
# Wait for "Server running" message
# Check output for "YAML parse error" messages
```
2. **Prettier format check:**
```bash
npx prettier _config.yml _data/ --check
npx prettier . --write # Fix formatting
```
3. **Visual verification:**
- Open http://localhost:8080
- Check that your changes appear correctly
- Verify navigation, social links, and metadata work
- Check site title and description in page source
## Common Issues
### "YAML parse error"
- Check for unquoted special characters (`:`, `&`, `#`, `|`, `>`)
- Verify indentation uses only spaces (2 spaces per level)
- Ensure closing quotes and braces are present
### Feature flag not working
- Check syntax: `feature: enabled: true` (colon after feature name)
- Verify spelling in Liquid template: `{% if site.feature.enabled %}`
- Clear browser cache if using old cached pages
### Social links not appearing
- Verify `_data/socials.yml` has correct entries
- Check icon identifiers exist in Font Awesome or Academicons
- Ensure `url:` field is not empty
## Trust These Instructions
When working with YAML configuration:
- Always test locally with `docker compose up` after changes
- Quote any string containing special characters
- Keep indentation consistent (2 spaces)
- Check output for YAML parse errors before committing
- Only search for additional details if encountering error messages not mentioned here

14
.github/release.yml vendored Normal file
View File

@ -0,0 +1,14 @@
changelog:
exclude:
labels:
- ignore-for-release
categories:
- title: new features 🚀
labels:
- enhancement
- title: bug fixes and improvements ✨
labels:
- bug-fix
- title: other changes 🛠️
labels:
- "*"

74
.github/workflows/axe.yml vendored Normal file
View File

@ -0,0 +1,74 @@
name: Axe accessibility testing
on:
# if you want to run this on every push uncomment the following lines
# push:
# branches:
# - master
# - main
# pull_request:
# branches:
# - master
# - main
workflow_dispatch:
inputs:
url:
description: "URL to be checked (e.g.: blog/)"
required: false
env:
URL: ""
jobs:
check:
# available images: https://github.com/actions/runner-images#available-images
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2.2"
bundler-cache: true
- name: Update _config.yml ⚙️
uses: fjogeleit/yaml-update-action@main
with:
commitChange: false
valueFile: "_config.yml"
changes: |
{
"giscus.repo": "${{ github.repository }}",
"baseurl": ""
}
- name: Install and Build 🔧
run: |
sudo apt-get update && sudo apt-get install -y imagemagick
pip3 install --upgrade jupyter
export JEKYLL_ENV=production
bundle exec jekyll build
- name: Purge unused CSS 🧹
run: |
npm install -g purgecss
purgecss -c purgecss.config.js
- name: Get Chromium version 🌐
# https://github.com/GoogleChromeLabs/chrome-for-testing?tab=readme-ov-file#other-api-endpoints
run: |
CHROMIUM_VERSION=$(wget -qO- https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_STABLE | cut -d. -f1)
echo "Chromium version: $CHROMIUM_VERSION"
echo "CHROMIUM_VERSION=$CHROMIUM_VERSION" >> $GITHUB_ENV
- name: Setup Chrome 🌐
id: setup-chrome
uses: browser-actions/setup-chrome@v1
with:
chrome-version: ${{ env.CHROMIUM_VERSION }}
- name: Install chromedriver 🚗
run: |
npm install -g chromedriver@$CHROMIUM_VERSION
- name: Run axe 🪓
# https://github.com/dequelabs/axe-core-npm/tree/develop/packages/cli
run: |
npm install -g @axe-core/cli
npm install -g http-server
http-server _site/ &
axe --chromedriver-path $(npm root -g)/chromedriver/bin/chromedriver http://localhost:8080/${{ github.event.inputs.url || env.URL }} --load-delay=1500 --exit

47
.github/workflows/broken-links-site.yml vendored Normal file
View File

@ -0,0 +1,47 @@
name: Check for broken links on site
on:
workflow_run:
workflows: [Deploy site]
types: [completed]
jobs:
check-links-on-site:
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-a-workflow-based-on-the-conclusion-of-another-workflow
if: ${{ github.event.workflow_run.conclusion == 'success' }}
# available images: https://github.com/actions/runner-images#available-images
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2.2"
bundler-cache: true
- name: Update _config.yml ⚙️
uses: fjogeleit/yaml-update-action@main
with:
commitChange: false
valueFile: "_config.yml"
changes: |
{
"giscus.repo": "${{ github.repository }}",
"baseurl": ""
}
- name: Install and Build 🔧
run: |
sudo apt-get update && sudo apt-get install -y imagemagick
pip3 install --upgrade jupyter
export JEKYLL_ENV=production
bundle exec jekyll build
- name: Purge unused CSS 🧹
run: |
npm install -g purgecss
purgecss -c purgecss.config.js
- name: Link Checker 🔗
uses: lycheeverse/lychee-action@v2.0.2
with:
fail: true
# only check local links
args: --offline --remap '_site(/?.*)/assets/(.*) _site/assets/$2' --verbose --no-progress '_site/**/*.html'

54
.github/workflows/broken-links.yml vendored Normal file
View File

@ -0,0 +1,54 @@
name: Check for broken links
on:
push:
branches:
- master
- main
paths:
- "assets/**"
- "**.html"
- "**.js"
- "**.liquid"
- "**/*.md"
- "**.yml"
- "!.github/workflows/axe.yml"
- "!.github/workflows/deploy-docker-tag.yml"
- "!.github/workflows/deploy-image.yml"
- "!.github/workflows/docker-slim.yml"
- "!.github/workflows/lighthouse-badger.yml"
- "!.github/workflows/prettier.yml"
- "!lighthouse_results/**"
pull_request:
branches:
- master
- main
paths:
- "assets/**"
- "**.html"
- "**.js"
- "**.liquid"
- "**/*.md"
- "**.yml"
- "!.github/workflows/axe.yml"
- "!.github/workflows/deploy-docker-tag.yml"
- "!.github/workflows/deploy-image.yml"
- "!.github/workflows/docker-slim.yml"
- "!.github/workflows/lighthouse-badger.yml"
- "!.github/workflows/prettier.yml"
- "!lighthouse_results/**"
jobs:
link-checker:
runs-on: ubuntu-latest
# only run on the main repo
if: github.repository == 'alshedivat/al-folio'
steps:
- uses: actions/checkout@v4
- name: Link Checker 🔗
uses: lycheeverse/lychee-action@v2.0.2
with:
fail: true
# removed md files that include liquid tags
args: --user-agent 'curl/7.54' --exclude-path README.md --exclude-path _pages/404.md --exclude-path _pages/blog.md --exclude-path _posts/2018-12-22-distill.md --exclude-path _posts/2023-04-24-videos.md --exclude-path _books/the_godfather.md --exclude-path .github/instructions/bibtex-bibliography.instructions.md --exclude-path .github/instructions/yaml-configuration.instructions.md --exclude-path .github/instructions/markdown-content.instructions.md --exclude-path .github/instructions/liquid-templates.instructions.md --exclude-path AGENTS.md --exclude-path SEO.md --verbose --no-progress './**/*.md' './**/*.html'

94
.github/workflows/codeql.yml vendored Normal file
View File

@ -0,0 +1,94 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
schedule:
- cron: "45 4 * * 3"
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: javascript-typescript
build-mode: none
- language: ruby
build-mode: none
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

View File

@ -0,0 +1,58 @@
name: "Copilot Setup Steps"
# Automatically run the setup steps when they are changed to allow for easy validation, and
# allow manual testing through the repository's "Actions" tab
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-latest
# Set the permissions to the lowest permissions possible needed for your steps.
# Copilot will be given its own token for its operations.
permissions:
contents: read
# You can define any steps you want, and they will run before the agent starts.
# If you do not check out your code, Copilot will do this for you.
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3.5"
bundler-cache: true
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
cache: "pip"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "latest"
cache: "npm"
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y imagemagick
- name: Install Python dependencies
run: |
pip3 install --upgrade nbconvert
- name: Install Node.js dependencies
run: npm ci

View File

@ -3,38 +3,48 @@ name: Docker Image CI (Upload Tag)
on: on:
push: push:
tags: tags:
- 'v*' - "v*"
paths:
- ".github/workflows/deploy-docker-tag.yml"
- ".github/workflows/deploy-image.yml"
- "bin/entry_point.sh"
- "Dockerfile"
- "Gemfile"
- "Gemfile.lock"
- "package.json"
- "package-lock.json"
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Buildx
uses: docker/setup-buildx-action@v1
- - name: Set up QEMU
name: Docker meta uses: docker/setup-qemu-action@v3
id: meta
uses: docker/metadata-action@v4
with:
images: amirpourmand/al-folio
- name: Login - name: Buildx
uses: docker/login-action@v1 uses: docker/setup-buildx-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push - name: Docker meta
uses: docker/build-push-action@v3 id: meta
with: uses: docker/metadata-action@v5
context: . with:
push: ${{ github.event_name != 'pull_request' }} images: amirpourmand/al-folio
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64/v8
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@ -2,30 +2,43 @@ name: Docker Image CI
on: on:
push: push:
branches: [ master ] branches:
- master
jobs: - main
paths:
- ".github/workflows/deploy-image.yml"
- "bin/entry_point.sh"
- "Dockerfile"
- "Gemfile"
- "Gemfile.lock"
- "package.json"
- "package-lock.json"
jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository_owner == 'alshedivat' if: github.repository_owner == 'alshedivat'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Buildx
uses: docker/setup-buildx-action@v1
- name: Login - name: Set up QEMU
uses: docker/login-action@v1 uses: docker/setup-qemu-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }} - name: Buildx
password: ${{ secrets.DOCKER_PASSWORD }} uses: docker/setup-buildx-action@v3
- name: Build and push - name: Login
uses: docker/build-push-action@v2 uses: docker/login-action@v3
with: with:
context: . username: ${{ secrets.DOCKER_USERNAME }}
push: true password: ${{ secrets.DOCKER_PASSWORD }}
tags: amirpourmand/al-folio
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64/v8
tags: amirpourmand/al-folio

View File

@ -1,42 +1,105 @@
name: deploy name: Deploy site
on: on:
push: push:
branches: branches:
- master - master
- main - main
paths:
- "assets/**"
- "_sass/**"
- "_scripts/**"
- "**.bib"
- "**.html"
- "**.js"
- "**.liquid"
- "**/*.md"
- "**.yml"
- "Gemfile"
- "Gemfile.lock"
- "!.github/workflows/axe.yml"
- "!.github/workflows/broken-links.yml"
- "!.github/workflows/deploy-docker-tag.yml"
- "!.github/workflows/deploy-image.yml"
- "!.github/workflows/docker-slim.yml"
- "!.github/workflows/lighthouse-badger.yml"
- "!.github/workflows/prettier.yml"
- "!lighthouse_results/**"
- "!CONTRIBUTING.md"
- "!CUSTOMIZE.md"
- "!FAQ.md"
- "!INSTALL.md"
- "!README.md"
pull_request: pull_request:
branches: branches:
- master - master
- main - main
paths:
- "assets/**"
- "_sass/**"
- "_scripts/**"
- "**.bib"
- "**.html"
- "**.js"
- "**.liquid"
- "**/*.md"
- "**.yml"
- "Gemfile"
- "Gemfile.lock"
- "!.github/workflows/axe.yml"
- "!.github/workflows/broken-links.yml"
- "!.github/workflows/deploy-docker-tag.yml"
- "!.github/workflows/deploy-image.yml"
- "!.github/workflows/docker-slim.yml"
- "!.github/workflows/lighthouse-badger.yml"
- "!.github/workflows/prettier.yml"
- "!lighthouse_results/**"
- "!CONTRIBUTING.md"
- "!CUSTOMIZE.md"
- "!FAQ.md"
- "!INSTALL.md"
- "!README.md"
workflow_dispatch:
permissions:
contents: write
jobs: jobs:
deploy: deploy:
# available images: https://github.com/actions/runner-images#available-images
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout 🛎️
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Setup Ruby - name: Setup Ruby 💎
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:
ruby-version: '3.0.2' ruby-version: "3.3.5"
bundler-cache: true bundler-cache: true
- name: Install deps - name: Setup Python 🐍
run: | uses: actions/setup-python@v5
npm install -g mermaid.cli with:
- name: Setup deploy options python-version: "3.13"
id: setup cache: "pip" # caching pip dependencies
run: | - name: Update _config.yml ⚙️
git config --global user.name "GitHub Action" uses: fjogeleit/yaml-update-action@main
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" with:
if [[ ${GITHUB_REF} = refs/pull/*/merge ]]; then # pull request commitChange: false
echo "SRC_BRANCH=${GITHUB_HEAD_REF}" >> $GITHUB_OUTPUT valueFile: "_config.yml"
echo "NO_PUSH=--no-push" >> $GITHUB_OUTPUT propertyPath: "giscus.repo"
elif [[ ${GITHUB_REF} = refs/heads/* ]]; then # branch, e.g. master, source etc value: ${{ github.repository }}
echo "SRC_BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT - name: Install and Build 🔧
fi run: |
echo "DEPLOY_BRANCH=gh-pages" >> $GITHUB_OUTPUT sudo apt-get update && sudo apt-get install -y imagemagick
- name: Deploy website pip3 install --upgrade nbconvert
run: yes | bash bin/deploy --verbose ${{ steps.setup.outputs.NO_PUSH }} export JEKYLL_ENV=production
--src ${{ steps.setup.outputs.SRC_BRANCH }} bundle exec jekyll build
--deploy ${{ steps.setup.outputs.DEPLOY_BRANCH }} - name: Purge unused CSS 🧹
run: |
npm install -g purgecss
purgecss -c purgecss.config.js
- name: Deploy 🚀
if: github.event_name != 'pull_request'
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: _site

53
.github/workflows/docker-slim.yml vendored Normal file
View File

@ -0,0 +1,53 @@
name: Docker Slim
#Only trigger, when the build workflow succeeded
on:
push:
branches:
- master
- main
paths:
- ".github/workflows/docker-slim.yml"
workflow_run:
workflows: ["Docker Image CI"]
types:
- completed
workflow_dispatch:
jobs:
build:
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-a-workflow-based-on-the-conclusion-of-another-workflow
if: ${{ github.event.workflow_run.conclusion == 'success' && github.repository_owner == 'alshedivat' }}
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ github.workspace }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: update docker-compose
shell: bash
run: |
sed -i "s|\.:|${{ github.workspace }}:|g" ${{ github.workspace }}/docker-compose.yml
cat ${{ github.workspace }}/docker-compose.yml
- uses: kitabisa/docker-slim-action@v1.2.0
env:
DSLIM_PULL: true
DSLIM_COMPOSE_FILE: ${{ github.workspace }}/docker-compose.yml
DSLIM_TARGET_COMPOSE_SVC: jekyll
DSLIM_CONTINUE_AFTER: signal
with:
target: amirpourmand/al-folio
tag: "slim"
# Push to the registry
- run: docker image push amirpourmand/al-folio:slim

62
.github/workflows/lighthouse-badger.yml vendored Normal file
View File

@ -0,0 +1,62 @@
# Lighthouse-Badger-Easy | GitHub Action Workflow
#
# Description: Generates, adds & updates manually/automatically Lighthouse badges & reports from one/multiple input URL(s) to the current repository & main branch with minimal settings
# Author: Sitdisch
# Source: https://github.com/myactionway/lighthouse-badger-workflows
# License: MIT
# Copyright (c) 2021 Sitdisch
name: "Lighthouse Badger"
########################################################################
# DEFINE YOUR INPUTS AND TRIGGERS IN THE FOLLOWING
########################################################################
# INPUTS as Secrets (env) for not manually triggered workflows
env:
URLS: https://alshedivat.github.io/al-folio/
# If any of the following env is blank, a default value is used instead
REPO_BRANCH: "${{ github.repository }} master" # target repository & branch e.g. 'dummy/mytargetrepo main'
MOBILE_LIGHTHOUSE_PARAMS: "--only-categories=performance,accessibility,best-practices,seo --throttling.cpuSlowdownMultiplier=2"
DESKTOP_LIGHTHOUSE_PARAMS: "--only-categories=performance,accessibility,best-practices,seo --preset=desktop --throttling.cpuSlowdownMultiplier=1"
# TRIGGERS
on:
page_build:
# schedule: # Check your schedule here => https://crontab.guru/
# - cron: '55 23 * * 0' # e.g. every Sunday at 23:55
#
# THAT'S IT; YOU'RE DONE;
workflow_dispatch:
########################################################################
# THAT'S IT; YOU DON'T HAVE TO DEFINE ANYTHING IN THE FOLLOWING
########################################################################
jobs:
lighthouse-badger-easy:
runs-on: ubuntu-latest
timeout-minutes: 8
steps:
- name: Preparatory Tasks
run: |
REPOSITORY=`expr "${{ env.REPO_BRANCH }}" : "\([^ ]*\)"`
BRANCH=`expr "${{ env.REPO_BRANCH }}" : ".* \([^ ]*\)"`
echo "REPOSITORY=$REPOSITORY" >> $GITHUB_ENV
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
env:
REPO_BRANCH: ${{ env.REPO_BRANCH }}
- uses: actions/checkout@v4
with:
repository: ${{ env.REPOSITORY }}
token: ${{ secrets.LIGHTHOUSE_BADGER_TOKEN }}
ref: ${{ env.BRANCH }}
- uses: actions/checkout@v4
with:
repository: "myactionway/lighthouse-badges"
path: temp_lighthouse_badges_nested
- uses: myactionway/lighthouse-badger-action@v2.2
with:
urls: ${{ env.URLS }}
mobile_lighthouse_params: ${{ env.MOBILE_LIGHTHOUSE_PARAMS }}
desktop_lighthouse_params: ${{ env.DESKTOP_LIGHTHOUSE_PARAMS }}

View File

@ -0,0 +1,18 @@
name: Comment on pull request
on:
repository_dispatch:
types: [prettier-failed-on-pr]
jobs:
comment:
# available images: https://github.com/actions/runner-images#available-images
runs-on: ubuntu-latest
steps:
- name: PR comment with html diff 💬
uses: thollander/actions-comment-pull-request@v2
with:
comment_tag: prettier-failed
pr_number: ${{ github.event.client_payload.pr_number }}
message: |
Failed [prettier code check](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.client_payload.run_id }}). Check [this file](${{ github.event.client_payload.artifact_url }}) for more information.

36
.github/workflows/prettier-html.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: Prettify gh-pages
on:
workflow_dispatch:
jobs:
format:
runs-on: ubuntu-latest
steps:
- name: Checkout gh-pages branch
uses: actions/checkout@v4
with:
ref: gh-pages
- name: Find and Remove </source> Tags
run: find . -type f -name "*.html" -exec sed -i 's/<\/source>//g' {} +
- name: Set up Node.js
uses: actions/setup-node@v4
- name: Install Prettier
run: npm install -g prettier
- name: Check for Prettier
run: npx prettier --version || echo "Prettier not found"
- name: Run Prettier on HTML files
run: npx prettier --write '**/*.html'
- name: Commit and push changes
run: |
git config user.name "github-actions"
git config user.email "actions@github.com"
git add .
git commit -m "Formatted HTML files" || echo "No changes to commit"
git push

48
.github/workflows/prettier.yml vendored Normal file
View File

@ -0,0 +1,48 @@
name: Prettier code formatter
on:
pull_request:
branches:
- master
- main
push:
branches:
- master
- main
jobs:
check:
# available images: https://github.com/actions/runner-images#available-images
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v4
- name: Setup Node.js ⚙️
uses: actions/setup-node@v4
- name: Install Prettier 💾
run: npm install --save-dev --save-exact prettier @shopify/prettier-plugin-liquid
- name: Prettier Check 🔎
id: prettier
run: npx prettier . --check
- name: Create diff 📝
# https://docs.github.com/en/actions/learn-github-actions/expressions#failure
if: ${{ failure() }}
run: |
npx prettier . --write
git diff -- . ':(exclude)package-lock.json' ':(exclude)package.json' > diff.txt
npm install -g diff2html-cli
diff2html -i file -s side -F diff.html -- diff.txt
- name: Upload html diff ⬆️
id: artifact-upload
if: ${{ failure() && steps.prettier.conclusion == 'failure' }}
uses: actions/upload-artifact@v4
with:
name: HTML Diff
path: diff.html
retention-days: 7
- name: Dispatch information to repository 🗣️
if: ${{ failure() && steps.prettier.conclusion == 'failure' && github.event_name == 'pull_request' }}
uses: peter-evans/repository-dispatch@v2
with:
event-type: prettier-failed-on-pr
client-payload: '{"pr_number": "${{ github.event.number }}", "artifact_url": "${{ steps.artifact-upload.outputs.artifact-url }}", "run_id": "${{ github.run_id }}"}'

58
.github/workflows/render-cv.yml vendored Normal file
View File

@ -0,0 +1,58 @@
name: Render a CV
on:
push:
branches:
- main
- master
paths:
- "_data/cv.yml"
- "assets/rendercv/design.yaml"
- "assets/rendercv/locale.yaml"
- "assets/rendercv/settings.yaml"
workflow_call:
workflow_dispatch:
permissions:
contents: write
jobs:
rendercv:
name: RenderCV
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install RenderCV
run: |
pip install -r requirements.txt
- name: RenderCV
run: |
cv_file=$(find _data -maxdepth 1 -type f \( -name "cv.yaml" -o -name "cv.yml" \))
if [ -z "$cv_file" ]; then
echo "No cv.yml file found!"
exit 1
fi
rendercv_dir=$(find assets -maxdepth 1 -type d -name "rendercv")
if [ -z "$rendercv_dir" ]; then
echo "No RenderCV config directory found!"
exit 1
fi
settings=$(find $rendercv_dir -maxdepth 1 -type f \( -name "settings.yaml" -o -name "settings.yml" \))
if [ -z "$settings" ]; then
echo "Missing RenderCV config file!"
exit 1
fi
rendercv render $cv_file --settings $settings
rm assets/rendercv/rendercv_output/*.typ
- name: Upload rendercv_output as an artifact
uses: actions/upload-artifact@v4
with:
name: RenderCV Output
path: assets/rendercv/rendercv_output
- name: Push the changes
run: |
git config --global user.name "${{ github.actor }}"
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
git add -A
git commit -m "chore: render the latest CV"
git push

39
.github/workflows/schedule-posts.txt vendored Normal file
View File

@ -0,0 +1,39 @@
name: Publish posts scheduled for today
on:
schedule:
# Run every day at 23:30 UTC or manually run
- cron: "30 23 * * *"
workflow_dispatch:
jobs:
publish_scheduled:
runs-on: ubuntu-latest
steps:
- name: Checkout main branch
uses: actions/checkout@v4
with:
ref: main
- name: Get the date for today
id: date
run: echo "TODAY=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
- name: Check for scheduled posts and move to posts
run: |
echo "Today is $TODAY"
shopt -s nullglob
for file in _scheduled/${TODAY}-*.md; do
echo "Found scheduled: $file"
mv "$file" "_posts/"
echo "Moved $file to _posts/"
done
- name: Commit and push changes
run: |
git config user.name "github-actions"
git config user.email "actions@github.com"
git add _posts/
git add _scheduled/
git commit -m "Posted Scheduled Drafts on $TODAY" || echo "No changes to commit"
git push

101
.github/workflows/update-citations.yml vendored Normal file
View File

@ -0,0 +1,101 @@
name: Update Google Scholar Citations
on:
schedule:
- cron: "0 0 * * 1" # Monday
- cron: "0 0 * * 3" # Wednesday
- cron: "0 0 * * 5" # Friday
workflow_dispatch:
jobs:
update-citations:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
# See CUSTOMIZE.md for details on how to set up PAT for triggering subsequent workflows
# with:
# token: ${{ secrets.PAT }}
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.13"
- name: Install dependencies
run: |
echo "🔧 Installing dependencies..."
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Save current citations.yml hash
id: before
run: |
echo "📦 Checking existing citations.yml hash..."
if [ -f _data/citations.yml ]; then
sha_before=$(sha256sum _data/citations.yml | awk '{print $1}')
echo "sha_before=$sha_before" >> $GITHUB_OUTPUT
echo "📝 SHA before: $sha_before"
else
echo "sha_before=none" >> $GITHUB_OUTPUT
echo "📝 No existing citations.yml file found."
fi
- name: Run citation update script
id: run_citation_update
shell: bash
run: |
set +e
echo "🚀 Running citation update script (single attempt)..."
start_time=$(date)
timeout 90 python bin/update_scholar_citations.py
status=$?
end_time=$(date)
if [ $status -eq 0 ]; then
echo "✅ Citation update succeeded (started at $start_time, ended at $end_time)."
echo "✅ Citation update succeeded." >> $GITHUB_STEP_SUMMARY
else
echo "❌ Citation update script failed with exit code $status (started at $start_time, ended at $end_time)."
echo "❌ Citation update script failed with exit code $status." >> $GITHUB_STEP_SUMMARY
fi
set -e
- name: Save new citations.yml hash
id: after
run: |
echo "🔍 Checking updated citations.yml hash..."
if [ -f _data/citations.yml ]; then
sha_after=$(sha256sum _data/citations.yml | awk '{print $1}')
echo "sha_after=$sha_after" >> $GITHUB_OUTPUT
echo "📝 SHA after: $sha_after"
else
echo "sha_after=none" >> $GITHUB_OUTPUT
echo "📝 citations.yml was not created or is missing."
fi
- name: Report citations.yml change in summary
run: |
echo "📋 Comparing citation file hashes..."
if [ "${{ steps.before.outputs.sha_before }}" != "${{ steps.after.outputs.sha_after }}" ]; then
echo "✅ _data/citations.yml was updated."
echo "✅ _data/citations.yml was updated." >> $GITHUB_STEP_SUMMARY
else
echo " _data/citations.yml was not changed."
echo " _data/citations.yml was not changed." >> $GITHUB_STEP_SUMMARY
fi
- name: Configure Git
run: |
git config --local user.email "actions@github.com"
git config --local user.name "GitHub Actions"
echo "🔧 Git configured."
- name: Commit and push if changed
run: |
git add _data/citations.yml
git diff --staged --quiet || (
echo "📤 Committing and pushing changes..."
git commit -m "Update Google Scholar citations"
git push
)

50
.github/workflows/update-tocs.yml vendored Normal file
View File

@ -0,0 +1,50 @@
name: Update TOCs
# This workflow automatically updates the Table of Contents (TOC) in markdown files
on:
push:
branches:
- main
- master
paths:
- "*.md"
workflow_dispatch:
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # OR "2" -> To retrieve the preceding commit.
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46
with:
files: ./*.md
- name: Updated toc on all markdown changed files
env:
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
curl https://raw.githubusercontent.com/george-gca/github-markdown-toc/main/gh-md-toc -o gh-md-toc
chmod a+x gh-md-toc
for file in ${ALL_CHANGED_FILES}; do
# Check if the file is a markdown file
if [[ "$file" != *.md ]]; then
continue
fi
./gh-md-toc --indent 2 --insert --no-backup --hide-footer $file
done
rm gh-md-toc
- name: Commit changes
if: steps.changed-files.outputs.any_changed == 'true'
uses: stefanzweifel/git-auto-commit-action@v5.0.1
with:
commit_message: Auto update markdown TOC

12
.gitignore vendored
View File

@ -1,11 +1,15 @@
_site _site
.bundle .bundle
.sass-cache .DS_store
.idea
.jekyll-cache .jekyll-cache
.jekyll-metadata .jekyll-metadata
.DS_store
.ruby-version .ruby-version
.sass-cache
.tweet-cache .tweet-cache
.venv
assets/libs/
assets/rendercv/rendercv_output/*.typ
Gemfile.lock Gemfile.lock
vendor node_modules/
vendor

14
.lycheeignore Normal file
View File

@ -0,0 +1,14 @@
.github/instructions/bibtex-bibliography.instructions.md
.github/instructions/liquid-templates.instructions.md
.github/instructions/markdown-content.instructions.md
.github/instructions/yaml-configuration.instructions.md
_books/the_godfather.md
_pages/404.md
_pages/blog.md
_posts/2018-12-22-distill.md
_posts/2023-04-24-videos.md
AGENTS.md
https://www.linkedin.com/
https://www.reddit.com/
README.md
SEO.md

View File

@ -1,10 +1,10 @@
# See https://pre-commit.com for more information # See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks # See https://pre-commit.com/hooks.html for more hooks
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0 rev: v4.3.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: end-of-file-fixer - id: end-of-file-fixer
- id: check-yaml - id: check-yaml
- id: check-added-large-files - id: check-added-large-files

13
.prettierignore Normal file
View File

@ -0,0 +1,13 @@
**/*.map
**/*.min.css
**/*.min.js
assets/css/main.scss
assets/js/distillpub/template.v2.js
assets/js/search/*.js
assets/plotly/demo.html
lighthouse_results/**
_posts/2015-10-20-math.md
_sass/font-awesome/*.scss
_scripts/*
# Ignore citation YAML file generated by script
_data/citations.yml

3
.prettierrc Normal file
View File

@ -0,0 +1,3 @@
plugins: ["@shopify/prettier-plugin-liquid"]
printWidth: 150
trailingComma: "es5"

81
AGENTS.md Normal file
View File

@ -0,0 +1,81 @@
# Agent Guidelines for al-folio
A simple, clean, and responsive Jekyll theme for academics.
## Quick Links by Role
- **Are you a coding agent?** → Read [`.github/copilot-instructions.md`](.github/copilot-instructions.md) first (tech stack, build, CI/CD, common pitfalls & solutions)
- **Customizing the site?** → See [`.github/agents/customize.agent.md`](.github/agents/customize.agent.md)
- **Writing documentation?** → See [`.github/agents/docs.agent.md`](.github/agents/docs.agent.md)
- **Need setup/deployment help?** → [INSTALL.md](INSTALL.md)
- **Troubleshooting & FAQ?** → [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
- **Customization & theming?** → [CUSTOMIZE.md](CUSTOMIZE.md)
- **Quick 5-min start?** → [QUICKSTART.md](QUICKSTART.md)
## Essential Commands
### Local Development (Docker)
The recommended approach is using Docker.
```bash
# Initial setup & start dev server
docker compose pull && docker compose up
# Site runs at http://localhost:8080
# Rebuild after changing dependencies or Dockerfile
docker compose up --build
# Stop containers and free port 8080
docker compose down
```
### Pre-Commit Checklist
Before every commit, you **must** run these steps:
1. **Format Code:**
```bash
# (First time only)
npm install --save-dev prettier @shopify/prettier-plugin-liquid
# Format all files
npx prettier . --write
```
2. **Build Locally & Verify:**
```bash
# Rebuild the site
docker compose up --build
# Verify by visiting http://localhost:8080.
# Check navigation, pages, images, and dark mode.
```
## Critical Configuration
When modifying `_config.yml`, these **must be updated together**:
- **Personal site:** `url: https://username.github.io` + `baseurl:` (empty)
- **Project site:** `url: https://username.github.io` + `baseurl: /repo-name/`
- **YAML errors:** Quote strings with special characters: `title: "My: Cool Site"`
## Development Workflow
- **Git & Commits:** For commit message format and Git practices, see [.github/GIT_WORKFLOW.md](.github/GIT_WORKFLOW.md).
- **Code-Specific Instructions:** Consult the relevant instruction file for your code type.
| File Type | Instruction File |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Markdown content (`_posts/`, `_pages/`, etc.) | [markdown-content.instructions.md](.github/instructions/markdown-content.instructions.md) |
| YAML config (`_config.yml`, `_data/`) | [yaml-configuration.instructions.md](.github/instructions/yaml-configuration.instructions.md) |
| BibTeX (`_bibliography/`) | [bibtex-bibliography.instructions.md](.github/instructions/bibtex-bibliography.instructions.md) |
| Liquid templates (`_includes/`, `_layouts/`) | [liquid-templates.instructions.md](.github/instructions/liquid-templates.instructions.md) |
| JavaScript (`_scripts/`) | [javascript-scripts.instructions.md](.github/instructions/javascript-scripts.instructions.md) |
## Common Issues
For troubleshooting, see:
- [Common Pitfalls & Workarounds](.github/copilot-instructions.md#common-pitfalls--workarounds) in copilot-instructions.md
- [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for detailed solutions
- [GitHub Issues](https://github.com/alshedivat/al-folio/issues) to search for your specific problem.

186
ANALYTICS.md Normal file
View File

@ -0,0 +1,186 @@
# Analytics Setup Guide
This guide helps you add website analytics to track visitor statistics and behavior.
<!--ts-->
- [Analytics Setup Guide](#analytics-setup-guide)
- [Overview](#overview)
- [Supported Analytics Services](#supported-analytics-services)
- [Google Analytics](#google-analytics)
- [Setup Steps](#setup-steps)
- [Privacy-Friendly Alternatives](#privacy-friendly-alternatives)
- [Pirsch Analytics](#pirsch-analytics)
- [Openpanel Analytics](#openpanel-analytics)
- [Monitoring &amp; Performance](#monitoring--performance)
- [Cronitor](#cronitor)
- [GDPR and Privacy Considerations](#gdpr-and-privacy-considerations)
- [GDPR Checklist](#gdpr-checklist)
- [Privacy-first services (No GDPR cookie banner needed)](#privacy-first-services-no-gdpr-cookie-banner-needed)
- [Services requiring cookie consent](#services-requiring-cookie-consent)
- [Comparing Analytics Services](#comparing-analytics-services)
- [Next Steps](#next-steps)
<!--te-->
## Overview
Analytics help you understand your website visitors: where they come from, which pages they visit, and how they interact with your content. al-folio supports several analytics providers that you can enable in `_config.yml`.
## Supported Analytics Services
Currently implemented in al-folio:
- **Google Analytics** Free, feature-rich, but collects user data
- **Pirsch Analytics** GDPR-compliant, free tier available, European servers
- **Openpanel Analytics** Open-source option, privacy-focused
- **Cronitor** Uptime monitoring with Real User Monitoring (RUM) analytics
---
## Google Analytics
Google Analytics is free and widely used. It provides detailed insights into visitor behavior.
### Setup Steps
1. **Create a Google Analytics account:**
- Visit [Google Analytics](https://analytics.google.com)
- Sign in with your Google account
- Click **Start measuring** → **Create account**
2. **Create a property for your website:**
- Enter your website name and URL
- Accept terms and continue
- Choose your timezone and currency
3. **Get your Measurement ID:**
- In the left sidebar, go to **Admin** → **Properties**
- Click **Data Streams****Web** (or your existing stream)
- Copy the **Measurement ID** (format: `G-XXXXXXXXXX`)
4. **Enable in your site:**
- Open `_config.yml` in your repository
- Set `enable_google_analytics: true`
- Add your Measurement ID: `google_analytics: G-XXXXXXXXXX`
- Commit and push
5. **Verify it's working:**
- Visit your website
- Go back to Google Analytics → **Real-time** tab
- You should see your visit appear within a few seconds
**Note:** Google Analytics takes 24-48 hours to start showing data trends.
---
## Privacy-Friendly Alternatives
If you're concerned about user privacy or GDPR compliance, consider these alternatives:
### Pirsch Analytics
**Best for:** GDPR-compliant analytics without complex setup
**Features:**
- ✅ GDPR compliant
- ✅ European servers
- ✅ Free tier available
- ✅ Simple integration
- ✅ No cookie consent needed
**Setup:**
1. Sign up at [Pirsch.io](https://pirsch.io)
2. Add your domain
3. Copy the tracking code
4. In `_config.yml`, set `enable_pirsch_analytics: true`
5. Add your Site ID: `pirsch_analytics: YOUR_SITE_ID` (format: 32 characters)
6. Commit and push
(The site ID appears in your Pirsch dashboard.)
---
### Openpanel Analytics
**Best for:** Open-source and privacy-conscious developers
**Features:**
- ✅ Open-source
- ✅ Self-hosted option available
- ✅ Privacy-focused
- ✅ Modern dashboard
**Setup:**
1. Sign up at [Openpanel.dev](https://openpanel.dev)
2. Create a project for your website
3. Get your **Client ID**
4. In `_config.yml`, set `enable_openpanel_analytics: true`
5. Add your Client ID: `openpanel_analytics: YOUR_CLIENT_ID` (format: UUID)
6. Commit and push
---
## Monitoring & Performance
### Cronitor
Cronitor is an **uptime monitoring** service with RUM (Real User Monitoring) analytics.
**Best for:** Tracking if your site is online + basic performance metrics
**Setup:**
1. Create account at [Cronitor.io](https://cronitor.io)
2. Get your **Site ID**
3. In `_config.yml`, set `enable_cronitor_analytics: true`
4. Add your Site ID: `cronitor_analytics: YOUR_SITE_ID`
5. Commit and push
---
## GDPR and Privacy Considerations
If you're in the European Union or serve EU visitors, consider GDPR requirements:
### GDPR Checklist
- [ ] If using Google Analytics: Add cookie consent banner
- [ ] Display a privacy policy explaining what analytics you use
- [ ] Allow users to opt-out if using tracking cookies
- [ ] Use privacy-first alternatives when possible
### Privacy-first services (No GDPR cookie banner needed)
- ✅ Pirsch Analytics
- ✅ Openpanel Analytics
### Services requiring cookie consent
- ❌ Google Analytics (EU users must consent first)
- ❌ Cronitor (collects user data via RUM)
---
## Comparing Analytics Services
| Service | Free | GDPR | Setup | Features | Best for |
| -------------------- | ------------ | ------------------- | ------ | ---------------- | -------------------------- |
| **Google Analytics** | ✅ | ⚠️ Requires consent | Easy | Detailed reports | Detailed tracking |
| **Pirsch** | ✅ Free tier | ✅ | Easy | Balanced | GDPR compliance |
| **Openpanel** | ✅ | ✅ | Medium | Modern dashboard | Privacy-focused developers |
| **Cronitor** | Paid | ⚠️ Requires consent | Easy | Uptime + RUM | Uptime monitoring |
---
## Next Steps
1. **Choose a service** based on your needs (privacy, features, budget)
2. **Follow the setup guide** for your chosen service
3. **Verify it's working** by visiting your site and checking the analytics dashboard
For more customization help, see [CUSTOMIZE.md](CUSTOMIZE.md).

1
CLAUDE.md Normal file
View File

@ -0,0 +1 @@
@AGENTS.md

View File

@ -1,25 +1,102 @@
# Contributing to al-folio # Contributing to al-folio
Thank you for considering to contribute to al-folio!
Thank you for considering contributing to al-folio!
## Pull Requests ## Pull Requests
We welcome your pull requests (PRs). We welcome your pull requests (PRs).
For minor fixes (e.g., documentation improvements), feel free to submit a PR directly. For minor fixes (e.g., documentation improvements), feel free to submit a PR directly.
If you would like to implement a new feature or a bug, please make sure you (or someone else) has opened an appropriate issue first; in your PR, please mention the issue it addresses. If you would like to implement a new feature or a bug, please make sure you (or someone else) has opened an appropriate issue first; in your PR, please mention the issue it addresses.
Note that since [#2048](https://github.com/alshedivat/al-folio/pull/2048) al-folio uses the [prettier formatter](https://prettier.io/) for its code, meaning all new submitted code must conform to its standard. If you don't have `prettier` installed for your setup and the `prettier` code check fails when submitting a PR, you can check the referred failed action in our repo. In that action there will be an artifact with an HTML diff showing the needed changes.
## GitHub Copilot Agents
This repository includes specialized GitHub Copilot agents and files to assist with development and documentation:
### CLAUDE.md
The `CLAUDE.md` file serves as an entry point for Claude (Anthropic's AI assistant) when working with this repository. It uses Claude's `@path/to/import` syntax (as described in [Claude's best practices](https://code.claude.com/docs/en/best-practices#write-an-effective-claude-md)) to dynamically import the `AGENTS.md` file. This approach keeps documentation centralized while providing a convenient entry point for AI assistants. The file simply contains:
```
@AGENTS.md
```
### Customization Agent
The **Customization Agent** (`.github/agents/customize.agent.md`) helps users customize their al-folio website. It:
- Guides you through modifying configuration files, adding content, and customizing the theme
- Explains technical concepts in plain language for users without coding experience
- Applies changes directly to your repository files
- Provides step-by-step instructions for common customization tasks
To use the customization agent, you need to have [GitHub Copilot](https://github.com/features/copilot) enabled in your repository. The agent can help with tasks like changing site information, updating your CV, adding publications, creating blog posts, customizing theme colors, and more.
### Documentation Agent
The **Documentation Agent** (`.github/agents/docs.agent.md`) maintains the project documentation. It:
- Updates and maintains documentation files (`README.md`, `INSTALL.md`, `CUSTOMIZE.md`, `FAQ.md`, `CONTRIBUTING.md`)
- Keeps documentation in sync with code changes
- Writes clear, concise documentation for users without technical backgrounds
- Follows documentation standards and best practices
The documentation agent is primarily intended for maintainers and contributors who are updating the project documentation.
### Custom Instruction Files
To enhance GitHub Copilot's effectiveness when working with specific file types, this repository includes custom instruction files in `.github/instructions/`:
- **`.github/copilot-instructions.md`** Main Copilot instructions with repository overview, build process, tech stack, project layout, CI/CD pipelines, and common pitfalls
- **`.github/instructions/liquid-templates.instructions.md`** Guidance for modifying Liquid template files (`.liquid`)
- **`.github/instructions/yaml-configuration.instructions.md`** Guidance for configuration and data files (`_config.yml`, `_data/**/*.yml`)
- **`.github/instructions/bibtex-bibliography.instructions.md`** Guidance for bibliography files (`.bib`, `_bibliography/**`)
- **`.github/instructions/markdown-content.instructions.md`** Guidance for content files across collections (`_books/`, `_news/`, `_pages/`, `_posts/`, `_projects/`, `_teachings/`)
- **`.github/instructions/javascript-scripts.instructions.md`** Guidance for JavaScript files in `_scripts/`
These files help Copilot agents understand project conventions, build requirements, and development workflows without requiring codebase exploration.
### Copilot Environment Setup
A GitHub Actions workflow (`.github/workflows/copilot-setup-steps.yml`) automatically configures the Copilot environment with required dependencies (Ruby 3.3.5, Python 3.13, Node.js, ImageMagick, nbconvert) before agent execution.
### Important: Verify Agent Output
While these agents are designed to assist you, **they can make mistakes or produce incorrect information**. Always review and verify the output before applying it to your repository:
- **Review code and configuration changes** Check that suggested modifications are correct and fit your needs
- **Test changes locally** Before pushing to GitHub, test the changes locally (using Docker or native setup)
- **Verify syntax** Ensure any YAML, Markdown, or configuration files have correct syntax
- **Check documentation** If the agent generates documentation, review it for accuracy and clarity
- **Don't blindly apply changes** Understand what changes are being made and why
- **Run your site** After applying changes, run your site locally and verify everything works as expected
**Example:** If an agent suggests a BibTeX entry or configuration change, verify that the syntax is correct and matches the existing style in your repository before committing.
### How to Enable Agents
GitHub Copilot agents are available to users with GitHub Copilot subscriptions. To use these agents:
1. Ensure you have [GitHub Copilot](https://github.com/features/copilot) enabled for your account
2. Open your repository in an editor with GitHub Copilot support (such as VS Code with the GitHub Copilot extension)
3. The agents will be automatically available based on the configuration files in `.github/agents/`. For more information, see [Using custom agents in your IDE](https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/use-copilot-agents/coding-agent/create-custom-agents#using-custom-agents-in-your-ide).
For more information about GitHub Copilot agents and how to use them, see the [GitHub Copilot documentation](https://docs.github.com/en/copilot).
## Issues ## Issues
We use GitHub issues to track bugs and feature requests. We use GitHub issues to track bugs and feature requests.
Before submitting an issue, please make sure: Before submitting an issue, please make sure:
1. You have read [the FAQ section](https://github.com/alshedivat/al-folio#faq) of the README and your question is NOT addressed there. 1. You have read [the FAQ section](FAQ.md) of the README and your question is NOT addressed there.
2. You have done your best to ensure that your issue is NOT a duplicate of one of [the previous issues](https://github.com/alshedivat/al-folio/issues). 2. You have done your best to ensure that your issue is NOT a duplicate of one of [the previous issues](https://github.com/alshedivat/al-folio/issues).
3. Your issue is either a bug (unexpected/undesirable behavior) or a feature request. 3. Your issue is either a bug (unexpected/undesirable behavior) or a feature request.
If it is just a question, please ask it in the [Discussions](https://github.com/alshedivat/al-folio/discussions) forum. If it is just a question, please ask it in the [Discussions](https://github.com/alshedivat/al-folio/discussions) forum.
When submitting an issue, please make sure to use the appropriate template. When submitting an issue, please make sure to use the appropriate template.
## License ## License
By contributing to al-folio, you agree that your contributions will be licensed By contributing to al-folio, you agree that your contributions will be licensed
under the LICENSE file in the root directory of the source tree. under the LICENSE file in the root directory of the source tree.

1402
CUSTOMIZE.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,76 @@
FROM bitnami/minideb:latest FROM ruby:slim
Label MAINTAINER Amir Pourmand
RUN apt-get update -y # uncomment these if you are having this issue with the build:
# add locale # /usr/local/bundle/gems/jekyll-4.3.4/lib/jekyll/site.rb:509:in `initialize': Permission denied @ rb_sysopen - /srv/jekyll/.jekyll-cache/.gitignore (Errno::EACCES)
RUN apt-get -y install locales # ARG GROUPID=901
# Set the locale # ARG GROUPNAME=ruby
# ARG USERID=901
# ARG USERNAME=jekyll
ENV DEBIAN_FRONTEND noninteractive
LABEL authors="Amir Pourmand,George Araújo" \
description="Docker image for al-folio academic template" \
maintainer="Amir Pourmand"
# uncomment these if you are having this issue with the build:
# /usr/local/bundle/gems/jekyll-4.3.4/lib/jekyll/site.rb:509:in `initialize': Permission denied @ rb_sysopen - /srv/jekyll/.jekyll-cache/.gitignore (Errno::EACCES)
# add a non-root user to the image with a specific group and user id to avoid permission issues
# RUN groupadd -r $GROUPNAME -g $GROUPID && \
# useradd -u $USERID -m -g $GROUPNAME $USERNAME
# install system dependencies
RUN apt-get update -y && \
apt-get install -y --no-install-recommends \
build-essential \
curl \
git \
imagemagick \
inotify-tools \
locales \
nodejs \
procps \
python3-pip \
zlib1g-dev && \
pip --no-cache-dir install --upgrade --break-system-packages nbconvert
# clean up
RUN apt-get clean && \
apt-get autoremove && \
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* /tmp/*
# set the locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# add ruby and jekyll # set environment variables
RUN apt-get install --no-install-recommends ruby-full build-essential zlib1g-dev -y ENV EXECJS_RUNTIME=Node \
RUN apt-get install imagemagick -y JEKYLL_ENV=production \
RUN apt-get clean \ LANG=en_US.UTF-8 \
&& rm -rf /var/lib/apt/lists/ LANGUAGE=en_US:en \
# ENV GEM_HOME='root/gems' \ LC_ALL=en_US.UTF-8
# PATH="root/gems/bin:${PATH}"
RUN gem install jekyll bundler # create a directory for the jekyll site
RUN mkdir /srv/jekyll RUN mkdir /srv/jekyll
# copy the Gemfile and Gemfile.lock to the image
ADD Gemfile.lock /srv/jekyll
ADD Gemfile /srv/jekyll ADD Gemfile /srv/jekyll
# set the working directory
WORKDIR /srv/jekyll WORKDIR /srv/jekyll
RUN bundle install
# install jekyll and dependencies
RUN gem install --no-document jekyll bundler
RUN bundle install --no-cache
EXPOSE 8080
COPY bin/entry_point.sh /tmp/entry_point.sh
# uncomment this if you are having this issue with the build:
# /usr/local/bundle/gems/jekyll-4.3.4/lib/jekyll/site.rb:509:in `initialize': Permission denied @ rb_sysopen - /srv/jekyll/.jekyll-cache/.gitignore (Errno::EACCES)
# set the ownership of the jekyll site directory to the non-root user
# USER $USERNAME
CMD ["/tmp/entry_point.sh"]

175
FAQ.md Normal file
View File

@ -0,0 +1,175 @@
# Frequently Asked Questions
Here are some frequently asked questions. If you have a different question, please check if it was not already answered in the Q&A section of the [GitHub Discussions](https://github.com/alshedivat/al-folio/discussions/categories/q-a). If not, feel free to ask a new question there.
<!--ts-->
- [Frequently Asked Questions](#frequently-asked-questions)
- [After I create a new repository from this template and setup the repo, I get a deployment error. Isn't the website supposed to correctly deploy automatically?](#after-i-create-a-new-repository-from-this-template-and-setup-the-repo-i-get-a-deployment-error-isnt-the-website-supposed-to-correctly-deploy-automatically)
- [I am using a custom domain (e.g., foo.com). My custom domain becomes blank in the repository settings after each deployment. How do I fix that?](#i-am-using-a-custom-domain-eg-foocom-my-custom-domain-becomes-blank-in-the-repository-settings-after-each-deployment-how-do-i-fix-that)
- [My webpage works locally. But after deploying, it fails to build and throws Unknown tag 'toc'. How do I fix that?](#my-webpage-works-locally-but-after-deploying-it-fails-to-build-and-throws-unknown-tag-toc-how-do-i-fix-that)
- [My webpage works locally. But after deploying, it is not displayed correctly (CSS and JS are not loaded properly). How do I fix that?](#my-webpage-works-locally-but-after-deploying-it-is-not-displayed-correctly-css-and-js-are-not-loaded-properly-how-do-i-fix-that)
- [Atom feed doesn't work. Why?](#atom-feed-doesnt-work-why)
- [My site doesn't work when I enable related_blog_posts. Why?](#my-site-doesnt-work-when-i-enable-related_blog_posts-why)
- [When trying to deploy, it's asking for github login credentials, which github disabled password authentication and it exits with an error. How to fix?](#when-trying-to-deploy-its-asking-for-github-login-credentials-which-github-disabled-password-authentication-and-it-exits-with-an-error-how-to-fix)
- [When I manually run the Lighthouse Badger workflow, it fails with Error: Input required and not supplied: token. How do I fix that?](#when-i-manually-run-the-lighthouse-badger-workflow-it-fails-with-error-input-required-and-not-supplied-token-how-do-i-fix-that)
- [My code runs fine locally, but when I create a commit and submit it, it fails with prettier code formatter workflow run failed for main branch. How do I fix that?](#my-code-runs-fine-locally-but-when-i-create-a-commit-and-submit-it-it-fails-with-prettier-code-formatter-workflow-run-failed-for-main-branch-how-do-i-fix-that)
- [After I update my site with some new content, even a small change, the GitHub action throws an error or displays a warning. What happened?](#after-i-update-my-site-with-some-new-content-even-a-small-change-the-github-action-throws-an-error-or-displays-a-warning-what-happened)
- [I am trying to deploy my site, but it fails with Could not find gem 'jekyll-diagrams' in locally installed gems. How do I fix that?](#i-am-trying-to-deploy-my-site-but-it-fails-with-could-not-find-gem-jekyll-diagrams-in-locally-installed-gems-how-do-i-fix-that)
- [How can I update Academicons version on the template](#how-can-i-update-academicons-version-on-the-template)
- [How can I update Font Awesome version on the template](#how-can-i-update-font-awesome-version-on-the-template)
- [What do all these GitHub actions/workflows mean?](#what-do-all-these-github-actionsworkflows-mean)
- [How can I use Google Search Console ID on the template?](#how-can-i-use-google-search-console-id-on-the-template)
- [What are Code Wiki and DeepWiki?](#what-are-code-wiki-and-deepwiki)
- [When to use these tools](#when-to-use-these-tools)
- [What they do](#what-they-do)
- [Limitations](#limitations)
- [Access these tools](#access-these-tools)
<!--te-->
## After I create a new repository from this template and setup the repo, I get a deployment error. Isn't the website supposed to correctly deploy automatically?
Yes, if you are using release `v0.3.5` or later, the website will automatically and correctly re-deploy right after your first commit. Please make some changes (e.g., change your website info in `_config.yml`), commit, and push. Make sure to follow [deployment instructions](https://github.com/alshedivat/al-folio#deployment). (Relevant issue: [209](https://github.com/alshedivat/al-folio/issues/209#issuecomment-798849211).)
## I am using a custom domain (e.g., `foo.com`). My custom domain becomes blank in the repository settings after each deployment. How do I fix that?
You need to add `CNAME` file to the `main` or `source` branch of your repository. The file should contain your custom domain name. (Relevant issue: [130](https://github.com/alshedivat/al-folio/issues/130).)
## My webpage works locally. But after deploying, it fails to build and throws `Unknown tag 'toc'`. How do I fix that?
Make sure you followed through the [deployment instructions](#deployment) in the previous section. You should have set the deployment branch to `gh-pages`. (Related issue: [1438](https://github.com/alshedivat/al-folio/issues/1438).)
## My webpage works locally. But after deploying, it is not displayed correctly (CSS and JS are not loaded properly). How do I fix that?
If the website does not load the theme, the layout looks weird, and all links are broken, being the main page displayed this way:
<img src="assets/img/template_error.png" width="500">
make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`. Set `url` to `https://<your-github-username>.github.io` or to `https://<your.custom.domain>` if you are using a custom domain. If you are deploying a <ins>personal</ins> or <ins>organization</ins> website, leave `baseurl` **empty** (do **NOT** delete it). If you are deploying a project page, set `baseurl: /<your-project-name>/`. If all previous steps were done correctly, all is missing is for your browser to fetch again the site stylesheet. For this, you can:
- press [Shift + F5 on Chromium-based](https://support.google.com/chrome/answer/157179#zippy=%2Cwebpage-shortcuts) or [Ctrl + F5 on Firefox-based](https://support.mozilla.org/en-US/kb/keyboard-shortcuts-perform-firefox-tasks-quickly) browsers to reload the page ignoring cached content
- clean your browser history
- simply try it in a private session, here's how to do it in [Chrome](https://support.google.com/chrome/answer/95464) and [Firefox](https://support.mozilla.org/en-US/kb/private-browsing-use-firefox-without-history)
## Atom feed doesn't work. Why?
Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`. RSS Feed plugin works with these correctly set up fields: `title`, `url`, `description` and `author`. Make sure to fill them in an appropriate way and try again.
## My site doesn't work when I enable `related_blog_posts`. Why?
This is probably due to the [classifier reborn](https://github.com/jekyll/classifier-reborn) plugin, which is used to calculate related posts. If the error states `Liquid Exception: Zero vectors can not be normalized...` or `sqrt': Numerical argument is out of domain - "sqrt"`, it means that it could not calculate related posts for a specific post. This is usually caused by [empty or minimal blog posts](https://github.com/jekyll/classifier-reborn/issues/64) without meaningful words (i.e. only [stop words](https://en.wikipedia.org/wiki/Stop_words)) or even [specific characters](https://github.com/jekyll/classifier-reborn/issues/194) you used in your posts. Also, the calculus for similar posts are made for every `post`, which means every page that uses `layout: post`, including the announcements. To change this behavior, simply add `related_posts: false` to the front matter of the page you don't want to display related posts on. Another solution is to disable the lsi (latent semantic indexing) entirely by setting the `lsi` flag to `false` in `_config.yml`. Related issue: [#1828](https://github.com/alshedivat/al-folio/issues/1828).
## When trying to deploy, it's asking for github login credentials, which github disabled password authentication and it exits with an error. How to fix?
Open .git/config file using your preferred editor. Change the `https` portion of the `url` variable to `ssh`. Try deploying again.
## When I manually run the Lighthouse Badger workflow, it fails with `Error: Input required and not supplied: token`. How do I fix that?
You need to [create a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token) and [add it as a secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-encrypted-secrets-for-a-repository) named `LIGHTHOUSE_BADGER_TOKEN` to your repository. For more information, check [lighthouse-badger documentation](https://github.com/MyActionWay/lighthouse-badger-workflows#lighthouse-badger-easyyml) on how to do this.
## My code runs fine locally, but when I create a commit and submit it, it fails with `prettier code formatter workflow run failed for main branch`. How do I fix that?
We implemented support for [Prettier code formatting](https://prettier.io/) in [#2048](https://github.com/alshedivat/al-folio/pull/2048). It basically ensures that your code is [well formatted](https://prettier.io/docs/en/). If you want to ensure your code is compliant with `Prettier`, you have a few options:
- if you are running locally with `Docker` and using [development containers](https://github.com/alshedivat/al-folio/blob/main/INSTALL.md#local-setup-with-development-containers), `Prettier` is already included
- if you don't use `Docker`, it is simple to integrate it with your preferred IDE using an [extension](https://prettier.io/docs/en/editors)
- if you want to run it manually, you can follow the first 2 steps in [this tutorial](https://george-gca.github.io/blog/2023/slidev_for_non_web_devs/) (`Installing node version manager (nvm)` and `Installing Node (latest version)`), then, install it using `npm install prettier` inside the project directory, or install it globally on your computer using `npm install -g prettier`. To run `Prettier` on your current directory use `npx prettier . --write`.
You can also disable it for your repo. For this, just delete the file [.github/workflows/prettier.yml](https://github.com/alshedivat/al-folio/blob/main/.github/workflows/prettier.yml).
## After I update my site with some new content, even a small change, the GitHub action throws an error or displays a warning. What happened?
Probably your GitHub workflow is throwing an error like this:
```bash
/opt/hostedtoolcache/Ruby/3.0.2/x64/lib/ruby/gems/3.0.0/gems/bundler-2.5.5/lib/bundler/runtime.rb:304:in `check_for_activated_spec!': You have already activated uri 0.10.1, but your Gemfile requires uri 0.13.0. Since uri is a default gem, you can either remove your dependency on it or try updating to a newer version of bundler that supports uri as a default gem. (Gem::LoadError)
```
or maybe displaying a warning like one of these:
```
Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: actions/checkout@v3. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/.
Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: actions/checkout@v2, actions/cache@v2. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/.
The following actions uses node12 which is deprecated and will be forced to run on node16: actions/checkout@v2, actions/cache@v2. For more info: https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/
The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
```
If that's the case, you are using deprecated libraries/commands. This happens because you are using a very old version of al-folio. To fix this it is recommended [upgrading your code to the latest version](INSTALL.md#upgrading-from-a-previous-version) of the template. You will probably need to do some manual merging. If you find it easier, you could create a copy of your repository, do a fresh installation from the template and reapply all your changes. For this I would recommend a tool like [meld](https://meldmerge.org/) or [winmerge](https://winmerge.org/) to check the differences between directories/files.
Note that libraries tend to be deprecated and support for them dropped as they are no longer maintained, and keep using them involves security breaches. Also, some of these deprecations are enforced, for example, by GitHub itself, so there's so much we can do. We have also added tons of new functionality, as well as tidying things up and improving the overall speed and structure, so you could also benefit from these improvements.
## I am trying to deploy my site, but it fails with `Could not find gem 'jekyll-diagrams' in locally installed gems`. How do I fix that?
`jekyll-diagrams` support was dropped in [#1992](https://github.com/alshedivat/al-folio/pull/1992) in favor of using `mermaid.js` directly. Simply [update your code](INSTALL.md#upgrading-from-a-previous-version) to get the latest changes.
## How can I update Academicons version on the template
To update the Academicons version, you need to download the latest release from the [Academicons website](https://jpswalsh.github.io/academicons/). After downloading, extract the zip file and copy the files `academicons.ttf` and `academicons.woff` from the `fonts/` directory to `assets/fonts/` and the file `academicons.min.css` from the `css/` directory to `assets/css/`.
## How can I update Font Awesome version on the template
To update the Font Awesome version, you need to download the latest release "for the web" from the [Font Awesome website](https://fontawesome.com/download). After downloading, extract the zip file and copy the `scss/` directory content to `_sass/font-awesome/` and the `webfonts/` content to `assets/webfonts/`.
## What do all these GitHub actions/workflows mean?
GitHub actions are a way to automate tasks in the repository. They are defined in `.github/workflows/` directory. Each file in this directory is a workflow. Workflows are made up of one or more jobs, and each job runs on a virtual machine hosted by GitHub. You can see the status of the workflows in the `Actions` tab of your repository. For more information, check the [GitHub Actions documentation](https://docs.github.com/en/actions).
Currently we have the following workflows:
- `axe.yml`: does some accessibility testing in your site. It uses the [axe cli](https://github.com/dequelabs/axe-core-npm/tree/develop/packages/cli) tool with a chrome driver to render the webpage and allow the analysis. Must be run manually, since fixing some of the issues is not straightforward
- `broken-links-site.yml`: checks for broken links in your built website with the [lychee-action](https://github.com/lycheeverse/lychee-action)
- `broken-links.yml`: checks for broken links in your repository with the [lychee-action](https://github.com/lycheeverse/lychee-action)
- `deploy-docker-tag.yml`: adds some metadata to the docker image and pushes it to Docker Hub
- `deploy-image.yml`: deploys a new docker image with the latest changes to Docker Hub
- `deploy.yml`: deploys the website to GitHub Pages
- `docker-slim.yml`: deploys a smaller version of the docker image to Docker Hub with the [docker-slim-action](https://github.com/kitabisa/docker-slim-action)
- `lighthouse-badger.yml`: runs a [lighthouse](https://github.com/GoogleChrome/lighthouse) test for your site with the [lighthouse-badger-action](https://github.com/MyActionWay/lighthouse-badger-action), saving the results in the repository for easy inspecting, as can be seen [here](https://github.com/alshedivat/al-folio?tab=readme-ov-file#lighthouse-pagespeed-insights). For more information on how to enable this workflow, check our [FAQ question about it](https://github.com/alshedivat/al-folio/blob/main/FAQ.md#when-i-manually-run-the-lighthouse-badger-workflow-it-fails-with-error-input-required-and-not-supplied-token-how-do-i-fix-that)
- `prettier-comment-on-pr.yml`: not working. For now, this action is disabled. It was supposed to run prettier on the PRs and comment on them with the changes needed. For more information, check [issue 2115](https://github.com/alshedivat/al-folio/issues/2115)
- `prettier.yml`: runs [prettier](https://prettier.io/) on the code to ensure it is well formatted. For more information, check our [FAQ question about it](https://github.com/alshedivat/al-folio/blob/main/FAQ.md#my-code-runs-fine-locally-but-when-i-create-a-commit-and-submit-it-it-fails-with-prettier-code-formatter-workflow-run-failed-for-main-branch-how-do-i-fix-that)
## How can I use Google Search Console ID on the template?
In the configuration file `_config.yml` the tag `google-site-verification` should be updated to use this functionality. Here is how you can proceed,
- Generate your HTML tag by following [https://support.google.com/webmasters/answer/9008080?hl=en#meta_tag_verification&zippy=%2Chtml-tag](https://support.google.com/webmasters/answer/9008080?hl=en#meta_tag_verification&zippy=%2Chtml-tag) with URL prefix option.
- In the verify ownership option choose HTML tag and copy the tag contents which should look like `<meta name="google-site-verification" content="GoogleSearchConsoleID" />`.
- The string against `content` is the Google Search Console ID that can be used in the template. e.g. `google-site-verification: GoogleSearchConsoleID`. Now set the property `enable_google_verification: true`.
It looks like the Domain type property in the Google Search Console to verify the ownership of all URLs across all subdomains with GitHub Pages does not work.
## What are Code Wiki and DeepWiki?
**Code Wiki** and **DeepWiki** are AI-powered tools that help you understand GitHub repositories through interactive documentation. They should be treated as supplementary resources when you cannot find the information you need in the official project documentation.
### When to use these tools
**Use Code Wiki and DeepWiki only after**:
- You have reviewed the relevant documentation files in this repository (`README.md`, `INSTALL.md`, `CUSTOMIZE.md`, `FAQ.md`, or `CONTRIBUTING.md`)
- You have checked the [GitHub Discussions Q&A section](https://github.com/alshedivat/al-folio/discussions/categories/q-a) for similar questions
- You have searched existing [GitHub Issues](https://github.com/alshedivat/al-folio/issues)
### What they do
**Code Wiki** (powered by Google Gemini) generates interactive documentation from your repository code. It allows you to:
- Browse your repository's structure and architecture
- Search for specific functions or modules
- Understand how different parts of the codebase work together
- Get diagrams and visual representations of your code architecture
**DeepWiki** provides an AI-powered interface to ask questions about a repository, similar to having an engineer available 24/7. It allows you to:
- Ask natural language questions about the codebase
- Get instant answers about how specific features work
- Search for code patterns and implementations
### Limitations
These tools are generated automatically from our code and may not always reflect the most current documentation standards or best practices specific to this project. They should not replace official documentation but rather complement it when you need deeper technical insights.
### Access these tools
- **Code Wiki**: [Code Wiki for al-folio](https://codewiki.google/github.com/alshedivat/al-folio)
- **DeepWiki**: [DeepWiki for al-folio](https://deepwiki.com/alshedivat/al-folio)

31
Gemfile
View File

@ -1,24 +1,45 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'jekyll'
# Core plugins that directly affect site building
group :jekyll_plugins do group :jekyll_plugins do
gem 'jekyll' gem 'jekyll-3rd-party-libraries'
gem 'jekyll-archives' gem 'jekyll-archives-v2'
gem 'jekyll-diagrams' gem 'jekyll-cache-bust'
gem 'jekyll-email-protect' gem 'jekyll-email-protect'
gem 'jekyll-feed' gem 'jekyll-feed'
gem 'jekyll-get-json'
gem 'jekyll-imagemagick' gem 'jekyll-imagemagick'
gem 'jekyll-jupyter-notebook'
gem 'jekyll-link-attributes'
gem 'jekyll-minifier' gem 'jekyll-minifier'
gem 'jekyll-paginate-v2' gem 'jekyll-paginate-v2'
gem 'jekyll-regex-replace'
gem 'jekyll-scholar' gem 'jekyll-scholar'
gem 'jekyll-sitemap' gem 'jekyll-sitemap'
gem 'jekyll-link-attributes' gem 'jekyll-socials'
gem 'jekyll-tabs'
gem 'jekyll-terser', :git => "https://github.com/RobertoJBeltran/jekyll-terser.git"
gem 'jekyll-toc'
gem 'jekyll-twitter-plugin' gem 'jekyll-twitter-plugin'
gem 'jemoji' gem 'jemoji'
gem 'jekyll-pandoc' gem 'jekyll-pandoc'
gem 'mini_racer' gem 'mini_racer'
gem 'unicode_utils' gem 'unicode_utils'
gem 'webrick' gem 'webrick'
gem 'classifier-reborn' # used for content categorization during the build
end end
# Gems for development or external data fetching (outside :jekyll_plugins)
group :other_plugins do group :other_plugins do
gem 'httparty' gem 'css_parser'
gem 'feedjira' gem 'feedjira'
gem 'httparty'
gem 'observer' # used by jekyll-scholar
gem 'ostruct' # used by jekyll-twitter-plugin
# gem 'terser' # used by jekyll-terser
# gem 'unicode_utils' -- should be already installed by jekyll
# gem 'webrick' -- should be already installed by jekyll
end end

329
Gemfile.lock Normal file
View File

@ -0,0 +1,329 @@
GIT
remote: https://github.com/RobertoJBeltran/jekyll-terser.git
revision: 1085bf66d692799af09fe39f8162a1e6e42a3cc4
specs:
jekyll-terser (0.2.3)
jekyll (>= 0.10.0)
terser (>= 1.0.0)
GEM
remote: https://rubygems.org/
specs:
activesupport (8.1.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
json
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.8.8)
public_suffix (>= 2.0.2, < 8.0)
base64 (0.3.0)
bibtex-ruby (6.2.0)
latex-decode (~> 0.0)
logger (~> 1.7)
racc (~> 1.7)
bigdecimal (4.0.1)
citeproc (1.1.0)
date
forwardable
json
namae (~> 1.0)
observer (< 1.0)
open-uri (< 1.0)
citeproc-ruby (2.1.8)
citeproc (~> 1.0, >= 1.0.9)
csl (~> 2.0)
observer (< 1.0)
classifier-reborn (2.3.0)
fast-stemmer (~> 1.0)
matrix (~> 0.4)
colorator (1.1.0)
concurrent-ruby (1.3.6)
connection_pool (3.0.2)
crass (1.0.6)
csl (2.2.1)
forwardable (~> 1.3)
namae (~> 1.2)
open-uri (< 1.0)
rexml (~> 3.0)
set (~> 1.1)
singleton (< 1.0)
time (< 1.0)
csl-styles (2.0.2)
csl (~> 2.0)
css_parser (1.21.1)
addressable
cssminify2 (2.1.0)
csv (3.3.5)
date (3.5.1)
deep_merge (1.2.2)
drb (2.2.3)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
eventmachine (1.2.7)
execjs (2.10.0)
fast-stemmer (1.0.2)
feedjira (4.0.1)
logger (>= 1.0, < 2)
loofah (>= 2.3.1, < 3)
sax-machine (>= 1.0, < 2)
ffi (1.17.3-aarch64-linux-gnu)
ffi (1.17.3-aarch64-linux-musl)
ffi (1.17.3-arm-linux-gnu)
ffi (1.17.3-arm-linux-musl)
ffi (1.17.3-arm64-darwin)
ffi (1.17.3-x86_64-darwin)
ffi (1.17.3-x86_64-linux-gnu)
ffi (1.17.3-x86_64-linux-musl)
forwardable (1.4.0)
forwardable-extended (2.6.0)
gemoji (4.1.0)
google-protobuf (4.33.4)
bigdecimal
rake (>= 13)
google-protobuf (4.33.4-aarch64-linux-gnu)
bigdecimal
rake (>= 13)
google-protobuf (4.33.4-aarch64-linux-musl)
bigdecimal
rake (>= 13)
google-protobuf (4.33.4-arm64-darwin)
bigdecimal
rake (>= 13)
google-protobuf (4.33.4-x86_64-darwin)
bigdecimal
rake (>= 13)
google-protobuf (4.33.4-x86_64-linux-gnu)
bigdecimal
rake (>= 13)
google-protobuf (4.33.4-x86_64-linux-musl)
bigdecimal
rake (>= 13)
html-pipeline (2.14.3)
activesupport (>= 2)
nokogiri (>= 1.4)
htmlcompressor (0.4.0)
http_parser.rb (0.8.1)
httparty (0.24.2)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
jekyll-3rd-party-libraries (0.0.1)
css_parser (>= 1.6, < 2.0)
jekyll (>= 3.6, < 5.0)
nokogiri (>= 1.8, < 2.0)
jekyll (4.4.1)
addressable (~> 2.4)
base64 (~> 0.2)
colorator (~> 1.0)
csv (~> 3.0)
em-websocket (~> 0.5)
i18n (~> 1.0)
jekyll-sass-converter (>= 2.0, < 4.0)
jekyll-watch (~> 2.0)
json (~> 2.6)
kramdown (~> 2.3, >= 2.3.1)
kramdown-parser-gfm (~> 1.0)
liquid (~> 4.0)
mercenary (~> 0.3, >= 0.3.6)
pathutil (~> 0.9)
rouge (>= 3.0, < 5.0)
safe_yaml (~> 1.0)
terminal-table (>= 1.8, < 4.0)
webrick (~> 1.7)
jekyll-archives-v2 (0.0.7)
activesupport
jekyll (>= 3.6, < 5.0)
jekyll-cache-bust (0.0.1)
jekyll (>= 3.6, < 5.0)
jekyll-email-protect (1.1.0)
jekyll-feed (0.17.0)
jekyll (>= 3.7, < 5.0)
jekyll-get-json (1.0.0)
deep_merge (~> 1.2)
jekyll (>= 3.0)
jekyll-imagemagick (1.4.0)
jekyll (>= 3.4)
jekyll-jupyter-notebook (0.0.6)
jekyll
jekyll-link-attributes (1.0.1)
jekyll-minifier (0.2.2)
cssminify2 (~> 2.1.0)
htmlcompressor (~> 0.4)
jekyll (~> 4.0)
json-minify (~> 0.0.3)
terser (~> 1.2.3)
jekyll-paginate-v2 (3.0.0)
jekyll (>= 3.0, < 5.0)
jekyll-regex-replace (1.1.0)
jekyll-sass-converter (3.1.0)
sass-embedded (~> 1.75)
jekyll-scholar (7.3.0)
bibtex-ruby (~> 6.0)
citeproc-ruby (>= 2.1.6)
csl-styles (~> 2.0)
jekyll (~> 4.0)
jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0)
jekyll-socials (0.0.6)
jekyll (>= 3.6, < 5.0)
jekyll-tabs (1.2.1)
jekyll (>= 3.0, < 5.0)
jekyll-toc (0.19.0)
jekyll (>= 3.9)
nokogiri (~> 1.12)
jekyll-twitter-plugin (2.1.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
jemoji (0.13.0)
gemoji (>= 3, < 5)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
json (2.18.0)
json-minify (0.0.3)
json (> 0)
kramdown (2.5.2)
rexml (>= 3.4.4)
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
latex-decode (0.4.2)
liquid (4.0.4)
listen (3.10.0)
logger
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
logger (1.7.0)
loofah (2.25.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
matrix (0.4.3)
mercenary (0.4.0)
mini_mime (1.1.5)
minitest (6.0.1)
prism (~> 1.5)
multi_xml (0.8.1)
bigdecimal (>= 3.1, < 5)
namae (1.2.0)
racc (~> 1.7)
nokogiri (1.19.0-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.19.0-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.19.0-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.19.0-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.19.0-arm64-darwin)
racc (~> 1.4)
nokogiri (1.19.0-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.19.0-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.19.0-x86_64-linux-musl)
racc (~> 1.4)
observer (0.1.2)
open-uri (0.5.0)
stringio
time
uri
ostruct (0.6.3)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
prism (1.8.0)
public_suffix (7.0.2)
racc (1.8.1)
rake (13.3.1)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rexml (3.4.4)
rouge (4.7.0)
safe_yaml (1.0.5)
sass-embedded (1.97.2-aarch64-linux-gnu)
google-protobuf (~> 4.31)
sass-embedded (1.97.2-aarch64-linux-musl)
google-protobuf (~> 4.31)
sass-embedded (1.97.2-arm-linux-gnueabihf)
google-protobuf (~> 4.31)
sass-embedded (1.97.2-arm-linux-musleabihf)
google-protobuf (~> 4.31)
sass-embedded (1.97.2-arm64-darwin)
google-protobuf (~> 4.31)
sass-embedded (1.97.2-x86_64-darwin)
google-protobuf (~> 4.31)
sass-embedded (1.97.2-x86_64-linux-gnu)
google-protobuf (~> 4.31)
sass-embedded (1.97.2-x86_64-linux-musl)
google-protobuf (~> 4.31)
sax-machine (1.3.2)
securerandom (0.4.1)
set (1.1.2)
singleton (0.3.0)
stringio (3.2.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
terser (1.2.6)
execjs (>= 0.3.0, < 3)
time (0.4.2)
date
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.6.0)
uri (1.1.1)
webrick (1.9.2)
PLATFORMS
aarch64-linux
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-gnueabihf
arm-linux-musl
arm-linux-musleabihf
arm64-darwin
x86_64-darwin
x86_64-linux
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
classifier-reborn
css_parser
feedjira
httparty
jekyll
jekyll-3rd-party-libraries
jekyll-archives-v2
jekyll-cache-bust
jekyll-email-protect
jekyll-feed
jekyll-get-json
jekyll-imagemagick
jekyll-jupyter-notebook
jekyll-link-attributes
jekyll-minifier
jekyll-paginate-v2
jekyll-regex-replace
jekyll-scholar
jekyll-sitemap
jekyll-socials
jekyll-tabs
jekyll-terser!
jekyll-toc
jekyll-twitter-plugin
jemoji
observer
ostruct
BUNDLED WITH
4.0.4

296
INSTALL.md Normal file
View File

@ -0,0 +1,296 @@
# Installing and Deploying
<!--ts-->
- [Installing and Deploying](#installing-and-deploying)
- [Recommended Approach](#recommended-approach)
- [Template vs. Fork: Which Should I Use?](#template-vs-fork-which-should-i-use)
- [Important Notes for GitHub Pages Sites](#important-notes-for-github-pages-sites)
- [Automatic Deployment](#automatic-deployment)
- [Local Development](#local-development)
- [Local setup on Windows](#local-setup-on-windows)
- [Local setup using Docker (Recommended)](#local-setup-using-docker-recommended)
- [Build your own docker image](#build-your-own-docker-image)
- [Have Bugs on Docker Image?](#have-bugs-on-docker-image)
- [Local Setup with Development Containers](#local-setup-with-development-containers)
- [Local Setup (Legacy, no longer supported)](#local-setup-legacy-no-longer-supported)
- [Deployment](#deployment)
- [For personal and organization webpages](#for-personal-and-organization-webpages)
- [For project pages](#for-project-pages)
- [Enabling automatic deployment](#enabling-automatic-deployment)
- [Manual deployment to GitHub Pages](#manual-deployment-to-github-pages)
- [Deploy on <a href="https://www.netlify.com/" rel="nofollow">Netlify</a>](https://www.netlify.com/)
- [Deployment to another hosting server (non GitHub Pages)](#deployment-to-another-hosting-server-non-github-pages)
- [Deployment to a separate repository (advanced users only)](#deployment-to-a-separate-repository-advanced-users-only)
- [Maintaining Dependencies](#maintaining-dependencies)
- [Upgrading from a previous version](#upgrading-from-a-previous-version)
<!--te-->
## Recommended Approach
The recommended approach for using **al-folio** is to first create your own site using the template with as few changes as possible, and only when it is up and running customize it however you like. This way it is easier to pinpoint what causes a potential issue in case of a bug.
**For the quickest setup**, follow the [Quick Start Guide](QUICKSTART.md), which will have you up and running in 5 minutes.
### Template vs. Fork: Which Should I Use?
**Use the "Use this template" button** (recommended) when creating your own al-folio site. This creates a clean, independent copy that is not linked to the main al-folio repository.
**If you already forked the repository**, your fork will work fine, but you should be aware of a common pitfall:
- Forks maintain a connection to the original repository, which can make it easy to accidentally submit pull requests to al-folio with your personal site changes
- **Solution:** When making changes to your fork, always create a new branch (e.g., `git checkout -b my-site-updates`) and verify that you're pushing to **your own fork** before submitting pull requests
- Only submit pull requests to `alshedivat/al-folio` if you're intentionally contributing improvements that benefit the entire al-folio community
### Important Notes for GitHub Pages Sites
If you plan to upload your site to `<your-github-username>.github.io`, the repository name :warning: **MUST BE** :warning: `<your-github-username>.github.io` or `<your-github-orgname>.github.io`, as stated in the [GitHub pages docs](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites).
When configuring `_config.yml`, set `url` to `https://<your-github-username>.github.io` and leave `baseurl` **empty** (do NOT delete it), setting it as `baseurl:`.
### Automatic Deployment
Starting version [v0.3.5](https://github.com/alshedivat/al-folio/releases/tag/v0.3.5), **al-folio** will automatically re-deploy your webpage each time you push new changes to your repository! :sparkles:
### Local Development
Once everything is deployed, you can download the repository to your machine and start customizing it locally:
```bash
git clone git@github.com:<your-username>/<your-repo-name>.git
```
See [Local setup using Docker](#local-setup-using-docker-recommended) or other sections below for local development options.
## Local setup on Windows
If you are using Windows, it is **highly recommended** to use [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/install), which is a compatibility layer for running Linux on top of Windows. You can follow [these instructions](https://ubuntu.com/tutorials/install-ubuntu-on-wsl2-on-windows-11-with-gui-support) to install WSL and Ubuntu on your machine. You only need to go up to the step 4 of the tutorial (you don't have to enable the optional `systemd` nor the graphical applications), and then you can follow the instructions below to install docker. You can install docker natively on Windows as well, but it has been having some issues as can be seen in [#1540](https://github.com/alshedivat/al-folio/issues/1540), [#2007](https://github.com/alshedivat/al-folio/issues/2007).
## Local setup using Docker (Recommended)
Using Docker to install Jekyll and Ruby dependencies is the easiest way.
You need to take the following steps to get `al-folio` up and running on your local machine:
- First, install [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/).
- Finally, run the following command that will pull the latest pre-built image from DockerHub and will run your website.
```bash
docker compose pull
docker compose up
```
Note that when you run it for the first time, it will download a docker image of size 400MB or so. To see the template running, open your browser and go to `http://localhost:8080`. You should see a copy of the theme's demo website.
Now, feel free to customize the theme however you like (don't forget to change the name!). Also, your changes should be automatically rendered in real-time (or maybe after a few seconds).
> Beta: You can also use the slimmed docker image with a size below 100MBs and exact same functionality. Just use `docker compose -f docker-compose-slim.yml up`
### Build your own docker image
> Note: this approach is only necessary if you would like to build an older or very custom version of al-folio.
Build and run a new docker image using:
```bash
docker compose up --build
```
> If you want to update jekyll, install new ruby packages, etc., all you have to do is build the image again using `--force-recreate` argument at the end of the previous command! It will download Ruby and Jekyll and install all Ruby packages again from scratch.
If you want to use a specific docker version, you can do so by changing the version tag to `your_version` in `docker-compose.yaml` (the `v0.16.3` in `image: amirpourmand/al-folio:v0.16.3`). For example, you might have created your website on `v0.10.0` and you want to stick with that.
### Have Bugs on Docker Image?
Sometimes, there might be some bugs in the current docker image. It might be version mismatch or anything. If you want to debug and easily solve the problem for yourself you can do the following steps:
```
docker compose up -d
docker compose logs
```
Then you can see the bug! You can enter the container via this command:
```
docker compose exec -it jekyll /bin/bash
```
Then you can run the script:
```
./bin/entry_point.sh
```
You might see problems for package dependecy or something which is not available. You can fix it now by using
```
bundle install
./bin/entry_point.sh
```
Most likely, this will solve the problem but it shouldn't really happen. So, please open a bug report for us.
## Local Setup with Development Containers
`al-folio` supports [Development Containers](https://containers.dev/supporting).
For example, when you open the repository with Visual Studio Code (VSCode), it prompts you to install the necessary extension and automatically install everything necessary.
## Local Setup (Legacy, no longer supported)
For a hands-on walkthrough of running al-folio locally without using Docker, check out [this cool blog post](https://george-gca.github.io/blog/2022/running-local-al-folio/) by one of the community members!
Assuming you have [Ruby](https://www.ruby-lang.org/en/downloads/) and [Bundler](https://bundler.io/) installed on your system (_hint: for ease of managing ruby gems, consider using [rbenv](https://github.com/rbenv/rbenv)_), and also [Python](https://www.python.org/) and [pip](https://pypi.org/project/pip/) (_hint: for ease of managing python packages, consider using a virtual environment, like [venv](https://docs.python.org/pt-br/3/library/venv.html) or [conda](https://docs.conda.io/en/latest/)_).
```bash
bundle install
# assuming pip is your Python package manager
pip install jupyter
bundle exec jekyll serve
```
To see the template running, open your browser and go to `http://localhost:4000`. You should see a copy of the theme's [demo website](https://alshedivat.github.io/al-folio/). Now, feel free to customize the theme however you like. After you are done, remember to **commit** your final changes.
## Deployment
Deploying your website to [GitHub Pages](https://pages.github.com/) is the most popular option.
Starting version [v0.3.5](https://github.com/alshedivat/al-folio/releases/tag/v0.3.5), **al-folio** will automatically re-deploy your webpage each time you push new changes to your repository **main branch**! :sparkles:
### For personal and organization webpages
1. The name of your repository **MUST BE** `<your-github-username>.github.io` or `<your-github-orgname>.github.io`.
2. In `_config.yml`, set `url` to `https://<your-github-username>.github.io` and leave `baseurl` empty.
3. Set up automatic deployment of your webpage (see instructions below).
4. Make changes to your main branch, commit, and push!
5. After deployment, the webpage will become available at `<your-github-username>.github.io`.
### For project pages
1. In `_config.yml`, set `url` to `https://<your-github-username>.github.io` and `baseurl` to `/<your-repository-name>/`.
2. Set up automatic deployment of your webpage (see instructions below).
3. Make changes to your main branch, commit, and push!
4. After deployment, the webpage will become available at `<your-github-username>.github.io/<your-repository-name>/`.
### Enabling automatic deployment
1. Click on **Actions** tab and **Enable GitHub Actions**; do not worry about creating any workflows as everything has already been set for you.
2. Go to `Settings -> Actions -> General -> Workflow permissions`, and give `Read and write permissions` to GitHub Actions
3. Make any other changes to your webpage, commit, and push to your main branch. This will automatically trigger the **Deploy** action.
4. Wait for a few minutes and let the action complete. You can see the progress in the **Actions** tab. If completed successfully, in addition to the `main` branch, your repository should now have a newly built `gh-pages` branch. **Do NOT touch this branch!**
5. Finally, in the **Settings** of your repository, in the Pages section, set the branch to `gh-pages` (**NOT** to `main`). For more details, see [Configuring a publishing source for your GitHub Pages site](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#choosing-a-publishing-source).
If you keep your site on another branch, open `.github/workflows/deploy.yml` **on the branch you keep your website on** and change `on->push->branches` and `on->pull\_request->branches` to the branch you keep your website on. This will trigger the action on pulls/pushes on that branch. The action will then deploy the website on the branch it was triggered from.
### Manual deployment to GitHub Pages
If you need to manually re-deploy your website to GitHub pages, go to Actions, click "Deploy" in the left sidebar, then "Run workflow."
### Deploy on [Netlify](https://www.netlify.com/)
1. [Use this template -> Create a new repository](https://github.com/new?template_name=al-folio&template_owner=alshedivat).
2. Netlify: **Add new site** -> **Import an existing project** -> **GitHub** and give Netlify access to the repository you just created.
3. Netlify: In the deploy settings
- Set **Branch to deploy** to `main`
- **Base directory** is empty
- Set **Build command** to `sed -i "s/^\(baseurl: \).*$/baseurl:/" _config.yml && bundle exec jekyll build`
- Set **Publish directory** to `_site`
4. Netlify: Add the following two **environment variables**
- | Key | Value |
| -------------- | -------------------------------------------------------------------------------------- |
| `JEKYLL_ENV` | `production` |
| `RUBY_VERSION` | set to the Ruby version found in `.github/workflows/deploy.yml` (for example, `3.3.5`) |
5. Netlify: Click **Deploy** and wait for the site to be published. If you want to use your own domain name, follow the steps in [this documentation](https://docs.netlify.com/domains-https/custom-domains/).
### Deployment to another hosting server (non GitHub Pages)
If you decide to not use GitHub Pages and host your page elsewhere, simply run:
```bash
bundle exec jekyll build
```
which will (re-)generate the static webpage in the `_site/` folder.
Then simply copy the contents of the `_site/` directory to your hosting server.
If you also want to remove unused css classes from your file, run:
```bash
purgecss -c purgecss.config.js
```
which will replace the css files in the `_site/assets/css/` folder with the purged css files.
**Note:** Make sure to correctly set the `url` and `baseurl` fields in `_config.yml` before building the webpage. If you are deploying your webpage to `your-domain.com/your-project/`, you must set `url: your-domain.com` and `baseurl: /your-project/`. If you are deploying directly to `your-domain.com`, leave `baseurl` blank, **do not delete it**.
### Deployment to a separate repository (advanced users only)
**Note:** Do not try using this method unless you know what you are doing (make sure you are familiar with [publishing sources](https://help.github.com/en/github/working-with-github-pages/about-github-pages#publishing-sources-for-github-pages-sites)). This approach allows to have the website's source code in one repository and the deployment version in a different repository.
Let's assume that your website's publishing source is a `publishing-source` subdirectory of a git-versioned repository cloned under `$HOME/repo/`.
For a user site this could well be something like `$HOME/<user>.github.io`.
Firstly, from the deployment repo dir, checkout the git branch hosting your publishing source.
Then from the website sources dir (commonly your al-folio fork's clone):
```bash
bundle exec jekyll build --destination $HOME/repo/publishing-source
```
This will instruct jekyll to deploy the website under `$HOME/repo/publishing-source`.
**Note:** Jekyll will clean `$HOME/repo/publishing-source` before building!
The quote below is taken directly from the [jekyll configuration docs](https://jekyllrb.com/docs/configuration/options/):
> Destination folders are cleaned on site builds
>
> The contents of `<destination>` are automatically cleaned, by default, when the site is built. Files or folders that are not created by your site will be removed. Some files could be retained by specifying them within the `<keep_files>` configuration directive.
>
> Do not use an important location for `<destination>`; instead, use it as a staging area and copy files from there to your web server.
If `$HOME/repo/publishing-source` contains files that you want jekyll to leave untouched, specify them under `keep_files` in `_config.yml`.
In its default configuration, al-folio will copy the top-level `README.md` to the publishing source. If you want to change this behavior, add `README.md` under `exclude` in `_config.yml`.
**Note:** Do _not_ run `jekyll clean` on your publishing source repo as this will result in the entire directory getting deleted, irrespective of the content of `keep_files` in `_config.yml`.
## Maintaining Dependencies
**al-folio** uses **Bundler** (a Ruby dependency manager) to keep track of Ruby packages (called "gems") needed to run Jekyll and its plugins.
**To update all dependencies:**
```bash
bundle update --all
```
**After updating:**
1. Rebuild the Docker image to apply changes: `docker compose up --build`
2. Test locally to ensure everything still works: `docker compose up`
3. Visit `http://localhost:8080` and verify the site renders correctly
4. If your site fails after updating, check the [FAQ](FAQ.md) for troubleshooting
**For Ruby/Python environment issues:**
- Always use Docker for consistency with CI/CD (see [Local setup using Docker](#local-setup-using-docker-recommended))
- Avoid manual Ruby/Python installation when possible
## Upgrading from a previous version
If you installed **al-folio** as described above, you can manually update your code by following the steps below:
```bash
# Assuming the current directory is <your-repo-name>
git remote add upstream https://github.com/alshedivat/al-folio.git
git fetch upstream
git rebase v0.16.3
```
If you have extensively customized a previous version, it might be trickier to upgrade.
You can still follow the steps above, but `git rebase` may result in merge conflicts that must be resolved.
See [git rebase manual](https://help.github.com/en/github/using-git/about-git-rebase) and how to [resolve conflicts](https://help.github.com/en/github/using-git/resolving-merge-conflicts-after-a-git-rebase) for more information.
If rebasing is too complicated, we recommend re-installing the new version of the theme from scratch and port over your content and changes from the previous version manually. You can use tools like [meld](https://meldmerge.org/)
or [winmerge](https://winmerge.org/) to help in this process.

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2022 Maruan Al-Shedivat. Copyright (c) 2025 Maruan Al-Shedivat.
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

111
QUICKSTART.md Normal file
View File

@ -0,0 +1,111 @@
# Quick Start Guide
**Get your al-folio site running in 5 minutes.** This guide is for users who just want a working website quickly without deep customization.
> **Video Tutorial:** Watch a walkthrough of these steps [here](assets/video/tutorial_al_folio.mp4)
<!--ts-->
- [Quick Start Guide](#quick-start-guide)
- [Step 1: Create Your Repository (1 min)](#step-1-create-your-repository-1-min)
- [Step 2: Configure Deployment (1 min)](#step-2-configure-deployment-1-min)
- [Step 3: Personalize (2 min)](#step-3-personalize-2-min)
- [Step 4: View Your Site (1 min)](#step-4-view-your-site-1-min)
- [What's Next?](#whats-next)
- [Add Your Content](#add-your-content)
- [Customize Appearance](#customize-appearance)
- [Learn More](#learn-more)
- [Get Help from AI](#get-help-from-ai)
<!--te-->
## Step 1: Create Your Repository (1 min)
**⚠️ Important:** Use the **"Use this template"** button, NOT the fork button. This ensures your site is independent and you won't accidentally submit your personal changes back to the al-folio project.
1. Go to the [al-folio repository](https://github.com/alshedivat/al-folio)
2. Click the green **"Use this template"** button (top right), then select **"Create a new repository"**
3. Name your repository:
- **Personal/Organization site (if you want your site to be at `username.github.io`):** `username.github.io` (replace `username` with your GitHub username)
- **Project site (if you want your site to be at `username.github.io/project-name`):** Any name (e.g., `my-research-website`)
4. Click **"Create repository from template"**
**Already forked by mistake?** No problem. Your fork will work fine—just be careful when making changes. Create a new branch for your updates (e.g., `git checkout -b my-site-updates`) and make sure you push to **your own repository**, not the main al-folio project.
## Step 2: Configure Deployment (1 min)
1. Go to your new repository → **Settings****Actions****General** → **Workflow permissions**
2. Select **Read and write permissions**
3. Click **Save**
## Step 3: Personalize (2 min)
1. Open `_config.yml` in your repository
2. Update these fields:
```yaml
title: My Website
first_name: Your
last_name: Name
url: https://your-username.github.io # or your custom domain
baseurl: # Leave this empty (do NOT delete it)
```
3. Click **Commit changes** (at the bottom of the page)
## Step 4: View Your Site (1 min)
1. Go to your repository → **Actions** tab
2. Wait for the "Deploy site" workflow to complete (look for a green checkmark, ~4 minutes)
3. Go to **Settings****Pages** → **Build and deployment**
4. Make sure **Source** is set to **Deploy from a branch**
5. Set the branch to **gh-pages** (NOT main)
6. Wait for the "pages-build-deployment" workflow to complete (~45 seconds)
7. Visit `https://your-username.github.io` in your browser
**That's it!** Your site is live. You now have a working al-folio website.
---
## What's Next?
Once your site is running, explore these customization options:
### Add Your Content
- **Profile picture:** Replace `assets/img/prof_pic.jpg` with your photo
- **About page:** Edit `_pages/about.md` to write your bio
- **Publications:** Add entries to `_bibliography/papers.bib`
- **Blog posts:** Create files in `_posts/` with format `YYYY-MM-DD-title.md`
### Customize Appearance
- **Theme color:** Edit `_config.yml`, search for `theme_color`
- **Enable/disable sections:** In `_config.yml`, look for `enabled: false/true` options
- **Social media links:** Edit `_data/socials.yml`
### Learn More
- Installation and local setup options: [INSTALL.md](INSTALL.md)
- Full customization guide: [CUSTOMIZE.md](CUSTOMIZE.md)
- Frequently asked questions: [FAQ.md](FAQ.md)
- Troubleshooting: [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
### Get Help from AI
Use the **GitHub Copilot Customization Agent** (if you have Copilot) to:
- Get step-by-step help with customizations
- Understand how to modify specific features
- Apply changes directly to your site
See [CUSTOMIZE.md § GitHub Copilot Customization Agent](CUSTOMIZE.md#github-copilot-customization-agent) for details.
---
**Common first steps:**
- Change the theme color in `_config.yml`
- Add your social media links in `_data/socials.yml`
- Upload your profile picture to `assets/img/prof_pic.jpg`
- Write a short bio in `_pages/about.md`
Happy customizing! 🎉

View File

@ -1,5 +1,6 @@
# Pages perso # Pages perso
</div>
## Setup and develop ## Setup and develop

536
SEO.md Normal file
View File

@ -0,0 +1,536 @@
# SEO Best Practices Guide
This guide helps you optimize your al-folio website for search engines so your research and work are discoverable.
<!--ts-->
- [SEO Best Practices Guide](#seo-best-practices-guide)
- [Overview](#overview)
- [Basic SEO Setup](#basic-seo-setup)
- [Sitemap and Robots](#sitemap-and-robots)
- [Site URL and Metadata](#site-url-and-metadata)
- [Enabling Open Graph (Social Media Previews)](#enabling-open-graph-social-media-previews)
- [What is Open Graph?](#what-is-open-graph)
- [Enable in al-folio](#enable-in-al-folio)
- [Schema.org Markup](#schemaorg-markup)
- [What is Schema.org?](#what-is-schemaorg)
- [Enable in al-folio](#enable-in-al-folio-1)
- [What Gets Marked Up](#what-gets-marked-up)
- [Search Console Setup](#search-console-setup)
- [Google Search Console](#google-search-console)
- [Bing Webmaster Tools](#bing-webmaster-tools)
- [Publication Indexing](#publication-indexing)
- [Google Scholar](#google-scholar)
- [DBLP (Computer Science)](#dblp-computer-science)
- [arXiv](#arxiv)
- [Content Optimization](#content-optimization)
- [Page Titles and Descriptions](#page-titles-and-descriptions)
- [Heading Structure](#heading-structure)
- [Image Optimization](#image-optimization)
- [Internal Linking](#internal-linking)
- [RSS Feed for Discovery](#rss-feed-for-discovery)
- [Performance &amp; Mobile](#performance--mobile)
- [SEO Checklist](#seo-checklist)
- [Resources](#resources)
<!--te-->
## Overview
SEO (Search Engine Optimization) makes your website discoverable on Google, Bing, and other search engines. For academics, this means:
- Your research becomes discoverable when people search for your work
- Your CV/bio appears in search results
- Your publications rank higher
- More citations and collaborations
al-folio includes SEO basics, but you can optimize further.
---
## Basic SEO Setup
### Sitemap and Robots
al-folio auto-generates a `sitemap.xml` and `robots.txt` for you. These tell search engines what pages exist.
**Verify they exist:**
- Visit `https://your-site.com/sitemap.xml` Should show an XML list of pages
- Visit `https://your-site.com/robots.txt` Should show instructions for search engines
If they're missing:
1. Check `_config.yml` has a valid `url`
2. Rebuild: `bundle exec jekyll build`
3. Check `_site/` directory has both files
**No configuration needed** al-folio handles this automatically.
---
### Site URL and Metadata
Ensure `_config.yml` has correct metadata:
```yaml
title: Your Full Name or Site Title
description: > # Brief description (1-2 sentences)
A description of your research and expertise.
This appears in search results.
author: Your Name
keywords: machine learning, research, academia, etc.
url: https://your-domain.com
lang: en
```
All fields are important for SEO. **Avoid leaving fields blank.**
---
## Enabling Open Graph (Social Media Previews)
### What is Open Graph?
When someone shares your page on Twitter, Facebook, LinkedIn, etc., Open Graph controls what preview appears.
**Without Open Graph:**
- Generic title
- No image
- Ugly preview
**With Open Graph:**
- Your custom title
- Your custom image (photo, diagram, etc.)
- Custom description
- Professional preview
### Enable in al-folio
Open Graph is disabled by default. To enable:
1. **Edit `_config.yml`:**
```yaml
serve_og_meta: true # Change from false to true
og_image: /assets/img/og-image.png # Path to your image (1200x630px recommended)
```
2. **Create your OG image:**
- Size: 1200x630 pixels
- Format: PNG or JPG
- Content: Your name/logo + key info
- Save to: `assets/img/og-image.png`
3. **Commit and deploy**
4. **Test it:**
- Use [Facebook's Sharing Debugger](https://developers.facebook.com/tools/debug/sharing/)
- Paste your site URL
- You should see your custom image and title
**Per-page OG images:**
Add to the frontmatter of a blog post or page:
```markdown
---
layout: post
title: My Research Paper
og_image: /assets/img/paper-diagram.png
---
```
---
## Schema.org Markup
### What is Schema.org?
Schema.org is structured data that tells search engines what kind of content is on your page:
- "This is a Person" (your bio page)
- "This is a Publication" (your paper)
- "This is a BlogPosting" (your article)
Benefits:
- Rich snippets in search results
- Better knowledge graph information
- Schema validation helps Google understand your site
### Enable in al-folio
Enable in `_config.yml`:
```yaml
serve_schema_org: true # Change from false to true
```
That's it! al-folio automatically marks up:
- **Author info** (Person schema with name, URL, photo)
- **Blog posts** (BlogPosting schema with date, title, description)
- **Publications** (CreativeWork/ScholarlyArticle schema)
### What Gets Marked Up
**Homepage (Person):**
- Your name, photo, description
- Links to your profiles (LinkedIn, GitHub, etc.)
**Blog posts (BlogPosting):**
- Title, date, author, description
- Content
- Publication date and modified date
**Publications (ScholarlyArticle):**
- Title, authors, abstract
- Publication date, venue
- URL and PDF links
---
## Search Console Setup
### Google Search Console
**Google Search Console** lets you monitor how your site appears in Google search results.
**Setup:**
1. Go to [Google Search Console](https://search.google.com/search-console)
2. Add your website:
- Click **"URL prefix"**
- Enter your site URL: `https://your-domain.com`
3. Verify ownership (choose one method):
- **HTML file upload** Download file, add to repository root
- **HTML tag** Copy meta tag to `_config.yml` → redeploy
- **Google Analytics** If you already use Google Analytics
- **DNS record** Advanced (if you own the domain)
**Add to `_config.yml`:**
```yaml
google_site_verification: YOUR_VERIFICATION_CODE
```
(Replace `YOUR_VERIFICATION_CODE` with the code from Search Console.)
**Monitor in Search Console:**
- **Performance** Which queries bring traffic, your ranking position
- **Coverage** Any indexing errors
- **Enhancements** Schema.org validation
- **Sitemaps** Your sitemap status
---
### Bing Webmaster Tools
Similar to Google Search Console but for Bing search:
1. Go to [Bing Webmaster Tools](https://www.bing.com/webmasters)
2. Add your site
3. Verify (usually auto-verifies if you verified Google)
4. Add to `_config.yml`:
```yaml
bing_site_verification: YOUR_BING_CODE
```
**Note:** Bing commands are optional but recommended. Check both console dashboards regularly.
---
## Publication Indexing
### Google Scholar
**Goal:** Get your publications listed on Google Scholar so they show up in scholar search results.
**Google Scholar auto-crawls:**
- Your website automatically (if publicly accessible)
- Your publications page if it has proper markup
- PDFs linked from your site
**To improve Scholar indexing:**
1. **Ensure BibTeX has proper format:**
```bibtex
@article{mykey,
title={Your Paper Title},
author={Your Name and Co-Author},
journal={Journal Name},
year={2024},
volume={1},
pages={1-10},
doi={10.1234/doi}
}
```
2. **Add PDFs to BibTeX:**
```bibtex
@article{mykey,
# ... other fields ...
pdf={my-paper.pdf} # File at assets/pdf/my-paper.pdf
}
```
3. **Submit to Google Scholar (optional):**
- Go to [Google Scholar Author Profile](https://scholar.google.com/citations)
- Create a profile
- Google will find your papers automatically within weeks
4. **Wait 3-6 months** Google Scholar takes time to index
---
### DBLP (Computer Science)
If your research is computer science related:
1. Go to [DBLP](https://dblp.org/)
2. Search for yourself or your papers
3. If missing, [Submit via DBLP](https://dblp.org/db/contrib/) (requires account)
4. DBLP will verify and add your work
---
### arXiv
If you have preprints:
1. Go to [arXiv.org](https://arxiv.org/)
2. Submit your preprint
3. Once listed, arXiv automatically indexes it across search engines
**Add arXiv link to BibTeX:**
```bibtex
@article{mykey,
# ... other fields ...
arxiv={2024.12345} # arXiv ID
}
```
---
## Content Optimization
### Page Titles and Descriptions
Every page needs a title and description. These show in search results.
**In `_config.yml`:**
```yaml
title: Jane Smith - Computer Science Researcher
description: >
Academic website of Jane Smith, focusing on machine learning and AI ethics.
```
**In page/post frontmatter:**
```markdown
---
layout: post
title: Novel Deep Learning Architecture for Climate Modeling
description: A new approach to improving climate model accuracy with deep learning
---
```
**Checklist:**
- [ ] Title under 60 characters (so it doesn't get cut off)
- [ ] Description 120-160 characters
- [ ] Include your name in the site title
- [ ] Include keywords naturally
---
### Heading Structure
Use proper HTML heading hierarchy for both SEO and accessibility:
```markdown
# H1: Main Page Title
Use one H1 per page, usually your blog post or page title
## H2: Section Heading
### H3: Subsection
### H3: Another subsection
## H2: Another Section
```
**Benefits:**
- Search engines understand your content structure
- Screen readers can navigate better
- Visitors can scan your content
---
### Image Optimization
**For SEO:**
- Use descriptive filenames: `neural-network-architecture.png` (not `img1.png`)
- Add alt text (also helps accessibility):
```markdown
![Neural network showing three layers with training accuracy of 95%](assets/img/neural-network.png)
```
**For performance:**
- Optimize image file size (use tools like TinyPNG)
- Use modern formats (WebP instead of large JPGs)
- Responsive images (different sizes for mobile vs desktop)
---
### Internal Linking
Link between your own pages strategically:
```markdown
See my [publication on climate AI](./publications/) or my [blog post on neural networks](/blog/2024/neural-networks/).
```
**Benefits:**
- Search engines crawl through your links
- Users discover more of your content
- Distributes "authority" across your site
---
## RSS Feed for Discovery
al-folio auto-generates an RSS feed at `/feed.xml`.
**Why RSS matters:**
- Content aggregators pick up your posts
- Researchers can subscribe to your updates
- Improves discoverability
**Ensure your feed works:**
```yaml
# In _config.yml
title: Your Site
description: Your site description
url: https://your-domain.com # MUST be complete URL
```
**Test your feed:**
- Visit `https://your-site.com/feed.xml`
- Should show XML with your recent posts
- Try subscribing in a feed reader (Feedly, etc.)
---
## Performance & Mobile
Search engines favor fast, mobile-friendly sites.
**Check your site:**
- Use [Google PageSpeed Insights](https://pagespeed.web.dev/)
- Enter your site URL
- Review recommendations
- al-folio already optimizes for performance, but you can improve further:
- Compress images
- Minimize CSS/JS (enabled by default)
- Use lazy loading (already enabled)
**Mobile optimization:**
- al-folio is responsive by default
- Test on phones/tablets
- Ensure buttons are large enough to tap
- Check readability on small screens
---
## SEO Checklist
Before considering your site "SEO optimized":
**Basic Setup:**
- [ ] `_config.yml` has `title`, `description`, `author`, `url`
- [ ] Sitemap accessible at `/sitemap.xml`
- [ ] `robots.txt` accessible at `/robots.txt`
- [ ] Mobile-friendly (test on phone)
**Search Console:**
- [ ] Google Search Console linked
- [ ] Bing Webmaster Tools linked (optional but recommended)
- [ ] No major indexing errors
- [ ] Sitemaps submitted
**Schema/Open Graph:**
- [ ] `serve_og_meta: true` (for social sharing)
- [ ] `serve_schema_org: true` (for structured data)
- [ ] Test OG with [Facebook Debugger](https://developers.facebook.com/tools/debug/sharing/)
- [ ] Validate schema at [Schema.org Validator](https://validator.schema.org/)
**Content:**
- [ ] Every page has unique title (under 60 chars)
- [ ] Every page has description (120-160 chars)
- [ ] Blog posts have proper dates
- [ ] Images have descriptive alt text
- [ ] Headings follow proper hierarchy
**Publications:**
- [ ] BibTeX entries have proper format
- [ ] PDFs linked from BibTeX
- [ ] Submitted to Google Scholar (optional)
- [ ] Indexed on DBLP or arXiv (if applicable)
**Performance:**
- [ ] Site loads under 3 seconds (check PageSpeed)
- [ ] No broken links (use lighthouse or similar)
- [ ] RSS feed works (check `/feed.xml`)
---
## Resources
- **[Google Search Central](https://developers.google.com/search)** Official SEO guide
- **[Moz SEO Checklist](https://moz.com/beginners-guide-to-seo)** Beginner-friendly guide
- **[Google PageSpeed Insights](https://pagespeed.web.dev/)** Performance analysis
- **[Schema.org](https://schema.org/)** Structured data reference
- **[WebAIM](https://webaim.org/)** Accessibility (helps SEO too)
- **[Lighthouse Audit](https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpombljlkpstvnztVTNyZe)** Browser extension
---
**Next Steps:**
1. Enable Open Graph and Schema.org in `_config.yml`
2. Set up Google Search Console and Bing Webmaster Tools
3. Optimize your page titles and descriptions
4. Add alt text to images and PDFs to your BibTeX
5. Monitor search console regularly for indexing issues
Your research will be more discoverable with these optimizations! 🔍

454
TROUBLESHOOTING.md Normal file
View File

@ -0,0 +1,454 @@
# Troubleshooting Guide
This guide covers common issues and their solutions. For more information, see [FAQ.md](FAQ.md) or check [GitHub Discussions](https://github.com/alshedivat/al-folio/discussions).
<!--ts-->
- [Troubleshooting Guide](#troubleshooting-guide)
- [Deployment Issues](#deployment-issues)
- [Site fails to deploy on GitHub Pages](#site-fails-to-deploy-on-github-pages)
- [Custom domain becomes blank after deployment](#custom-domain-becomes-blank-after-deployment)
- [GitHub Actions: "Unknown tag 'toc'" error](#github-actions-unknown-tag-toc-error)
- [Local Build Issues](#local-build-issues)
- [Docker build fails](#docker-build-fails)
- [Ruby dependency issues](#ruby-dependency-issues)
- [Port already in use](#port-already-in-use)
- [Styling &amp; Layout Problems](#styling--layout-problems)
- [CSS and JS not loading properly](#css-and-js-not-loading-properly)
- [Site looks broken after deployment](#site-looks-broken-after-deployment)
- [Theme colors not applying](#theme-colors-not-applying)
- [Content Not Appearing](#content-not-appearing)
- [Blog posts not showing up](#blog-posts-not-showing-up)
- [Publications not displaying](#publications-not-displaying)
- [Images not loading](#images-not-loading)
- [Configuration Issues](#configuration-issues)
- [YAML syntax errors](#yaml-syntax-errors)
- [Feed (RSS/Atom) not working](#feed-rssatom-not-working)
- [Search not working](#search-not-working)
- [Feature-Specific Issues](#feature-specific-issues)
- [Comments (Giscus) not appearing](#comments-giscus-not-appearing)
- [Related posts broken](#related-posts-broken)
- [Code formatting issues](#code-formatting-issues)
- [Getting Help](#getting-help)
<!--te-->
## Deployment Issues
### Site fails to deploy on GitHub Pages
**Problem:** GitHub Actions shows an error when deploying.
**Solution:**
1. Check your repository **Actions** tab for error messages
2. Ensure you followed [Step 2 of QUICKSTART.md](QUICKSTART.md#step-2-configure-deployment-1-min) (Workflow permissions)
3. Verify your `_config.yml` has correct `url` and `baseurl`:
- Personal site: `url: https://username.github.io` and `baseurl:` (empty)
- Project site: `url: https://username.github.io` and `baseurl: /repo-name/`
4. Check that you're pushing to the `main` (or `master`) branch, NOT `gh-pages`
5. Commit and push a small change to trigger redeployment
**For YAML syntax errors:**
- Run `bundle exec jekyll build` locally to see the exact error
- Check for unquoted special characters (`:`, `&`, `#`) in YAML strings
---
### Custom domain becomes blank after deployment
**Problem:** You set a custom domain (e.g., `example.com`), but it resets to blank after deployment.
**Solution:**
1. Create a file named `CNAME` (no extension) in your repository root
2. Add your domain to it: `example.com` (one domain per line)
3. Commit and push
4. The domain will persist after future deployments
(See [DNS configuration instructions in INSTALL.md](INSTALL.md#deployment) for initial custom domain setup.)
---
### GitHub Actions: "Unknown tag 'toc'" error
**Problem:** Local build works, but GitHub Actions fails with `Unknown tag 'toc'`.
**Solution:**
1. Check your **Settings****Pages****Source** is set to `Deploy from a branch`
2. Ensure the branch is set to `gh-pages` (NOT `main`)
3. Wait 5 minutes and check Actions again
4. The issue usually resolves after you verify the gh-pages branch is set
---
## Local Build Issues
### Docker build fails
**Problem:** `docker compose up` fails or shows errors.
**Solution:**
1. Update Docker: `docker compose pull`
2. Rebuild: `docker compose up --build`
3. If still failing, check your system resources (disk space, RAM)
4. For M1/M2 Mac users, verify you're using a compatible Docker version
5. Check Docker Desktop is running
**For permission issues:**
- Linux users may need to add your user to the docker group: `sudo usermod -aG docker $USER`
- Then log out and log back in
---
### Ruby dependency issues
**Problem:** `Gemfile.lock` conflicts or bundle errors.
**Solution:**
1. Delete `Gemfile.lock`: `rm Gemfile.lock`
2. Update Bundler: `bundle update`
3. Install gems: `bundle install`
4. Try serving again: `bundle exec jekyll serve`
---
### Port already in use
**Problem:** "Address already in use" when running `jekyll serve`.
**Solution - Docker:**
```bash
docker compose down # Stop the running container
docker compose up # Start fresh
```
**Solution - Local Ruby:**
```bash
# Find and kill the Jekyll process
lsof -i :4000 | grep LISTEN | awk '{print $2}' | xargs kill
# Or specify a different port
bundle exec jekyll serve --port 5000
```
---
## Styling & Layout Problems
### CSS and JS not loading properly
**Problem:** Site looks broken: no colors, fonts wrong, links don't work.
**Common cause:** Incorrect `url` and `baseurl` in `_config.yml`.
**Solution:**
1. **Personal/organization site:**
```yaml
url: https://username.github.io
baseurl: # MUST be empty (not deleted)
```
2. **Project site:**
```yaml
url: https://username.github.io
baseurl: /repository-name/ # Must match your repo name
```
3. **Clear browser cache:**
- Chrome: `Ctrl+Shift+R` (Windows/Linux) or `Cmd+Shift+R` (Mac)
- Firefox: `Ctrl+F5` (Windows/Linux) or `Cmd+R` (Mac)
- Or open a private/incognito window
4. Redeploy: Make a small change and push to trigger GitHub Actions again
---
### Site looks broken after deployment
**Checklist:**
- [ ] Is `baseurl` correct (and not accidentally deleted)?
- [ ] Did you clear your browser cache?
- [ ] Wait 5 minutes for GitHub Pages to update
- [ ] Check GitHub Actions completed successfully
---
### Theme colors not applying
**Problem:** You changed `_config.yml` color settings but nothing changed.
**Solution:**
1. Check your color name is valid in `_sass/_variables.scss`
2. Clear browser cache (see above)
3. Rebuild: `docker compose up --build` (Docker) or `bundle exec jekyll build` (Ruby)
4. Wait for GitHub Actions to complete
5. Visit the site in a private/incognito window
---
## Content Not Appearing
### Blog posts not showing up
**Problem:** Created a post in `_posts/` but it's not on the blog page.
**Checklist:**
- [ ] Filename format is correct: `YYYY-MM-DD-title.md` (e.g., `2024-01-15-my-post.md`)
- [ ] File is in the `_posts/` directory (not in a subdirectory)
- [ ] Post has required frontmatter:
```markdown
---
layout: post
title: My Post Title
date: 2024-01-15
---
```
- [ ] Post date is NOT in the future (Jekyll doesn't publish future-dated posts by default)
- [ ] Blog posts are enabled in `_config.yml`: `blog_page: true`
**To fix:**
1. Check the filename format (uppercase, dashes, no spaces)
2. Verify the date is today or in the past
3. Rebuild: `bundle exec jekyll build` and check for error messages
---
### Publications not displaying
**Problem:** You added a BibTeX entry to `papers.bib` but it's not showing on the publications page.
**Checklist:**
- [ ] File is at `_bibliography/papers.bib`
- [ ] BibTeX syntax is correct (check for missing commas, unmatched braces)
- [ ] Entry has a unique citation key: `@article{einstein1905, ...}`
- [ ] Publication page is enabled: Check `publications_page: true` in `_config.yml`
**To debug BibTeX errors:**
```bash
# Local Ruby setup
bundle exec jekyll build 2>&1 | grep -i bibtex
# Docker
docker compose run --rm web jekyll build 2>&1 | grep -i bibtex
```
---
### Images not loading
**Problem:** Image paths broken or showing as missing.
**Common causes:**
- Wrong path in Markdown (use relative paths)
- Image file doesn't exist at the specified location
- Case sensitivity (Linux/Mac are case-sensitive)
**Solutions:**
1. **Correct path format:**
```markdown
![Alt text](assets/img/image-name.jpg)
```
2. **Check the file exists:**
- Personal images: `assets/img/`
- Paper PDFs: `assets/pdf/`
- Use lowercase filenames, no spaces
3. **For BibTeX PDF links:**
```bibtex
@article{mykey,
pdf={my-paper.pdf}, % File should be at assets/pdf/my-paper.pdf
}
```
---
## Configuration Issues
### YAML syntax errors
**Problem:** GitHub Actions fails with YAML error, or build is silent.
**Common mistakes:**
```yaml
# ❌ Wrong: Unquoted colons or ampersands
title: My Site: Research & Teaching
# ✅ Correct: Quote special characters
title: "My Site: Research & Teaching"
```
```yaml
# ❌ Wrong: Inconsistent indentation
nav:
- name: Home
url: /
- name: About # Extra space!
url: /about/
# ✅ Correct: Consistent 2-space indentation
nav:
- name: Home
url: /
- name: About
url: /about/
```
**To find errors:**
1. Use a YAML validator: [yamllint.com](https://www.yamllint.com/)
2. Run locally: `bundle exec jekyll build` shows the exact error line
3. Check that you didn't delete required lines (like `baseurl:`)
---
### Feed (RSS/Atom) not working
**Problem:** RSS feed at `/feed.xml` is empty or broken.
**Solution:**
1. Verify required `_config.yml` fields:
```yaml
title: Your Site Title
description: Brief description
url: https://your-domain.com # MUST be absolute URL
```
2. Ensure `baseurl` is correct
3. Check at least one blog post exists (with correct date)
4. Rebuild and wait for GitHub Actions to complete
---
### Search not working
**Problem:** Search box is empty or always returns nothing.
**Solution:**
1. Ensure search is enabled in `_config.yml`:
```yaml
search_enabled: true
```
2. Check that `_config.yml` has a valid `url` (required for search)
3. Rebuild the site
4. Search index is generated during build; give it a minute after push
---
## Feature-Specific Issues
### Comments (Giscus) not appearing
**Problem:** You enabled Giscus in `_config.yml` but comments don't show.
**Solution:**
1. Verify you have a GitHub repository for discussions (usually your main repo)
2. Check `_config.yml` has correct settings:
```yaml
disqus_shortname: false # Make sure this is false
giscus:
repo: username/repo-name
repo_id: YOUR_REPO_ID
category_id: YOUR_CATEGORY_ID
```
3. Visit [Giscus.app](https://giscus.app) to get your IDs and verify setup
4. Check the GitHub repo has Discussions enabled (Settings → Features)
---
### Related posts broken
**Problem:** Related posts feature crashes or shows errors.
**Solution:**
1. Related posts requires more gems. If you disabled it in `_config.yml`, that's fine:
```yaml
related_blog_posts:
enabled: false
```
2. If you want to enable it, ensure `Gemfile` has all dependencies installed:
```bash
bundle install
bundle exec jekyll build
```
---
### Code formatting issues
**Problem:** Code blocks don't have syntax highlighting or look wrong.
**Solution:**
1. Use proper markdown syntax:
````markdown
```python
# Your code here
print("hello")
```
````
2. For inline code:
```markdown
Use `code-here` for inline code.
```
3. Check that your language is supported by Pygments (Python, Ruby, JavaScript, etc. are all supported)
---
## Getting Help
If you're stuck:
1. **Check existing documentation:**
- [QUICKSTART.md](QUICKSTART.md) Get started in 5 minutes
- [INSTALL.md](INSTALL.md) Installation and deployment
- [CUSTOMIZE.md](CUSTOMIZE.md) Full customization guide
- [FAQ.md](FAQ.md) Frequently asked questions
2. **Search for your issue:**
- [GitHub Discussions](https://github.com/alshedivat/al-folio/discussions) Q&A from community
- [GitHub Issues](https://github.com/alshedivat/al-folio/issues) Bug reports and feature requests
3. **Get help from AI:**
- Use the **GitHub Copilot Customization Agent** (requires Copilot subscription) to get step-by-step help
- See [CUSTOMIZE.md § GitHub Copilot Customization Agent](CUSTOMIZE.md#github-copilot-customization-agent)
4. **Create a new discussion:**
- [Ask a question](https://github.com/alshedivat/al-folio/discussions/new?category=q-a) on GitHub
- Include error messages and what you're trying to do
---
**Most issues are resolved by:**
1. Checking `url` and `baseurl` in `_config.yml`
2. Clearing browser cache
3. Waiting for GitHub Actions to complete (~5 minutes)

28
_books/the_godfather.md Normal file
View File

@ -0,0 +1,28 @@
---
layout: book-review
title: The Godfather
author: Mario Puzo
cover: assets/img/book_covers/the_godfather.jpg
olid: OL43499941M # use Open Library ID to fetch cover (if no `cover` is provided)
isbn: 7539967447 # use ISBN to fetch cover (if no `olid` is provided, dashes are optional)
categories: classics crime historical-fiction mystery novels thriller
tags: top-100
buy_link: https://www.amazon.com/Godfather-Deluxe-Mario-Puzo/dp/0593542592
date: 2024-08-23
started: 2024-08-23
finished: 2024-09-07
released: 1969
stars: 5
goodreads_review: 6318556633
status: Finished
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sollicitudin eros sit amet ante aliquet, sit amet vulputate lectus mattis. Aenean ullamcorper pretium nunc, sed egestas lorem elementum id. Nulla id mi id neque ultrices egestas ut in urna. Sed ac ultricies nunc. Nam convallis placerat urna id egestas. Nulla porta, est interdum vestibulum venenatis, lorem odio laoreet sapien, in pulvinar tellus eros a dolor. Vivamus sapien justo, ullamcorper a mi eget, scelerisque euismod nunc. In augue augue, ultrices a ornare non, tincidunt quis justo. Donec sit amet consectetur eros. Nullam neque leo, tincidunt id ipsum ac, volutpat lobortis mi. Phasellus consequat ultricies arcu, eu semper ligula ultrices eget. Ut in fringilla elit, ac tincidunt nisi.
Nunc commodo elit nec turpis feugiat consectetur. Nullam in nisi egestas, fermentum ligula hendrerit, euismod enim. Nulla eu hendrerit eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin et velit ante. Vestibulum pretium vitae quam et sagittis. Proin eu nunc vel velit accumsan eleifend. Nulla facilisis, diam tempus imperdiet ultrices, massa ipsum consequat orci, sed efficitur eros mi a felis. Cras lobortis turpis sem, sed lobortis nunc ullamcorper tristique. Nam vehicula rhoncus ante, in faucibus sapien scelerisque et. Donec semper libero et tincidunt mattis. In vestibulum, nulla pretium dictum commodo, risus nulla vestibulum felis, at tincidunt massa mi in odio. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Donec efficitur ultrices purus sit amet imperdiet. Nam consequat metus in erat sodales faucibus. Aliquam maximus fermentum nulla id finibus. Aliquam iaculis sed odio vel rutrum. Curabitur sed odio est. Praesent nec sollicitudin tortor. Praesent pharetra, turpis quis porttitor rhoncus, ante massa fringilla lacus, nec porttitor magna turpis vitae felis. Nullam tristique massa id odio imperdiet, nec sodales massa egestas. Proin nisi metus, euismod sed accumsan vitae, facilisis vel risus. Morbi suscipit auctor erat, nec viverra elit fringilla eu. Mauris congue, purus id tristique facilisis, felis nisi efficitur magna, eu consectetur augue sem vitae lacus. Aliquam erat volutpat. Cras at nibh ultricies, volutpat arcu vitae, dictum est. In ac dolor sagittis, egestas lectus et, semper nisl. Etiam consectetur purus vitae sapien porttitor auctor.
Nulla sit amet venenatis odio. Suspendisse ac lacus quis augue mollis tempus vel in lorem. Donec augue turpis, eleifend nec nibh eu, elementum dictum metus. Proin ut est ligula. Etiam vehicula facilisis metus, sit amet consectetur risus ullamcorper porttitor. In congue nibh quis sollicitudin iaculis. Donec a mollis lorem, non mollis lacus. Nulla et leo ex. Aliquam erat volutpat. Nam sit amet tincidunt mauris. Vivamus vitae est sit amet nisi semper egestas. Donec in diam pharetra, commodo diam vitae, imperdiet ligula. Cras iaculis ac diam eget vehicula. Proin suscipit ante enim, quis vehicula mi porta bibendum. Aliquam a diam porttitor, sollicitudin justo vitae, tempor odio.
Cras fermentum dignissim pretium. Donec quis turpis eu neque lacinia facilisis in sit amet nibh. Nulla non tortor ultricies, euismod est in, blandit nibh. Ut a neque metus. Sed convallis condimentum nibh quis finibus. Praesent aliquam sem iaculis eros maximus accumsan. Nulla venenatis mauris id aliquet maximus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin at enim vitae ex porttitor vestibulum sed eget nibh. Suspendisse accumsan feugiat quam eget ultricies.

View File

@ -20,7 +20,8 @@ icon: 🎓 # 🧥 # 🚀 #🚲 # 🌐 #👤 # 🧑🏼‍💻 # 🧔 # 🛰️ #
url: https://florent.guiotte.fr # the base hostname & protocol for your site url: https://florent.guiotte.fr # the base hostname & protocol for your site
baseurl: # the subpath of your site, e.g. /blog/ baseurl: # the subpath of your site, e.g. /blog/
last_updated: false # set to true if you want to display last updated in the footer last_updated: false # set to true if you want to display last updated in the footer
impressum_path: # set to path to include impressum link in the footer, use the same path as permalink in a page, helps to conform with EU GDPR impressum_path: # set to path to include impressum link in the footer, use the same path as permalink in a page, helps to conform with EU GDPR
back_to_top: true # set to false to disable the back to top button
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Theme # Theme
@ -31,8 +32,19 @@ highlight_theme_light: tango # assets/stylesheets/
highlight_theme_dark: zenburn # assets/stylesheets/ highlight_theme_dark: zenburn # assets/stylesheets/
# repo color theme # repo color theme
repo_theme_light: default # https://github.com/anuraghazra/github-readme-stats/blob/master/themes/README.md repo_theme_light: default # https://github.com/anuraghazra/github-readme-stats/blob/master/themes/README.md
repo_theme_dark: dark # https://github.com/anuraghazra/github-readme-stats/blob/master/themes/README.md repo_theme_dark: dark # https://github.com/anuraghazra/github-readme-stats/blob/master/themes/README.md
repo_trophies:
enabled: true
theme_light: flat # https://github.com/ryo-ma/github-profile-trophy
theme_dark: gitdimmed # https://github.com/ryo-ma/github-profile-trophy
# External service URLs for repository page
# To use a different instance or service for displaying GitHub stats and trophies,
# update these URLs. These are used in the repository templates.
external_services:
github_readme_stats_url: https://github-readme-stats.vercel.app
github_profile_trophy_url: https://github-profile-trophy.vercel.app
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# RSS Feed # RSS Feed
@ -48,66 +60,37 @@ rss_icon: false
navbar_fixed: true navbar_fixed: true
footer_fixed: true footer_fixed: true
search_enabled: true
socials_in_search: true
posts_in_search: true
bib_search: true
# Dimensions # Dimensions
max_width: 800px max_width: 930px
# TODO: add layout settings (single page vs. multi-page)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Open Graph & Schema.org # Open Graph & Schema.org
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Display links to the page with a preview object on social media. # Display links to the page with a preview object on social media.
# see https://schema.org/docs/faq.html for more information
serve_og_meta: false # Include Open Graph meta tags in the HTML head serve_og_meta: false # Include Open Graph meta tags in the HTML head
serve_schema_org: false # Include Schema.org in the HTML head serve_schema_org: false # Include Schema.org in the HTML head
og_image: # The site-wide (default for all links) Open Graph preview image og_image: # The site-wide (default for all links) Open Graph preview image
# -----------------------------------------------------------------------------
# Social integration
# -----------------------------------------------------------------------------
github_username: fguiotte # your GitHub user name
gitlab_username: # your GitLab user name
twitter_username: # your Twitter handle
mastodon_username: # your mastodon instance+username in the format instance.tld/@username
linkedin_username: fguiotte # your LinkedIn user name
telegram_username: # your Telegram user name
scholar_userid: QHs7TucAAAAJ # your Google Scholar ID
semanticscholar_id: # your Semantic Scholar ID
whatsapp_number: # your WhatsApp number (full phone number in international format. Omit any zeroes, brackets, or dashes when adding the phone number in international format.)
orcid_id: # your ORCID ID
medium_username: # your Medium username
quora_username: # your Quora username
publons_id: # your ID on Publons
research_gate_profile: # your profile on ResearchGate
blogger_url: # your blogger URL
work_url: # work page URL
keybase_username: # your keybase user name
wikidata_id: # your wikidata id
dblp_url: # your DBLP profile url
stackoverflow_id: # your stackoverflow id
kaggle_id: # your kaggle id
lastfm_id: # your lastfm id
spotify_id: # your spotify id
pinterest_id: # your pinterest id
unsplash_id: # your unsplash id
instagram_id: # your instagram id
facebook_id: # your facebook id
youtube_id: # your youtube channel id (youtube.com/@<youtube_id>)
discord_id: # your discord id (18-digit unique numerical identifier)
contact_note: >
You can even add a little note about which of these is the best way to reach you.
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Analytics and search engine verification # Analytics and search engine verification
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
google_analytics: # your Goole Analytics measurement ID (format: G-XXXXXXXXXX) # For Google Analytics, see https://support.google.com/analytics/answer/10447272?hl=en&ref_topic=14088998&sjid=5129943941510317771-SA#zippy=%2Cgoogle-sites
panelbear_analytics: # panelbear analytics site ID (format: XXXXXXXXX) # and follow the instructions for Google Sites. You will need to create a Google Analytics property and copy the Google tag ID.
google_analytics: # your Google Analytics measurement ID (format: G-XXXXXXXXXX)
cronitor_analytics: # cronitor RUM analytics site ID (format: XXXXXXXXX)
pirsch_analytics: # your Pirsch analytics site ID (length 32 characters)
openpanel_analytics: # your Openpanel analytics client ID (format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
google_site_verification: # your google-site-verification ID (Google Search Console) # For Google Search Console, see https://support.google.com/webmasters/answer/9008080?hl=en#meta_tag_verification&zippy=%2Chtml-tag
bing_site_verification: # out your bing-site-verification ID (Bing Webmaster) google_site_verification: # your google-site-verification ID (Google Search Console)
bing_site_verification: # out your bing-site-verification ID (Bing Webmaster)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Blog # Blog
@ -117,24 +100,29 @@ blog_name: al-folio # blog_name will be displayed in your blog page
blog_nav_title: # your blog must have a title for it to be displayed in the nav bar blog_nav_title: # your blog must have a title for it to be displayed in the nav bar
blog_description: a simple whitespace theme for academics blog_description: a simple whitespace theme for academics
permalink: /blog/:year/:title/ permalink: /blog/:year/:title/
lsi: false # produce an index for related posts
# Pagination # Pagination
pagination: pagination:
enabled: true enabled: true
related_blog_posts:
enabled: true
max_related: 5
# Giscus comments (RECOMMENDED) # Giscus comments (RECOMMENDED)
# Follow instructions on https://giscus.app/ to setup for your repo to fill out # Follow instructions on https://giscus.app/ to setup for your repo to fill out the information below.
# the information below.
giscus: giscus:
repo: alshedivat/al-folio # <your-github-user-name>/<your-github-repo-name> repo: # <your-github-user-name>/<your-github-repo-name>
repo_id: MDEwOlJlcG9zaXRvcnk2MDAyNDM2NQ== repo_id: # leave empty or specify your repo_id (see https://giscus.app/)
category: Comments # name of the category under which discussions will be created category: Comments # name of the category under which discussions will be created
category_id: DIC_kwDOA5PmLc4CTBt6 category_id: # leave empty or specify your category_id (see https://giscus.app/)
mapping: title # identify discussions by post title mapping: title # identify discussions by post title
strict: 1 # use strict identification mode strict: 1 # use strict identification mode
reactions_enabled: 1 # enable (1) or disable (0) emoji reactions reactions_enabled: 1 # enable (1) or disable (0) emoji reactions
input_position: bottom # whether to display input form below (bottom) or above (top) the comments input_position: bottom # whether to display input form below (bottom) or above (top) the comments
theme: preferred_color_scheme # name of the color scheme (preferred works well with al-folio light/dark mode) dark_theme: dark # name of the dark color scheme (preferred works well with al-folio dark mode)
light_theme: light # name of the light color scheme (preferred works well with al-folio light mode)
emit_metadata: 0 emit_metadata: 0
lang: en lang: en
@ -143,28 +131,45 @@ disqus_shortname: al-folio # put your disqus shortname
# https://help.disqus.com/en/articles/1717111-what-s-a-shortname # https://help.disqus.com/en/articles/1717111-what-s-a-shortname
# External sources. # External sources.
# If you have blog posts published on medium.com or other exteranl sources, # If you have blog posts published on medium.com or other external sources,
# you can display them in your blog by adding a link to the RSS feed. # you can display them in your blog by adding a link to the RSS feed.
# Optional: Set default categories and tags for posts from each source.
external_sources: external_sources:
- name: medium.com - name: medium.com
rss_url: https://medium.com/@al-folio/feed rss_url: https://medium.com/@al-folio/feed
categories: [external-posts]
tags: [medium]
- name: Google Blog
posts:
- url: https://blog.google/technology/ai/google-gemini-update-flash-ai-assistant-io-2024/
published_date: 2024-05-14
categories: [external-posts]
tags: [google]
# -----------------------------------------------------------------------------
# Newsletter
# -----------------------------------------------------------------------------
newsletter:
enabled: false
endpoint: # your loops endpoint (e.g., https://app.loops.so/api/newsletter-form/YOUR-ENDPOINT)
# https://loops.so/docs/forms/custom-form
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Collections # Collections
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
collections: collections:
books:
output: true
news: news:
defaults: defaults:
layout: post layout: post
output: true output: true
permalink: /news/:path/
projects: projects:
output: true output: true
permalink: /projects/:path/ teachings:
output: true
news_scrollable: true # adds a vertical scroll bar if there are more than 3 news items
news_limit: 5 # leave blank to include all the news in the `_news` folder
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Jekyll settings # Jekyll settings
@ -173,36 +178,62 @@ news_limit: 5 # leave blank to include all the news in the `_news` folder
# Markdown and syntax highlight # Markdown and syntax highlight
markdown: Pandoc markdown: Pandoc
highlighter: rouge highlighter: rouge
#pandoc: kramdown:
# extensions: input: GFM
# - filter: mathjax-pandoc-filter syntax_highlighter_opts:
# - '-Mmathjax.centerDisplayMath' # center display math css_class: "highlight"
# - filter: mermaid-filter span:
line_numbers: false
block:
line_numbers: false
start_line: 1
# Includes & excludes # Includes & excludes
include: ['_pages'] include: ["_pages", "_scripts"]
exclude: exclude:
- bin - bin/
- CONTRIBUTING.md
- CUSTOMIZE.md
- Dockerfile
- docker-compose.yml
- docker-compose-slim.yml
- FAQ.md
- Gemfile - Gemfile
- Gemfile.lock - Gemfile.lock
- INSTALL.md
- LICENSE
- lighthouse_results/
- package.json
- package-lock.json
- _pages/about_einstein.md
- purgecss.config.js
- README.md
- readme_preview/
- vendor - vendor
keep_files: keep_files:
- CNAME - CNAME
- .nojekyll - .nojekyll
- .git
# Plug-ins # Plug-ins
plugins: plugins:
- jekyll-archives - jekyll-3rd-party-libraries
- jekyll-diagrams - jekyll-archives-v2
- jekyll-cache-bust
- jekyll-email-protect - jekyll-email-protect
- jekyll-feed - jekyll-feed
- jekyll-get-json
- jekyll-imagemagick - jekyll-imagemagick
- jekyll-jupyter-notebook
- jekyll-link-attributes
- jekyll-minifier - jekyll-minifier
- jekyll-paginate-v2 - jekyll-paginate-v2
- jekyll-regex-replace
- jekyll/scholar - jekyll/scholar
- jekyll-sitemap - jekyll-sitemap
- jekyll-link-attributes - jekyll-socials
- jekyll-tabs
- jekyll-terser
- jekyll-toc
- jekyll-twitter-plugin - jekyll-twitter-plugin
- jemoji - jemoji
- jekyll-pandoc - jekyll-pandoc
@ -210,35 +241,45 @@ plugins:
# Sitemap settings # Sitemap settings
defaults: defaults:
- scope: - scope:
path: "assets/**/*.*" path: "assets"
values: values:
sitemap: false sitemap: false
sass:
style: compressed
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Jekyll Minifier # Jekyll Minifier
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
jekyll-minifier: jekyll-minifier:
exclude: ['robots.txt'] compress_javascript: false # set to false since we are using terser as the js minifier
uglifier_args: exclude: ["robots.txt", "assets/js/search/*.js"]
harmony: true
# -----------------------------------------------------------------------------
# Terser
# -----------------------------------------------------------------------------
terser:
compress:
drop_console: true
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Jekyll Archives # Jekyll Archives
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
jekyll-archives: jekyll-archives:
enabled: [year, tags, categories] # enables year, tag and category archives (remove if you need to disable one of them). posts:
layouts: enabled: [year, tags, categories] # enables year, tag and category archives (remove if you need to disable one of them).
year: archive-year permalinks:
tag: archive-tag year: "/blog/:year/"
category: archive-category tags: "/blog/:type/:name/"
permalinks: categories: "/blog/:type/:name/"
year: '/blog/:year/' books:
tag: '/blog/tag/:name/' enabled: [year, tags, categories] # enables year, tag and category archives (remove if you need to disable one of them).
category: '/blog/category/:name/'
display_tags: ['formatting', 'images', 'links', 'math', 'code'] # this tags will be dispalyed on the front page of your blog display_tags: ["formatting", "images", "links", "math", "code", "blockquotes"] # these tags will be displayed on the front page of your blog
display_categories: ["external-services"] # these categories will be displayed on the front page of your blog
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Jekyll Scholar # Jekyll Scholar
@ -264,23 +305,57 @@ scholar:
join_strings: true join_strings: true
details_dir: bibliography details_dir: bibliography
details_layout: bibtex.html
details_link: Details details_link: Details
query: "@*" query: "@*"
group_by: year
group_order: descending
badges: # Display different badges for your pulications # Display different badges withs stats for your publications
altmetric_badge: false # Altmetric badge (https://www.altmetric.com/products/altmetric-badges/) # Customize badge behavior in _layouts/bib.liquid
dimensions_badge: false # Dimensions badge (https://badge.dimensions.ai/) enable_publication_badges:
altmetric: true # Altmetric badge (Customization options: https://badge-docs.altmetric.com/index.html)
dimensions: true # Dimensions badge (Customization options: https://badge.dimensions.ai/)
google_scholar: true # Google Scholar badge (https://scholar.google.com/intl/en/scholar/citations.html)
inspirehep: true # Inspire HEP badge (https://help.inspirehep.net/knowledge-base/citation-metrics/)
# Filter out certain bibtex entry keywords used internally from the bib output # Filter out certain bibtex entry keywords used internally from the bib output
bibtex_show: true filtered_bibtex_keywords:
filtered_bibtex_keywords: [abbr, abstract, arxiv, bibtex_show, html, pdf, selected, supp, blog, code, poster, slides, website, preview, altmetric, keywords, annotation] [
abbr,
abstract,
additional_info,
altmetric,
annotation,
arxiv,
award,
award_name,
bibtex_show,
blog,
code,
dimensions,
eprint,
google_scholar_id,
hal,
html,
inspirehep_id,
pdf,
pmid,
poster,
preview,
selected,
slides,
supp,
video,
website,
]
# Maximum number of authors to be shown for each publication (more authors are visible on click) # Maximum number of authors to be shown for each publication (more authors are visible on click)
max_author_limit: 3 # leave blank to always show all authors max_author_limit: 3 # leave blank to always show all authors
more_authors_animation_delay: 10 # more authors are revealed on click using animation; smaller delay means faster animation more_authors_animation_delay: 10 # more authors are revealed on click using animation; smaller delay means faster animation
# Enables publication thumbnails. If disabled, none of the publications will display thumbnails, even if specified in the bib entry.
enable_publication_thumbnails: true
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Jekyll Link Attributes # Jekyll Link Attributes
@ -293,13 +368,14 @@ external_links:
target: _blank target: _blank
exclude: exclude:
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Responsive WebP Images # Responsive WebP Images
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# MAKE SURE imagemagick is installed and on your PATH before enabling imagemagick. In a terminal, run:
# convert -version
imagemagick: imagemagick:
enabled: true # enables responsive images for your site (recomended, see https://github.com/alshedivat/al-folio/issues/537) enabled: true # enables responsive images for your site (recommended, see https://github.com/alshedivat/al-folio/issues/537)
widths: widths:
- 480 - 480
- 800 - 800
@ -311,66 +387,294 @@ imagemagick:
- ".jpeg" - ".jpeg"
- ".png" - ".png"
- ".tiff" - ".tiff"
- ".gif"
output_formats: output_formats:
webp: "-resize 800x" webp: "-auto-orient -quality 85"
# -----------------------------------------------------------------------------
# Jekyll Diagrams
# -----------------------------------------------------------------------------
jekyll-diagrams:
# configuration, see https://github.com/zhustec/jekyll-diagrams.
# feel free to comment out this section if not using jekyll diagrams.
# Lazy loading images
# If you enable lazy loading, all images will add the loading="lazy" attribute.
# This will make your site load faster, but it may not be supported in all browsers.
# You can also set loading="" to other values for specific images to override the default behavior.
# Options: "auto", "eager", "lazy"
# See https://web.dev/browser-level-image-lazy-loading/ for more information.
lazy_loading_images: true # enables lazy loading of images (recommended)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Optional Features # Optional Features
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
enable_google_analytics: false # enables google analytics enable_google_analytics: false # enables google analytics
enable_panelbear_analytics: false # enables panelbear analytics enable_cronitor_analytics: false # enables cronitor RUM analytics
enable_google_verification: false # enables google site verification enable_pirsch_analytics: false # enables Pirsch analytics (https://pirsch.io/)
enable_bing_verification: false # enables bing site verification enable_openpanel_analytics: false # enables Openpanel analytics (https://openpanel.dev/)
enable_masonry: true # enables automatic project cards arangement enable_google_verification: false # enables google site verification
enable_math: true # enables math typesetting (uses MathJax) enable_bing_verification: false # enables bing site verification
enable_tooltips: false # enables automatic tooltip links generated enable_cookie_consent: false # enables GDPR-compliant cookie consent dialog (https://github.com/orestbida/cookieconsent)
# for each section titles on pages and posts enable_masonry: true # enables automatic project cards arrangement
enable_darkmode: true # enables switching between light/dark modes enable_math: true # enables math typesetting (uses MathJax)
enable_navbar_social: true # enables displaying social links in the enable_tooltips: false # enables automatic tooltip links generated for each section titles on pages and posts
# navbar on the about page enable_darkmode: true # enables switching between light/dark modes
enable_project_categories: true # enables categorization of projects into enable_navbar_social: false # enables displaying social links in the navbar on the about page
# multiple categories enable_project_categories: true # enables categorization of projects into multiple categories
enable_medium_zoom: true # enables image zoom feature (as on medium.com) enable_medium_zoom: true # enables image zoom feature (as on medium.com)
enable_progressbar: true # enables a horizontal progress bar linked to the vertical scroll position enable_progressbar: true # enables a horizontal progress bar linked to the vertical scroll position
enable_video_embedding: false # enables video embedding for bibtex entries. If false, the button opens the video link in a new window.
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Library versions # Library versions
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
academicons: # Add the url, version and integrity hash of the libraries you use in your site.
version: "1.9.1" # The integrity hash is used to ensure that the library is not tampered with.
integrity: "sha256-i1+4qU2G2860dGGIOJscdC30s9beBXjFfzjWLjBRsBg=" # Integrity hashes not provided by the libraries were generated using https://www.srihash.org/
bootstrap: third_party_libraries:
version: "4.6.1" download: false # if true, download the versions of the libraries specified below and use the downloaded files
integrity: bootstrap-table:
css: "sha256-DF7Zhf293AJxJNTmh5zhoYYIMs2oXitRfBjY+9L//AY=" integrity:
js: "sha256-fgLAgv7fyCGopR/gBNq2iW3ZKIdqIcyshnUULC4vex8=" css: "sha256-uRX+PiRTR4ysKFRCykT8HLuRCub26LgXJZym3Yeom1c="
fontawesome: js: "sha256-4rppopQE9POKfukn2kEvhJ9Um25Cf6+IDVkARD0xh78="
version: "5.15.4" url:
integrity: "sha256-mUZM63G8m73Mcidfrv5E+Y61y7a12O5mW4ezU3bxqW4=" css: "https://cdn.jsdelivr.net/npm/bootstrap-table@{{version}}/dist/bootstrap-table.min.css"
jquery: js: "https://cdn.jsdelivr.net/npm/bootstrap-table@{{version}}/dist/bootstrap-table.min.js"
version: "3.6.0" version: "1.22.4"
integrity: "sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" chartjs:
mathjax: integrity:
version: "3.2.0" js: "sha256-0q+JdOlScWOHcunpUk21uab1jW7C1deBQARHtKMcaB4="
masonry: url:
version: "4.2.2" js: "https://cdn.jsdelivr.net/npm/chart.js@{{version}}/dist/chart.umd.min.js"
integrity: "sha256-Nn1q/fx0H7SNLZMQ5Hw5JLaTRZp0yILA/FRexe19VdI=" version: "4.4.1"
mdb: d3:
version: "4.20.0" integrity:
integrity: js: "sha256-1rA678n2xEx7x4cTZ5x4wpUCj6kUMZEZ5cxLSVSFWxw="
css: "sha256-jpjYvU3G3N6nrrBwXJoVEYI/0zw8htfFnhT9ljN3JJw=" url:
js: "sha256-NdbiivsvWt7VYCt6hYNT3h/th9vSTL4EDWeGs5SN3DA=" js: "https://cdn.jsdelivr.net/npm/d3@{{version}}/dist/d3.min.js"
medium_zoom: version: "7.8.5"
version: "1.0.8" diff2html:
integrity: "sha256-7PhEpEWEW0XXQ0k6kQrPKwuoIomz8R8IYyuU1Qew4P8=" integrity:
css: "sha256-IMBK4VNZp0ivwefSn51bswdsrhk0HoMTLc2GqFHFBXg="
js: "sha256-eU2TVHX633T1o/bTQp6iIJByYJEtZThhF9bKz/DcbbY="
url:
css: "https://cdn.jsdelivr.net/npm/diff2html@{{version}}/bundles/css/diff2html.min.css"
js: "https://cdn.jsdelivr.net/npm/diff2html@{{version}}/bundles/js/diff2html-ui.min.js"
version: "3.4.47"
echarts:
integrity:
js:
library: "sha256-QvgynZibb2U53SsVu98NggJXYqwRL7tg3FeyfXvPOUY="
dark_theme: "sha256-sm6Ui9w41++ZCWmIWDLC18a6ki72FQpWDiYTDxEPXwU="
url:
js:
library: "https://cdn.jsdelivr.net/npm/echarts@{{version}}/dist/echarts.min.js"
dark_theme: "https://cdn.jsdelivr.net/npm/echarts@{{version}}/theme/dark-fresh-cut.js"
version: "5.5.0"
google_fonts:
url:
fonts: "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Roboto+Slab:100,300,400,500,700|Material+Icons&display=swap"
highlightjs:
integrity:
css:
light: "sha256-Oppd74ucMR5a5Dq96FxjEzGF7tTw2fZ/6ksAqDCM8GY="
dark: "sha256-nyCNAiECsdDHrr/s2OQsp5l9XeY2ZJ0rMepjCT2AkBk="
url:
css:
light: "https://cdn.jsdelivr.net/npm/highlight.js@{{version}}/styles/github.min.css"
dark: "https://cdn.jsdelivr.net/npm/highlight.js@{{version}}/styles/github-dark.min.css"
version: "11.9.0"
imagesloaded:
integrity:
js: "sha256-htrLFfZJ6v5udOG+3kNLINIKh2gvoKqwEhHYfTTMICc="
url:
js: https://cdn.jsdelivr.net/npm/imagesloaded@{{version}}/imagesloaded.pkgd.min.js
version: "5.0.0"
img-comparison-slider:
integrity:
css: "sha256-3qTIuuUWIFnnU3LpQMjqiXc0p09rvd0dmj+WkpQXSR8="
js: "sha256-EXHg3x1K4oIWdyohPeKX2ZS++Wxt/FRPH7Nl01nat1o="
map: "sha256-3wfqS2WU5kGA/ePcgFzJXl5oSN1QsgZI4/edprTgX8w="
url:
css: "https://cdn.jsdelivr.net/npm/img-comparison-slider@{{version}}/dist/styles.min.css"
js: "https://cdn.jsdelivr.net/npm/img-comparison-slider@{{version}}/dist/index.min.js"
map: "https://cdn.jsdelivr.net/npm/img-comparison-slider@{{version}}/dist/index.js.map"
version: "8.0.6"
jquery:
integrity:
js: "sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
url:
js: "https://cdn.jsdelivr.net/npm/jquery@{{version}}/dist/jquery.min.js"
version: "3.6.0"
leaflet:
integrity:
css: "sha256-q9ba7o845pMPFU+zcAll8rv+gC+fSovKsOoNQ6cynuQ="
js: "sha256-MgH13bFTTNqsnuEoqNPBLDaqxjGH+lCpqrukmXc8Ppg="
js_map: "sha256-YAoQ3FzREN4GmVENMir8vgHHypC0xfSK3CAxTHCqx1M="
local:
images: "images/"
url:
css: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.min.css"
images: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/images/"
js: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.min.js"
js_map: "https://cdn.jsdelivr.net/npm/leaflet@{{version}}/dist/leaflet.js.map"
version: "1.9.4"
lightbox2:
integrity:
css: "sha256-uypRbsAiJcFInM/ndyI/JHpzNe6DtUNXaWEUWEPfMGo="
js: "sha256-A6jI5V9s1JznkWwsBaRK8kSeXLgIqQfxfnvdDOZEURY="
url:
css: "https://cdn.jsdelivr.net/npm/lightbox2@{{version}}/dist/css/lightbox.min.css"
js: "https://cdn.jsdelivr.net/npm/lightbox2@{{version}}/dist/js/lightbox.min.js"
version: "2.11.5"
mathjax:
integrity:
js: "sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="
local:
fonts: "output/chtml/fonts/woff-v2/"
url:
fonts: "https://cdn.jsdelivr.net/npm/mathjax@{{version}}/es5/output/chtml/fonts/woff-v2/"
js: "https://cdn.jsdelivr.net/npm/mathjax@{{version}}/es5/tex-mml-chtml.js"
version: "3.2.2"
masonry:
integrity:
js: "sha256-Nn1q/fx0H7SNLZMQ5Hw5JLaTRZp0yILA/FRexe19VdI="
url:
js: "https://cdn.jsdelivr.net/npm/masonry-layout@{{version}}/dist/masonry.pkgd.min.js"
version: "4.2.2"
mdb:
integrity:
css: "sha256-jpjYvU3G3N6nrrBwXJoVEYI/0zw8htfFnhT9ljN3JJw="
css_map: "sha256-iYYMNfsJdVZjvsebJulg09miBXM4/GMTJgv1u5EZFFM="
js: "sha256-NdbiivsvWt7VYCt6hYNT3h/th9vSTL4EDWeGs5SN3DA="
js_map: "sha256-UPgyn4YNsT0khkBK5553QwhnlbTlU0aa+igyc6qP1bE="
url:
css: "https://cdn.jsdelivr.net/npm/mdbootstrap@{{version}}/css/mdb.min.css"
css_map: "https://cdn.jsdelivr.net/npm/mdbootstrap@{{version}}/css/mdb.min.css.map"
js: "https://cdn.jsdelivr.net/npm/mdbootstrap@{{version}}/js/mdb.min.js"
js_map: "https://cdn.jsdelivr.net/npm/mdbootstrap@{{version}}/js/mdb.min.js.map"
version: "4.20.0"
medium_zoom:
integrity:
js: "sha256-ZgMyDAIYDYGxbcpJcfUnYwNevG/xi9OHKaR/8GK+jWc="
url:
js: "https://cdn.jsdelivr.net/npm/medium-zoom@{{version}}/dist/medium-zoom.min.js"
version: "1.1.0"
mermaid:
integrity:
js: "sha256-TtLOdUA8mstPoO6sGvHIGx2ceXrrX4KgIItO06XOn8A="
url:
js: "https://cdn.jsdelivr.net/npm/mermaid@{{version}}/dist/mermaid.min.js"
version: "10.7.0"
photoswipe:
integrity:
js: "sha256-VCBpdxvrNNxGHNuTdNqK9kPFkev2XY7DYzHdmgaB69Q="
url:
css: "https://cdn.jsdelivr.net/npm/photoswipe@{{version}}/dist/photoswipe.min.css"
js: "https://cdn.jsdelivr.net/npm/photoswipe@{{version}}/dist/photoswipe.esm.min.js"
version: "5.4.4"
photoswipe-lightbox:
integrity:
js: "sha256-uCw4VgT5DMdwgtjhvU9e98nT2mLZXcw/8WkaTrDd3RI="
url:
js: "https://cdn.jsdelivr.net/npm/photoswipe@{{version}}/dist/photoswipe-lightbox.esm.min.js"
version: "5.4.4"
plotly:
integrity:
js: "sha256-oy6Be7Eh6eiQFs5M7oXuPxxm9qbJXEtTpfSI93dW16Q="
url:
js: "https://cdn.jsdelivr.net/npm/plotly.js@{{version}}/dist/plotly.min.js"
version: "3.0.1"
polyfill:
url:
js: "https://cdnjs.cloudflare.com/polyfill/v{{version}}/polyfill.min.js?features=es6"
version: "3"
pseudocode:
integrity:
css: "sha256-VwMV//xgBPDyRFVSOshhRhzJRDyBmIACniLPpeXNUdc="
js: "sha256-aVkDxqyzrB+ExUsOY9PdyelkDhn/DfrjWu08aVpqNlo="
url:
css: "https://cdn.jsdelivr.net/npm/pseudocode@{{version}}/build/pseudocode.min.css"
js: "https://cdn.jsdelivr.net/npm/pseudocode@{{version}}/build/pseudocode.min.js"
version: "2.4.1"
spotlight:
integrity:
css: "sha256-Dsvkx8BU8ntk9Iv+4sCkgHRynYSQQFP6gJfBN5STFLY="
url:
css: "https://cdn.jsdelivr.net/npm/spotlight.js@{{version}}/dist/css/spotlight.min.css"
js: "https://cdn.jsdelivr.net/npm/spotlight.js@{{version}}/dist/spotlight.bundle.min.js"
version: "0.7.8"
swiper:
integrity:
css: "sha256-yUoNxsvX+Vo8Trj3lZ/Y5ZBf8HlBFsB6Xwm7rH75/9E="
js: "sha256-BPrwikijIybg9OQC5SYFFqhBjERYOn97tCureFgYH1E="
map: "sha256-lbF5CsospW93otqvWOIbbhj80CjazrZXvamD7nC7TBI="
url:
css: "https://cdn.jsdelivr.net/npm/swiper@{{version}}/swiper-bundle.min.css"
js: "https://cdn.jsdelivr.net/npm/swiper@{{version}}/swiper-element-bundle.min.js"
map: "https://cdn.jsdelivr.net/npm/swiper@{{version}}/swiper-element-bundle.min.js.map"
version: "11.0.5"
swiper-map:
integrity:
js: "sha256-hlZaH8ySXX97bZaetnrtYlKuhx3oEXFz/s2IXchu6vk="
url:
js: "https://cdn.jsdelivr.net/npm/swiper@11.1.0/swiper-element-bundle.min.js.map"
version: "11.0.5"
vanilla-cookieconsent:
integrity:
css: "sha256-ygRrixsQlBByBZiOcJamh7JByO9fP+/l5UPtKNJmRsE="
js: "sha256-vG4vLmOB/AJbJ6awr7Wg4fxonG+fxAp4cIrbIFTvRXU="
url:
css: "https://cdn.jsdelivr.net/npm/vanilla-cookieconsent@{{version}}/dist/cookieconsent.css"
js: "https://cdn.jsdelivr.net/npm/vanilla-cookieconsent@{{version}}/dist/cookieconsent.umd.js"
version: "3.1.0"
vega:
integrity:
js: "sha256-Yot/cfgMMMpFwkp/5azR20Tfkt24PFqQ6IQS+80HIZs="
js_map: "sha256-z0x9ICA65dPkZ0JVa9wTImfF6n7AJsKc6WlFE96/wNA="
url:
js: "https://cdn.jsdelivr.net/npm/vega@{{version}}/build/vega.min.js"
js_map: "https://cdn.jsdelivr.net/npm/vega@{{version}}/build/vega.min.js.map"
version: "5.27.0"
vega-embed:
integrity:
js: "sha256-FPCJ9JYCC9AZSpvC/t/wHBX7ybueZhIqOMjpWqfl3DU="
js_map: "sha256-VBbfSEFYSMdX/rTdGrONEHNP6BprCB7H/LpMMNt/cPA="
url:
js: "https://cdn.jsdelivr.net/npm/vega-embed@{{version}}/build/vega-embed.min.js"
js_map: "https://cdn.jsdelivr.net/npm/vega-embed@{{version}}/build/vega-embed.min.js.map"
version: "6.24.0"
vega-lite:
integrity:
js: "sha256-TvBvIS5jUN4BSy009usRjNzjI1qRrHPYv7xVLJyjUyw="
js_map: "sha256-l2I4D5JC23Ulsu6e3sKVe5AJ+r+DFkzkKnZS8nUGz28="
url:
js: "https://cdn.jsdelivr.net/npm/vega-lite@{{version}}/build/vega-lite.min.js"
js_map: "https://cdn.jsdelivr.net/npm/vega-lite@{{version}}/build/vega-lite.min.js.map"
version: "5.16.3"
venobox:
integrity:
css: "sha256-ohJEB0/WsBOdBD+gQO/MGfyJSbTUI8OOLbQGdkxD6Cg="
js: "sha256-LsGXHsHMMmTcz3KqTaWvLv6ome+7pRiic2LPnzTfiSo="
url:
css: "https://cdn.jsdelivr.net/npm/venobox@{{version}}/dist/venobox.min.css"
js: "https://cdn.jsdelivr.net/npm/venobox@{{version}}/dist/venobox.min.js"
version: "2.1.8"
# -----------------------------------------------------------------------------
# Get external JSON data
# -----------------------------------------------------------------------------
jekyll_get_json:
- data: resume
json: assets/json/resume.json # it can also be an url
jsonresume:
- basics
- work
- education
- publications
- projects
- volunteer
- awards
- certificates
- skills
- languages
- interests
- references

4179
_data/citations.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,7 @@
github_users: github_users:
- fguiotte - fguiotte
repo_description_lines_max: 2
github_repos: github_repos:
- fguiotte/sap - fguiotte/sap

14
_data/socials.yml Normal file
View File

@ -0,0 +1,14 @@
# this file contains the social media links and usernames of the author
# the socials will be displayed in the order they are defined here
# for more information, please refer to the documentation of jekyll-socials plugin: https://github.com/george-gca/jekyll-socials
cv_pdf: /assets/pdf/example_pdf.pdf # path to your CV PDF file
email: you@example.com # your email address
inspirehep_id: 1010907 # Inspire HEP author ID
rss_icon: true # comment this line to hide the RSS icon
scholar_userid: qc6CJjYAAAAJ # your Google Scholar ID
# wechat_qr: # filename of your wechat qr-code saved as an image (e.g., wechat-qr.png if saved to assets/img/wechat-qr.png)
# whatsapp_number: # your WhatsApp number (full phone number in international format. Omit any zeroes, brackets, or dashes when adding the phone number in international format.)
custom_social: # can be any name here other than the ones already defined in the jekyll-socials plugin
logo: https://www.alberteinstein.com/wp-content/uploads/2024/03/cropped-favicon-192x192.png # can be png, svg, jpg
title: Custom Social
url: https://www.alberteinstein.com/

30
_includes/audio.liquid Normal file
View File

@ -0,0 +1,30 @@
<figure>
<audio
src="{% if include.cache_bust %}{{ include.path | relative_url | bust_file_cache }}{% else %}{{ include.path | relative_url }}{% endif %}"
{% if include.class %}
class="{{ include.class }}"
{% endif %}
{% if include.alt %}
alt="{{ include.alt }}"
{% endif %}
{% if include.title %}
title="{{ include.title }}"
{% endif %}
{% if include.autoplay %}
autoplay
{% endif %}
{% if include.controls %}
controls
{% endif %}
{% if include.loop %}
loop
{% endif %}
{% if include.muted %}
muted
{% endif %}
/>
{% if include.caption %}
<figcaption class="caption">{{ include.caption }}</figcaption>
{% endif %}
</figure>

View File

@ -0,0 +1,4 @@
{% if site.bib_search %}
<script src="{{ '/assets/js/bibsearch.js' | relative_url | bust_file_cache }}" type="module"></script>
<input type="text" id="bibsearch" spellcheck="false" autocomplete="off" class="search bibsearch-form-input" placeholder="Type to filter">
{% endif %}

25
_includes/calendar.liquid Normal file
View File

@ -0,0 +1,25 @@
{% if include.calendar_id %}
<div class="post mt-4">
<h2 class="mb-3"><i class="fas fa-calendar-alt"></i> Upcoming Events</h2>
<button
class="btn btn-sm btn-outline-primary mb-3"
onclick="toggleCalendar()"
id="calendar-toggle-btn"
>
Show Calendar
</button>
<div class="calendar-wrapper" id="calendar-container" style="display: none;">
<iframe
id="calendar-iframe"
data-calendar-id="{{ include.calendar_id }}"
data-timezone="{{ include.timezone | default: 'UTC' }}"
style="{{ include.style | default: 'border:0; width:100%; height:600px;' }}"
frameborder="0"
scrolling="no"
>
</iframe>
</div>
</div>
{% endif %}

26
_includes/citation.liquid Normal file
View File

@ -0,0 +1,26 @@
<br>
<hr>
<br>
If you found this useful, please cite this as:
{% capture citation_quote -%}
> {{ site.last_name }}, {{ site.first_name }}{% if site.middle_name %} {{ site.middle_name }}{% endif %} ({{ page.date | date: "%b %Y" }}). {{ page.title }}. {% if site.title != 'blank' %}{{ site.title }}. {% endif %}{{ site.url }}.
{%- endcapture %}
{{ citation_quote | markdownify }}
<p>or as a BibTeX entry:</p>
{% capture citation_code -%}
```bibtex
@article{ {{- site.last_name | downcase }}{{ page.date | date: "%Y" }}{{ page.title | slugify }},
title = { {{- page.title -}} },
author = { {{- site.last_name }}, {{ site.first_name }}{% if site.middle_name %} {{ site.middle_name }}{% endif -%}},
{%- if site.title != 'blank' %}journal = { {{- site.title -}} },{% endif %}
year = { {{- page.date | date: "%Y" -}} },
month = { {{- page.date | date: "%b" -}} },
url = { {{- site.url }}{{ page.url -}} }
}
```
{%- endcapture %}
{{ citation_code | markdownify }}

View File

@ -0,0 +1,71 @@
{% assign course = site.teachings | where: 'course_id', include.course_id | first %}
{% if course %}
<div class="course-schedule">
<h2>{{ course.title }}</h2>
{% if course.description %}
<div class="course-description">
{{ course.description | markdownify }}
</div>
{% endif %}
{% if course.instructor %}
<p><strong>Instructor:</strong> {{ course.instructor }}</p>
{% endif %}
{% if course.term %}
<p><strong>Term:</strong> {{ course.term }}</p>
{% endif %}
{% if course.schedule %}
<table class="table table-sm table-responsive">
<thead>
<tr>
<th>Week</th>
<th>Date</th>
<th>Topic</th>
<th>Materials</th>
</tr>
</thead>
<tbody>
{% for entry in course.schedule %}
<tr>
<td>{{ entry.week }}</td>
<td>{{ entry.date }}</td>
<td>
{% if entry.topic %}
<strong>{{ entry.topic }}</strong>
{% endif %}
{% if entry.description %}
<div class="schedule-description">{{ entry.description | markdownify }}</div>
{% endif %}
</td>
<td>
{% if entry.materials %}
<ul class="schedule-materials">
{% for material in entry.materials %}
<li>
{% if material.url %}
{% if material.url contains '://' %}
<a href="{{ material.url }}" target="_blank">{{ material.name }}</a>
{% else %}
<a href="{{ material.url | relative_url }}" target="_blank">{{ material.name }}</a>
{% endif %}
{% else %}
{{ material.name }}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No schedule available for this course.</p>
{% endif %}
</div>
{% endif %}

37
_includes/courses.liquid Normal file
View File

@ -0,0 +1,37 @@
{% if site.teachings %}
<div class="courses">
{% assign courses_by_year = site.teachings | sort: 'year' | reverse | group_by: 'year' %}
{% for year_group in courses_by_year %}
<h2 class="year">{{ year_group.name }}</h2>
<div class="course-list">
{% assign year_courses = year_group.items | sort: 'term' %}
{% for course in year_courses %}
<div class="course-item">
<h3 class="course-title">
<a href="{{ course.url | relative_url }}">{{ course.title }}</a>
</h3>
<div class="course-meta">
{% if course.term %}
<span class="course-term">{{ course.term }}</span>
{% endif %}
{% if course.instructor %}
<span class="course-instructor">{{ course.instructor }}</span>
{% endif %}
</div>
{% if course.description %}
<div class="course-description">
{{ course.description | markdownify }}
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
{% else %}
<p>No courses available yet.</p>
{% endif %}

View File

@ -0,0 +1,66 @@
{% comment %}
Unified awards entry renderer for both formats
{% endcomment %}
<ul class="card-text font-weight-light list-group list-group-flush">
{% for entry in entries %}
<li class="list-group-item">
<div class="row">
{% capture start_date %}
{% if entry.date %}{{ entry.date }}{% endif %}
{% endcapture %}
{% if start_date != '' %}
<div class="col-xs-2 col-sm-2 col-md-2 text-center">
<table class="table-cv">
<tbody>
<tr>
<td>
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px">
{{- start_date | split: '-' | slice: 0, 1 | join: '' -}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-xs-10 col-sm-10 col-md-10 mt-2 mt-md-0">
{% if entry.url %}
<h6 class="title font-weight-bold ml-1 ml-md-4">
<a href="{{ entry.url }}">{{ entry.title }}</a>
</h6>
{% elsif entry.title %}
<h6 class="title font-weight-bold ml-1 ml-md-4">{{ entry.title }}</h6>
{% endif %}
{% if entry.awarder %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">{{ entry.awarder }}</h6>
{% endif %}
{% if entry.summary %}
<p class="ml-1 ml-md-4">{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
{% endif %}
</div>
{% else %}
<div class="col-xs-12 col-sm-12 col-md-12">
{% if entry.url %}
<h6 class="title font-weight-bold ml-1 ml-md-4">
<a href="{{ entry.url }}">{{ entry.title }}</a>
</h6>
{% elsif entry.title %}
<h6 class="title font-weight-bold ml-1 ml-md-4">{{ entry.title }}</h6>
{% endif %}
{% if entry.awarder %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">{{ entry.awarder }}</h6>
{% endif %}
{% if entry.summary %}
<p class="ml-1 ml-md-4">{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
{% endif %}
</div>
{% endif %}
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,28 @@
{% comment %}
Unified certificates entry renderer for both formats
{% endcomment %}
<ul class="card-text font-weight-light list-group list-group-flush">
{% for entry in entries %}
<li class="list-group-item">
{% if entry.icon %}
<i class="{{ entry.icon }}"></i>
{% endif %}
{% if entry.url %}
<strong
><a href="{{ entry.url }}" target="_blank">{{ entry.name }}</a></strong
>
{% else %}
<strong>{{ entry.name }}</strong>
{% endif %}
{% if entry.issuer %}
- <em>{{ entry.issuer }}</em>
{% endif %}
{% if entry.date %}
({{ entry.date | split: '-' | slice: 0, 1 | join: '' }})
{% endif %}
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,93 @@
{% comment %}
Unified education entry renderer for both RenderCV and JSONResume formats
Handles both:
- RenderCV: institution, area, studyType (or degree), start_date, end_date, location, courses, highlights
- JSONResume: institution, area, studyType, startDate, endDate, location, courses, highlights
{% endcomment %}
<ul class="card-text font-weight-light list-group list-group-flush">
{% for entry in entries %}
<li class="list-group-item">
<div class="row">
<div class="col-xs-2 col-sm-2 col-md-2 text-center date-column">
{% capture start_date %}
{% if entry.start_date %}{{ entry.start_date }}{% elsif entry.startDate %}{{ entry.startDate }}{% endif %}
{% endcapture %}
{% capture end_date %}
{% if entry.end_date %}{{ entry.end_date }}{% elsif entry.endDate %}{{ entry.endDate }}{% endif %}
{% endcapture %}
{% if start_date != '' %}
{% comment %} Extract year only from dates like "1933-01-01" or just use "1933" as is {% endcomment %}
{% assign startDate = start_date | split: '-' | first %}
{% assign endDate = end_date | split: '-' | first | default: 'Present' %}
{% assign date = startDate | append: ' - ' | append: endDate %}
{% else %}
{% assign date = null %}
{% endif %}
<table class="table-cv">
<tbody>
<tr>
<td>
{% if date %}
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px">{{ date }}</span>
{% endif %}
</td>
</tr>
{% capture location %}
{% if entry.location %}{{ entry.location }}{% endif %}
{% endcapture %}
{% if location != '' %}
<tr>
<td>
<p class="location">
<i class="fa-solid fa-location-dot iconlocation"></i>
{{ location }}
</p>
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
<div class="col-xs-10 col-sm-10 col-md-10 mt-2 mt-md-0">
{% capture study_type %}
{% if entry.studyType %}{{ entry.studyType }}{% elsif entry.degree %}{{ entry.degree }}{% endif %}
{% endcapture %}
{% if entry.url %}
<h6 class="title font-weight-bold ml-1 ml-md-4">
<a href="{{ entry.url }}">{{ study_type }}</a>
</h6>
{% elsif study_type != '' %}
<h6 class="title font-weight-bold ml-1 ml-md-4">{{ study_type }}</h6>
{% endif %}
{% if entry.institution %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">{{ entry.institution }}</h6>
{% endif %}
{% if entry.area %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic">{{ entry.area }}</h6>
{% endif %}
{% if entry.courses or entry.highlights %}
<ul class="items">
{% for item in entry.courses %}
<li>
<span class="item">{{ item }}</span>
</li>
{% endfor %}
{% for item in entry.highlights %}
<li>
<span class="item">{{ item | markdownify | remove: '<p>' | remove: '</p>' }}</span>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,91 @@
{% comment %}
Unified work/experience entry renderer for both RenderCV and JSONResume formats
Handles both:
- RenderCV: company, position, start_date, end_date, location, url, summary, highlights
- JSONResume: name, position, startDate, endDate, location, url, summary, highlights
{% endcomment %}
<ul class="card-text font-weight-light list-group list-group-flush">
{% for entry in entries %}
<li class="list-group-item">
<div class="row">
<div class="col-xs-2 col-sm-2 col-md-2 text-center date-column">
{% capture start_date %}
{% if entry.start_date %}{{ entry.start_date }}{% elsif entry.startDate %}{{ entry.startDate }}{% endif %}
{% endcapture %}
{% capture end_date %}
{% if entry.end_date %}{{ entry.end_date }}{% elsif entry.endDate %}{{ entry.endDate }}{% endif %}
{% endcapture %}
{% if start_date != '' %}
{% comment %} Extract year only from dates like "1933-01-01" or just use "1933" as is {% endcomment %}
{% assign startDate = start_date | split: '-' | first %}
{% assign endDate = end_date | split: '-' | first | default: 'Present' %}
{% assign date = startDate | append: ' - ' | append: endDate %}
{% else %}
{% assign date = '' %}
{% endif %}
<table class="table-cv">
<tbody>
<tr>
<td>
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px">{{ date }}</span>
</td>
</tr>
{% capture location %}
{% if entry.location %}{{ entry.location }}{% endif %}
{% endcapture %}
{% if location != '' %}
<tr>
<td>
<p class="location">
<i class="fa-solid fa-location-dot iconlocation"></i>
{{ location }}
</p>
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
<div class="col-xs-10 col-sm-10 col-md-10 mt-2 mt-md-0">
{% capture position_title %}
{% if entry.position %}{{ entry.position }}{% endif %}
{% endcapture %}
{% if entry.url %}
<h6 class="title font-weight-bold ml-1 ml-md-4">
<a href="{{ entry.url }}">{{ position_title }}</a>
</h6>
{% elsif position_title != '' %}
<h6 class="title font-weight-bold ml-1 ml-md-4">{{ position_title }}</h6>
{% endif %}
{% capture company_name %}
{% if entry.name %}{{ entry.name }}{% elsif entry.company %}{{ entry.company }}{% elsif entry.organization %}{{ entry.organization }}{% endif %}
{% endcapture %}
{% if company_name != '' %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">{{ company_name }}</h6>
{% endif %}
{% if entry.summary %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem; font-style: italic">
{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}
</h6>
{% endif %}
{% if entry.highlights %}
<ul class="items">
{% for item in entry.highlights %}
<li>
<span class="item">{{ item | markdownify | remove: '<p>' | remove: '</p>' }}</span>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,29 @@
{% comment %}
Unified interests entry renderer for both formats
{% endcomment %}
<div class="card-text font-weight-light">
{% for entry in entries %}
<div class="interest-item">
{% if entry.icon %}
<i class="{{ entry.icon }}"></i>
{% endif %}
<strong>{{ entry.name }}:</strong>
{% if entry.keywords %}
{% for keyword in entry.keywords %}
{% if forloop.last %}
{{ keyword }}
{% else %}
{{ keyword }},
{% endif %}
{% endfor %}
{% endif %}
</div>
{% endfor %}
</div>
<style>
.interest-item {
padding: 0.5rem 0;
}
</style>

View File

@ -0,0 +1,28 @@
{% comment %}
Unified languages entry renderer for both formats
- RenderCV uses: name, summary
- JSONResume uses: language, fluency
{% endcomment %}
<div class="card-text font-weight-light">
{% for entry in entries %}
<div class="language-item">
{% if entry.icon %}
<i class="{{ entry.icon }}"></i>
{% endif %}
{% capture lang_name %}
{% if entry.name %}{{ entry.name }}{% elsif entry.language %}{{ entry.language }}{% endif %}
{% endcapture %}
{% capture fluency %}
{% if entry.summary %}{{ entry.summary }}{% elsif entry.fluency %}{{ entry.fluency }}{% endif %}
{% endcapture %}
<strong>{{ lang_name }}:</strong> {{ fluency }}
</div>
{% endfor %}
</div>
<style>
.language-item {
padding: 0.5rem 0;
}
</style>

View File

@ -1,5 +0,0 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% for content in entry.contents %}
<li class="list-group-item">{{ content }}</li>
{% endfor %}
</ul>

View File

@ -1,8 +0,0 @@
<table class="table table-sm table-borderless table-responsive">
{% for content in entry.contents %}
<tr>
<td class="p-1 pr-2 font-weight-bold"><b>{{ content.name }}</b></td>
<td class="p-1 pl-2 font-weight-light text">{{ content.value }}</td>
</tr>
{% endfor %}
</table>

View File

@ -1,14 +0,0 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% for content in entry.contents %}
<li class="list-group-item">
<h5 class="font-italic">{{ content.title }}</h5>
{% if content.items %}
<ul class="subitems">
{% for subitem in content.items %}
<li><span class="subitem">{{ subitem }}</span></li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,31 @@
{% comment %}
Unified projects entry renderer for both formats
{% endcomment %}
<ul class="card-text font-weight-light list-group list-group-flush">
{% for entry in entries %}
<li class="list-group-item">
{% if entry.url %}
<h6 class="title font-weight-bold">
<a href="{{ entry.url }}" target="_blank">{{ entry.name }}</a>
</h6>
{% else %}
<h6 class="title font-weight-bold">{{ entry.name }}</h6>
{% endif %}
{% if entry.summary %}
<p>{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
{% endif %}
{% if entry.highlights %}
<ul class="items">
{% for item in entry.highlights %}
<li>
<span class="item">{{ item | markdownify | remove: '<p>' | remove: '</p>' }}</span>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,70 @@
{% comment %}
Unified publications entry renderer for both formats
{% endcomment %}
<ul class="card-text font-weight-light list-group list-group-flush">
{% for entry in entries %}
<li class="list-group-item">
<div class="row">
{% capture pub_date %}
{% if entry.releaseDate %}{{ entry.releaseDate }}{% elsif entry.date %}{{ entry.date }}{% endif %}
{% endcapture %}
{% if pub_date != '' %}
<div class="col-xs-2 col-sm-2 col-md-2 text-center">
<table class="table-cv">
<tbody>
<tr>
<td>
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px">
{{- pub_date | split: '-' | slice: 0, 1 | join: '' -}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-xs-10 col-sm-10 col-md-10 mt-2 mt-md-0">
{% if entry.url %}
<h6 class="title font-weight-bold ml-1 ml-md-4">
<a href="{{ entry.url }}">{{ entry.title | default: entry.name }}</a>
</h6>
{% elsif entry.title %}
<h6 class="title font-weight-bold ml-1 ml-md-4">{{ entry.title }}</h6>
{% endif %}
{% if entry.publisher %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">
<em>{{ entry.publisher }}</em>
</h6>
{% endif %}
{% if entry.summary %}
<p class="ml-1 ml-md-4">{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
{% endif %}
</div>
{% else %}
<div class="col-xs-12 col-sm-12 col-md-12">
{% if entry.url %}
<h6 class="title font-weight-bold ml-1 ml-md-4">
<a href="{{ entry.url }}">{{ entry.title | default: entry.name }}</a>
</h6>
{% elsif entry.title %}
<h6 class="title font-weight-bold ml-1 ml-md-4">{{ entry.title }}</h6>
{% endif %}
{% if entry.publisher %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem">
<em>{{ entry.publisher }}</em>
</h6>
{% endif %}
{% if entry.summary %}
<p class="ml-1 ml-md-4">{{ entry.summary | markdownify | remove: '<p>' | remove: '</p>' }}</p>
{% endif %}
</div>
{% endif %}
</div>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,15 @@
{% comment %}
Unified references entry renderer for both formats
{% endcomment %}
<ul class="card-text font-weight-light list-group list-group-flush">
{% for entry in entries %}
<li class="list-group-item">
{% if entry.icon %}
<i class="{{ entry.icon }}"></i>
{% endif %}
<strong>{{ entry.name }}</strong>
<p>{{ entry.reference | markdownify | remove: '<p>' | remove: '</p>' }}</p>
</li>
{% endfor %}
</ul>

View File

@ -0,0 +1,32 @@
{% comment %}
Unified skills entry renderer for both formats
{% endcomment %}
<div class="card-text font-weight-light">
{% for entry in entries %}
<div class="skill-item">
{% if entry.icon %}
<i class="{{ entry.icon }}"></i>
{% endif %}
<strong>
{{- entry.name -}}
{%- if entry.level %} ({{ entry.level }}){% endif %}:</strong
>
{% if entry.keywords %}
{% for keyword in entry.keywords %}
{% if forloop.last %}
{{ keyword }}
{% else %}
{{ keyword }},
{% endif %}
{% endfor %}
{% endif %}
</div>
{% endfor %}
</div>
<style>
.skill-item {
padding: 0.5rem 0;
}
</style>

View File

@ -1,59 +0,0 @@
<ul class="card-text font-weight-light list-group list-group-flush">
{% for content in entry.contents %}
<li class="list-group-item">
<div class="row">
{% if content.year %}
<div class="col-xs-2 cl-sm-2 col-md-2 text-center" style="width: 75px;">
<span class="badge font-weight-bold danger-color-dark text-uppercase align-middle" style="min-width: 75px;">
{{ content.year }}
</span>
</div>
{% endif %}
<div class="col-xs-10 cl-sm-10 col-md-10 mt-2 mt-md-0">
{% if content.title %}
<h6 class="title font-weight-bold ml-1 ml-md-4">{{content.title}}</h6>
{% endif %}
{% if content.institution %}
<h6 class="ml-1 ml-md-4" style="font-size: 0.95rem;">{{content.institution}}</h6>
{% endif %}
{% if content.description %}
<ul class="items">
{% for item in content.description %}
<li>
{% if item.contents %}
<span class="item-title">{{ item.title }}</span>
<ul class="subitems">
{% for subitem in item.contents %}
<li><span class="subitem">{{ subitem }}</span></li>
{% endfor %}
</ul>
{% else %}
<span class="item">{{ item }}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% if content.items %}
<ul class="items">
{% for item in content.items %}
<li>
{% if item.contents %}
<span class="item-title">{{ item.title }}</span>
<ul class="subitems">
{% for subitem in item.contents %}
<li><span class="subitem">{{ subitem }}</span></li>
{% endfor %}
</ul>
{% else %}
<span class="item">{{ item }}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
</li>
{% endfor %}
</ul>

View File

@ -1,13 +0,0 @@
<div id="disqus_thread" style="max-width: {{ site.max_width }}; margin: 0 auto;">
<script type="text/javascript">
var disqus_shortname = '{{ site.disqus_shortname }}';
var disqus_identifier = '{{ page.id }}';
var disqus_title = {{ page.title | jsonify }};
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>

13
_includes/disqus.liquid Normal file
View File

@ -0,0 +1,13 @@
<div id="disqus_thread" style="max-width: {{ site.max_width }}; margin: 0 auto;">
<script type="text/javascript">
var disqus_shortname = '{{ site.disqus_shortname }}';
var disqus_identifier = '{{ page.id }}';
var disqus_title = {{ page.title | jsonify }};
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>

View File

@ -0,0 +1,340 @@
<!-- jQuery -->
<script
src="{{ site.third_party_libraries.jquery.url.js }}"
integrity="{{ site.third_party_libraries.jquery.integrity.js }}"
crossorigin="anonymous"
></script>
<!-- Bootsrap & MDB scripts -->
<script src="{{ '/assets/js/bootstrap.bundle.min.js' | relative_url }}"></script>
<script
src="{{ site.third_party_libraries.mdb.url.js }}"
integrity="{{ site.third_party_libraries.mdb.integrity.js }}"
crossorigin="anonymous"
></script>
<!-- Custom overrides -->
<script src="{{ '/assets/js/distillpub/overrides.js' | relative_url }}"></script>
{% if page.mermaid and page.mermaid.enabled %}
<!-- Mermaid and D3 -->
<script
defer
src="{{ site.third_party_libraries.mermaid.url.js }}"
integrity="{{ site.third_party_libraries.mermaid.integrity.js }}"
crossorigin="anonymous"
></script>
{% if page.mermaid.zoomable %}
<script
defer
src="{{ site.third_party_libraries.d3.url.js }}"
integrity="{{ site.third_party_libraries.d3.integrity.js }}"
crossorigin="anonymous"
></script>
{% endif %}
<script defer src="{{ '/assets/js/mermaid-setup.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.code_diff %}
<!-- Diff2HTML -->
<!-- diff2html doesn't go well with Bootstrap Table -->
<script
src="{{ site.third_party_libraries.diff2html.url.js }}"
integrity="{{ site.third_party_libraries.diff2html.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/diff2html-setup.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.map %}
<!-- Leaflet -->
<script
src="{{ site.third_party_libraries.leaflet.url.js }}"
integrity="{{ site.third_party_libraries.leaflet.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/leaflet-setup.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.chart and page.chart.chartjs %}
<!-- Chart.js -->
<script
defer
src="{{ site.third_party_libraries.chartjs.url.js }}"
integrity="{{ site.third_party_libraries.chartjs.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/chartjs-setup.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.chart and page.chart.echarts %}
<!-- ECharts -->
<script
src="{{ site.third_party_libraries.echarts.url.js.library }}"
integrity="{{ site.third_party_libraries.echarts.integrity.js.library }}"
crossorigin="anonymous"
></script>
{% if site.enable_darkmode %}
<script
src="{{ site.third_party_libraries.echarts.url.js.dark_theme }}"
integrity="{{ site.third_party_libraries.echarts.integrity.js.dark_theme }}"
crossorigin="anonymous"
></script>
{% endif %}
<script defer src="{{ '/assets/js/echarts-setup.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.chart and page.chart.plotly %}
<!-- Plotly -->
<script
defer
src="{{ site.third_party_libraries.plotly.url.js }}"
integrity="{{ site.third_party_libraries.plotly.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/plotly-setup.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.chart and page.chart.vega_lite %}
<!-- Vega -->
<script
defer
src="{{ site.third_party_libraries.vega.url.js }}"
integrity="{{ site.third_party_libraries.vega.integrity.js }}"
crossorigin="anonymous"
></script>
<script
defer
src="{{ site.third_party_libraries.vega-lite.url.js }}"
integrity="{{ site.third_party_libraries.vega-lite.integrity.js }}"
crossorigin="anonymous"
></script>
<script
defer
src="{{ site.third_party_libraries.vega-embed.url.js }}"
integrity="{{ site.third_party_libraries.vega-embed.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/vega-setup.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.tikzjax %}
<!-- Tikzjax -->
<script defer src="{{ '/assets/js/tikzjax.min.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.typograms %}
<!-- Typograms -->
<script src="{{ '/assets/js/typograms.js' | relative_url | bust_file_cache }}"></script>
{% endif %}
{% if site.enable_tooltips %}
<!-- Tooltips -->
<script src="{{ '/assets/js/tooltips-setup.js' | relative_url | bust_file_cache }}"></script>
{% endif %}
{% if site.enable_medium_zoom %}
<!-- Medium Zoom JS -->
<script
defer
src="{{ site.third_party_libraries.medium_zoom.url.js }}"
integrity="{{ site.third_party_libraries.medium_zoom.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/zoom.js' | relative_url | bust_file_cache }}"></script>
{% endif %}
{% if page.toc and page.toc.sidebar %}
<!-- Sidebar Table of Contents -->
<script defer src="{{ '/assets/js/bootstrap-toc.min.js' | relative_url | bust_file_cache }}"></script>
{% endif %}
{% if page.pretty_table %}
<!-- Bootstrap Table -->
<!-- Bootstrap Table doesn't go well with diff2html -->
<script
defer
src="{{ site.third_party_libraries.bootstrap-table.url.js }}"
integrity="{{ site.third_party_libraries.bootstrap-table.integrity.js }}"
crossorigin="anonymous"
></script>
{% endif %}
<!-- Load Common JS -->
<script src="{{ '/assets/js/no_defer.js' | relative_url | bust_file_cache }}"></script>
<script defer src="{{ '/assets/js/common.js' | relative_url | bust_file_cache }}"></script>
<script defer src="{{ '/assets/js/copy_code.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
<!-- Jupyter Open External Links New Tab -->
<script defer src="{{ '/assets/js/jupyter_new_tab.js' | relative_url | bust_file_cache }}"></script>
<!-- Removed Badges -->
{% if site.enable_math %}
<!-- MathJax -->
<script
defer
type="text/javascript"
id="MathJax-script"
src="{{ site.third_party_libraries.mathjax.url.js }}"
integrity="{{ site.third_party_libraries.mathjax.integrity.js }}"
crossorigin="anonymous"
></script>
<script src="{{ '/assets/js/mathjax-setup.js' | relative_url | bust_file_cache }}"></script>
<script
defer
src="{{ site.third_party_libraries.polyfill.url.js }}"
crossorigin="anonymous"
></script>
<!-- Removed Pseudocode -->
{% endif %}
{% if site.enable_cookie_consent %}
<!-- Cookie Consent -->
<script
defer
src="{{ site.third_party_libraries.vanilla-cookieconsent.url.js }}"
integrity="{{ site.third_party_libraries.vanilla-cookieconsent.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/cookie-consent-setup.js' | relative_url }}"></script>
{% endif %}
{% if site.enable_google_analytics %}
<!-- Analytics -->
<!-- Global site tag (gtag.js) - Google Analytics -->
<script
{% if site.enable_cookie_consent %}
type="text/plain" data-category="analytics"
{% endif %}
async
src="https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics }}"
></script>
<script
{% if site.enable_cookie_consent %}
type="text/plain" data-category="analytics"
{% endif %}
defer
src="{{ '/assets/js/google-analytics-setup.js' | relative_url }}"
></script>
{% endif %}
{% if site.enable_cronitor_analytics %}
<!-- Cronitor RUM -->
<script
{% if site.enable_cookie_consent %}
type="text/plain" data-category="analytics"
{% endif %}
async
src="https://rum.cronitor.io/script.js"
></script>
<script
{% if site.enable_cookie_consent %}
type="text/plain" data-category="analytics"
{% endif %}
defer
src="{{ '/assets/js/cronitor-analytics-setup.js' | relative_url }}"
></script>
{% endif %}
{% if site.enable_pirsch_analytics %}
<script
{% if site.enable_cookie_consent %}
type="text/plain" data-category="analytics"
{% endif %}
defer
src="https://api.pirsch.io/pa.js"
id="pianjs"
data-code="{{ site.pirsch_analytics }}"
></script>
{% endif %}
{% if site.enable_openpanel_analytics %}
<script
{% if site.enable_cookie_consent %}
type="text/plain" data-category="analytics"
{% endif %}
defer
src="{{ '/assets/js/open-panel-analytics-setup.js' | relative_url }}"
></script>
<script
{% if site.enable_cookie_consent %}
type="text/plain" data-category="analytics"
{% endif %}
async
defer
src="https://openpanel.dev/op1.js"
></script>
{% endif %}
{% if site.enable_progressbar %}
<!-- Scrolling Progress Bar -->
<script defer src="{{ '/assets/js/progress-bar.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% if page.images %}
<!-- Image Layouts -->
{% if page.images.compare %}
<script
defer
src="{{ site.third_party_libraries.img-comparison-slider.url.js }}"
integrity="{{ site.third_party_libraries.img-comparison-slider.integrity.js }}"
crossorigin="anonymous"
></script>
{% endif %}
{% if page.images.lightbox2 %}
<script
defer
src="{{ site.third_party_libraries.lightbox2.url.js }}"
integrity="{{ site.third_party_libraries.lightbox2.integrity.js }}"
crossorigin="anonymous"
></script>
{% endif %}
{% if page.images.photoswipe %}
<script defer src="{{ '/assets/js/photoswipe-setup.js' | relative_url }}" type="module"></script>
{% endif %}
{% if page.images.slider %}
<script
defer
src="{{ site.third_party_libraries.swiper.url.js }}"
integrity="{{ site.third_party_libraries.swiper.integrity.js }}"
crossorigin="anonymous"
></script>
{% endif %}
{% if page.images.spotlight %}
<script
defer
src="{{ site.third_party_libraries.spotlight.url.js }}"
crossorigin="anonymous"
></script>
{% endif %}
{% if page.images.venobox %}
<script
defer
src="{{ site.third_party_libraries.venobox.url.js }}"
integrity="{{ site.third_party_libraries.venobox.integrity.js }}"
crossorigin="anonymous"
></script>
<script defer src="{{ '/assets/js/venobox-setup.js' | relative_url | bust_file_cache }}" type="text/javascript"></script>
{% endif %}
{% endif %}
{% if page.tabs %}
<!-- Jekyll Tabs -->
<script src="{{ '/assets/js/tabs.min.js' | relative_url | bust_file_cache }}"></script>
{% endif %}
{% if site.back_to_top %}
<!-- Back to Top -->
<script src="{{ '/assets/js/vanilla-back-to-top.min.js' | relative_url | bust_file_cache }}"></script>
<script>
addBackToTop();
</script>
{% endif %}
{% if site.search_enabled %}
<!-- Search -->
<script type="module" src="{{ '/assets/js/search/ninja-keys.min.js' | relative_url | bust_file_cache }}"></script>
<ninja-keys hideBreadcrumbs noAutoLoadMdIcons placeholder="Type to start searching"></ninja-keys>
<script src="{{ '/assets/js/search-setup.js' | relative_url | bust_file_cache }}"></script>
<script src="{{ '/assets/js/search-data.js' | relative_url }}"></script>
<script src="{{ '/assets/js/shortcut-key.js' | relative_url | bust_file_cache }}"></script>
{% endif %}

View File

@ -1,36 +0,0 @@
{%- assign img_path = include.path | remove: ".jpg" | remove: ".jpeg" | remove: ".png" | remove: ".tiff" -%}
<figure>
<picture>
{% if site.imagemagick.enabled %}
{% for i in site.imagemagick.widths -%}
<source
class="responsive-img-srcset"
media="(max-width: {{ i }}px)"
srcset="{{ img_path | relative_url }}-{{ i }}.webp"
/>
{% endfor -%}
{% endif %}
<!-- Fallback to the original file -->
<img
src="{{ include.path | relative_url }}"
{% if include.class %}class="{{ include.class }}"{% endif %}
{% if include.width %}width="{{ include.width }}"{% else %}width="auto"{% endif %}
{% if include.height %}height="{{ include.height }}"{% else %}height="auto"{% endif %}
{% if include.min-width %}min-width="{{ include.min-width }}"{% endif %}
{% if include.min-height %}min-height="{{ include.min-height }}"{% endif %}
{% if include.max-width %}max-width="{{ include.max-width }}"{% endif %}
{% if include.max-height %}height="{{ include.max-height }}"{% endif %}
{% if include.alt %}alt="{{ include.alt }}"{% endif %}
{% if include.title %}title="{{ include.title }}"{% endif %}
{% if include.zoomable %}data-zoomable{% endif %}
onerror="this.onerror=null; $('.responsive-img-srcset').remove();"
/>
</picture>
{%- if include.caption -%}<figcaption class="caption">{{ include.caption }}</figcaption>{%- endif %}
</figure>

86
_includes/figure.liquid Normal file
View File

@ -0,0 +1,86 @@
{% assign img_path = include.path | remove: '.jpg' | remove: '.jpeg' | remove: '.png' | remove: '.tiff' | remove: '.gif' %}
{% assign parts = include.path | split: '.' %}
{% assign ext = parts.last %}
<figure
{% if include.slot %}
slot="{{ include.slot }}"
{% endif %}
>
<picture>
<!-- Auto scaling with imagemagick -->
<!--
See https://www.debugbear.com/blog/responsive-images#w-descriptors-and-the-sizes-attribute and
https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images for info on defining 'sizes' for responsive images
-->
{% if site.imagemagick.enabled %}
{% unless include.avoid_scaling %}
<source
class="responsive-img-srcset"
{% if ext == 'gif' or ext == 'jpeg' or ext == 'jpg' or ext == 'png' or ext == 'tiff' %}
srcset="{% for i in site.imagemagick.widths %}{{ img_path | relative_url }}-{{ i }}.webp {{ i }}w,{% endfor %}"
type="image/webp"
{% else %}
srcset="{{ include.path | relative_url }}"
{% endif %}
{% if include.sizes %}
sizes="{{ include.sizes }}"
{% else %}
sizes="95vw"
{% endif %}
>
{% endunless %}
{% endif %}
<img
src="{% if include.url %}{{ include.url }}{% elsif include.cache_bust %}{{ include.path | relative_url | bust_file_cache }}{% else %}{{ include.path | relative_url }}{% endif %}"
{% if include.class %}
class="{{ include.class }}"
{% endif %}
{% if include.width %}
width="{{ include.width }}"
{% else %}
width="100%"
{% endif %}
{% if include.height %}
height="{{ include.height }}"
{% else %}
height="auto"
{% endif %}
{% if include['min-width'] or include['min-height'] or include['max-width'] or include['max-height'] %}
style="
{% if include['min-width'] %}
min-width: {{ include.min-width }};
{% endif %}
{% if include['min-height'] %}
min-height: {{ include.min-height }};
{% endif %}
{% if include['max-width'] %}
max-width: {{ include.max-width }};
{% endif %}
{% if include['max-height'] %}
max-height: {{ include.max-height }};
{% endif %}
"
{% endif %}
{% if include.alt %}
alt="{{ include.alt }}"
{% endif %}
{% if include.title %}
title="{{ include.title }}"
{% endif %}
{% if include.zoomable %}
data-zoomable
{% endif %}
{% if include.loading %}
loading="{{ include.loading }}"
{% elsif site.lazy_loading_images %}
loading="lazy"
{% endif %}
onerror="this.onerror=null; $('.responsive-img-srcset').remove();"
>
</picture>
{% if include.caption %}
<figcaption class="caption">{{ include.caption }}</figcaption>
{% endif %}
</figure>

View File

@ -1,25 +0,0 @@
{% if site.footer_fixed %}
<footer class="fixed-bottom">
<div class="container mt-0">
&copy; Copyright {{ site.time | date: '%Y' }} {{ site.first_name }} {{ site.middle_name }} {{ site.last_name }}. {{ site.footer_text }}
{%- if site.impressum_path -%}
<a href="{{ site.url }}{{ site.baseurl }}{{ site.impressum_path }}">Impressum</a>.
{%- endif -%}
{%- if site.last_updated -%}
Last updated: {{ "now" | date: '%B %d, %Y' }}.
{%- endif %}
</div>
</footer>
{%- else -%}
<footer class="sticky-bottom mt-5">
<div class="container">
&copy; Copyright {{ site.time | date: '%Y' }} {{ site.first_name }} {{ site.middle_name }} {{ site.last_name }}. {{ site.footer_text }}
{%- if site.impressum_path -%}
<a href="{{ site.url }}{{ site.baseurl }}{{ site.impressum_path }}">Impressum</a>.
{%- endif -%}
{%- if site.last_updated -%}
Last updated: {{ "now" | date: '%B %d, %Y' }}.
{%- endif %}
</div>
</footer>
{%- endif %}

30
_includes/footer.liquid Normal file
View File

@ -0,0 +1,30 @@
{% capture footer_contents %}
&copy; Copyright {{ site.time | date: '%Y' }}
{{ site.first_name }}
{{ site.middle_name }}
{{ site.last_name }}. {{ site.footer_text }}
{% if site.impressum_path %}
<a href="{{ site.url }}{{ site.baseurl }}{{ site.impressum_path }}">Impressum</a>.
{% endif %}
{% if site.last_updated %}
Last updated: {{ 'now' | date: '%B %d, %Y' }}.
{% endif %}
{% endcapture %}
{% if site.footer_fixed %}
<footer class="fixed-bottom" role="contentinfo">
<div class="container mt-0">
{{ footer_contents }}
</div>
</footer>
{% else %}
<footer class="sticky-bottom mt-5" role="contentinfo">
{% if site.newsletter.enabled %}
{% include newsletter.liquid %}
{% endif %}
<div class="container">
{{ footer_contents }}
</div>
</footer>
{% endif %}

View File

@ -1,27 +0,0 @@
<div id="giscus_thread" style="max-width: {{ site.max_width }}; margin: 0 auto;">
<script>
let giscusTheme = localStorage.getItem("theme");
let giscusAttributes = {
"src": "https://giscus.app/client.js",
"data-repo": "{{ site.giscus.repo }}",
"data-repo-id": "{{ site.giscus.repo_id }}",
"data-category": "{{ site.giscus.category }}",
"data-category-id": "{{ site.giscus.category_id }}",
"data-mapping": "{{ site.giscus.mapping }}",
"data-strict": "{{ site.giscus.strict }}",
"data-reactions-enabled": "{{ site.giscus.reactions_enabled }}",
"data-emit-metadata": "{{ site.giscus.emit_metadata }}",
"data-input-position": "{{ site.giscus.input_position }}",
"data-theme": giscusTheme,
"data-lang": "{{ site.giscus.lang }}",
"crossorigin": "anonymous",
"async": "",
};
let giscusScript = document.createElement("script");
Object.entries(giscusAttributes).forEach(([key, value]) => giscusScript.setAttribute(key, value));
document.getElementById("giscus_thread").appendChild(giscusScript);
</script>
<noscript>Please enable JavaScript to view the <a href="http://giscus.app/?ref_noscript">comments powered by giscus.</a></noscript>
</div>

25
_includes/giscus.liquid Normal file
View File

@ -0,0 +1,25 @@
<div
id="giscus_thread"
{% if page.layout == 'post' %}
style="max-width: {{ site.max_width }}; margin: 0 auto;"
{% endif %}
>
{% if page.layout == 'post' %}
<br>
{% endif %}
{% if site.giscus.repo %}
<script defer src="{{ '/assets/js/giscus-setup.js' | relative_url }}"></script>
<noscript>
Please enable JavaScript to view the
<a href="http://giscus.app/?ref_noscript">comments powered by giscus.</a>
</noscript>
{% else %}
{% capture giscus_warning %}
> ##### giscus comments misconfigured
> Please follow instructions at [http://giscus.app](http://giscus.app) and update your giscus configuration.
{: .block-danger }
{% endcapture %}
{{ giscus_warning | markdownify }}
{% endif %}
</div>

View File

@ -1,32 +0,0 @@
<!-- Metadata, OpenGraph and Schema.org -->
{% include metadata.html %}
<!-- Bootstrap & MDB -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@{{ site.bootstrap.version }}/dist/css/bootstrap.min.css" rel="stylesheet" integrity="{{ site.bootstrap.integrity.css }}" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mdbootstrap@{{ site.mdb.version }}/css/mdb.min.css" integrity="{{ site.mdb.integrity.css }}" crossorigin="anonymous" />
<!-- Fonts & Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@{{ site.fontawesome.version }}/css/all.min.css" integrity="{{ site.fontawesome.integrity }}" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/academicons@{{ site.academicons.version }}/css/academicons.min.css" integrity="{{ site.academicons.integrity }}" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Roboto+Slab:100,300,400,500,700|Material+Icons">
<!-- Code Syntax Highlighting -->
<!---<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jwarby/jekyll-pygments-themes@master/{{ site.highlight_theme_light | append: '.css' }}" media="" id="highlight_theme_light" /> -->
<link rel="stylesheet" href="/assets/stylesheets/{{ site.highlight_theme_light | append: '.css' }}" media="" id="highlight_theme_light" />
<!-- Styles -->
{% if site.icon.size <= 4 %}
<link rel="shortcut icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>{{ site.icon }}</text></svg>">
{% elsif site.icon != blank %}
<link rel="shortcut icon" href="{{ site.icon | prepend: '/assets/img/' | relative_url}}"/>
{% endif %}
<link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url }}">
<link rel="canonical" href="{{ page.url | replace:'index.html','' | absolute_url }}">
<!-- Dark Mode -->
{% if site.enable_darkmode %}
<link rel="stylesheet" href="/assets/stylesheets/{{ site.highlight_theme_dark | append: '.css' }}" media="" id="highlight_theme_dark" />
<script src="{{ '/assets/js/theme.js' | relative_url }}"></script>
<script src="{{ '/assets/js/dark_mode.js' | relative_url }}"></script>
{% endif %}

208
_includes/head.liquid Normal file
View File

@ -0,0 +1,208 @@
<!-- Metadata, OpenGraph and Schema.org -->
{% include metadata.liquid %}
<!-- Security: Content Security Policy -->
<!-- Permissive CSP suitable for academic websites. Allows external images, videos, and common embed services. -->
<!-- To customize for your needs, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data: https:; media-src 'self' https:; frame-src 'self' https:; connect-src 'self' https:;"
>
<!-- Bootstrap & MDB -->
<link rel="stylesheet" href="{{ '/assets/css/bootstrap.min.css' | relative_url | bust_file_cache }}">
<link
rel="stylesheet"
href="{{ site.third_party_libraries.mdb.url.css }}"
integrity="{{ site.third_party_libraries.mdb.integrity.css }}"
crossorigin="anonymous"
>
{% if page.pretty_table %}
<!-- Bootstrap Table -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.bootstrap-table.url.css }}"
integrity="{{ site.third_party_libraries.bootstrap-table.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
<!-- Fonts & Icons -->
<link defer rel="stylesheet" href="{{ '/assets/css/academicons.min.css' | relative_url | bust_file_cache }}">
<link defer rel="stylesheet" href="{{ '/assets/css/scholar-icons.css' | relative_url | bust_file_cache }}">
<link
defer
rel="stylesheet"
type="text/css"
href="{{ site.third_party_libraries.google_fonts.url.fonts }}"
>
<!-- Code Syntax Highlighting -->
<link
defer
rel="stylesheet"
href="{{ '/assets/css/jekyll-pygments-themes-github.css' | relative_url | bust_file_cache }}"
media=""
id="highlight_theme_light"
>
{% if page.toc and page.toc.sidebar %}
<!-- Sidebar Table of Contents -->
<link defer href="{{ '/assets/css/bootstrap-toc.min.css' | relative_url | bust_file_cache }}" rel="stylesheet">
{% endif %}
<!-- Styles -->
{% if page.pseudocode %}
<!-- pseudocode -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.pseudocode.url.css }}"
integrity="{{ site.third_party_libraries.pseudocode.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
{% if site.icon.size <= 4 %}
<link
rel="shortcut icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>{{ site.icon }}</text></svg>"
>
{% elsif site.icon != blank %}
<link rel="shortcut icon" href="{{ site.icon | prepend: '/assets/img/' | relative_url | bust_file_cache}}">
{% endif %}
<link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url | bust_css_cache }}">
<link rel="canonical" href="{{ page.url | replace:'index.html','' | absolute_url }}">
{% if site.enable_darkmode %}
<!-- Dark Mode -->
<script src="{{ '/assets/js/theme.js' | relative_url | bust_file_cache }}"></script>
<link
defer
rel="stylesheet"
href="{{ '/assets/css/jekyll-pygments-themes-native.css' | relative_url | bust_file_cache }}"
media="none"
id="highlight_theme_dark"
>
<script>
initTheme();
</script>
{% endif %}
{% if page.map %}
<!-- GeoJSON support via Leaflet -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.leaflet.url.css }}"
integrity="{{ site.third_party_libraries.leaflet.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
{% if page.code_diff %}
<!-- diff2html -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.highlightjs.url.css.light }}"
integrity="{{ site.third_party_libraries.highlightjs.integrity.css.light }}"
crossorigin="anonymous"
media="screen and (prefers-color-scheme: light)"
>
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.highlightjs.url.css.dark }}"
integrity="{{ site.third_party_libraries.highlightjs.integrity.css.dark }}"
crossorigin="anonymous"
media="screen and (prefers-color-scheme: dark)"
>
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.diff2html.url.css }}"
integrity="{{ site.third_party_libraries.diff2html.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
{% if page.images %}
{% if page.images.compare %}
<!-- Image comparison slider -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.img-comparison-slider.url.css }}"
integrity="{{ site.third_party_libraries.img-comparison-slider.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
{% if page.images.lightbox2 %}
<!-- Lightbox2 -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.lightbox2.url.css }}"
integrity="{{ site.third_party_libraries.lightbox2.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
{% if page.images.photoswipe %}
<!-- Photoswipe -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.photoswipe.url.css }}"
crossorigin="anonymous"
>
{% endif %}
{% if page.images.slider %}
<!-- Image slider -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.swiper.url.css }}"
integrity="{{ site.third_party_libraries.swiper.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
{% if page.images.spotlight %}
<!-- Spotlight -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.spotlight.url.css }}"
integrity="{{ site.third_party_libraries.spotlight.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
{% if page.images.venobox %}
<!-- Venobox -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.venobox.url.css }}"
integrity="{{ site.third_party_libraries.venobox.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}
{% endif %}
{% if page.tikzjax %}
<link defer rel="stylesheet" type="text/css" href="{{ '/assets/css/tikzjax.min.css' | relative_url | bust_file_cache }}">
{% endif %}
{% if site.enable_cookie_consent %}
<!-- Cookie Consent -->
<link
defer
rel="stylesheet"
href="{{ site.third_party_libraries.vanilla-cookieconsent.url.css }}"
integrity="{{ site.third_party_libraries.vanilla-cookieconsent.integrity.css }}"
crossorigin="anonymous"
>
{% endif %}

View File

@ -1,119 +0,0 @@
<header>
<!-- Nav Bar -->
<nav id="navbar" class="navbar navbar-light navbar-expand-sm {% if site.navbar_fixed %}fixed-top{% else %}sticky-top{% endif %}">
<div class="container">
{% if page.permalink != '/' -%}
<a class="navbar-brand title font-weight-lighter" href="{{ site.baseurl }}/">
{%- if site.title == "blank" -%}
{%- if site.first_name -%}
<span class="font-weight-bold">{{- site.first_name -}}&nbsp;</span>
{%- endif -%}
{%- if site.middle_name -%}
{{- site.middle_name -}}&nbsp;
{%- endif -%}
{%- if site.last_name -%}
{{- site.last_name -}}
{%- endif -%}
{%- else -%}
{{- site.title -}}
{%- endif -%}
</a>
{%- elsif site.enable_navbar_social -%}
<!-- Social Icons -->
<div class="navbar-brand social">
{% include social.html %}
</div>
{% endif %}
<!-- Navbar Toggle -->
<button class="navbar-toggler collapsed ml-auto" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar top-bar"></span>
<span class="icon-bar middle-bar"></span>
<span class="icon-bar bottom-bar"></span>
</button>
<div class="collapse navbar-collapse text-right" id="navbarNav">
<ul class="navbar-nav ml-auto flex-nowrap">
{%- for page in site.pages -%}
{% if page.permalink == '/' %}
{% assign about_title = page.title %}
{% endif %}
{% endfor %}
<!-- About -->
<li class="nav-item {% if page.permalink == '/' %}active{% endif %}">
<a class="nav-link" href="{{ '/' | relative_url }}">{{ about_title }}
{%- if page.permalink == '/' -%}
<span class="sr-only">(current)</span>
{%- endif -%}
</a>
</li>
{% if site.blog_nav_title %}
<!-- Blog -->
<li class="nav-item {% if page.url contains 'blog' %}active{% endif %}">
<a class="nav-link" href="{{ '/blog/' | relative_url }}">{{ site.blog_nav_title }}
{%- if page.url contains 'blog' -%}
<span class="sr-only">(current)</span>
{%- endif -%}
</a>
</li>
{%- endif %}
<!-- Other pages -->
{%- assign sorted_pages = site.pages | sort: "nav_order" -%}
{%- for p in sorted_pages -%}
{%- if p.nav and p.autogen == nil -%}
{%- if p.dropdown %}
<li class="nav-item dropdown {% if page.title == p.title %}active{% endif %}">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ p.title }}
{%- if page.title == p.title -%}
<span class="sr-only">(current)</span>
{%- endif -%}
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
{%- for child in p.children -%}
{%- if child.title == 'divider' %}
<div class="dropdown-divider"></div>
{%- else %}
<a class="dropdown-item" href="{{ child.permalink | relative_url }}">{{ child.title }}</a>
{%- endif -%}
{% endfor %}
</div>
</li>
{%- else %}
<li class="nav-item {% if page.title == p.title %}active{% endif %}">
<a class="nav-link" href="{{ p.url | relative_url }}">{{ p.title }}
{%- if page.title == p.title -%}
<span class="sr-only">(current)</span>
{%- endif -%}
</a>
</li>
{%- endif -%}
{%- endif -%}
{% endfor -%}
{%- if site.enable_darkmode %}
<!-- Toogle theme mode -->
<li class="toggle-container">
<button id="light-toggle" title="Change theme">
<i class="fas fa-moon"></i>
<i class="fas fa-sun"></i>
</button>
</li>
{%- endif %}
</ul>
</div>
</div>
</nav>
{% if site.enable_progressbar %}
<!-- Scrolling Progress Bar -->
<progress id="progress" value="0">
<div class="progress-container">
<span class="progress-bar"></span>
</div>
</progress>
{%- endif %}
</header>

150
_includes/header.liquid Normal file
View File

@ -0,0 +1,150 @@
<header>
<!-- Nav Bar -->
<nav id="navbar" class="navbar navbar-light navbar-expand-sm {% if site.navbar_fixed %}fixed-top{% else %}sticky-top{% endif %}" role="navigation">
<div class="container">
{% if page.permalink != '/' %}
<a class="navbar-brand title font-weight-lighter" href="{{ site.baseurl }}/">
{% if site.title == 'blank' %}
{% if site.first_name %}
<span class="font-weight-bold">
{{- site.first_name -}}
</span>
{% endif %}
{% if site.middle_name %}
{{- site.middle_name -}}
{% endif %}
{% if site.last_name %}
{{- site.last_name -}}
{% endif %}
{% else %}
{{- site.title -}}
{% endif %}
</a>
{% elsif site.enable_navbar_social %}
<!-- Social Icons -->
<div class="navbar-brand social">{% social_links %}</div>
{% endif %}
<!-- Navbar Toggle -->
<button
class="navbar-toggler collapsed ml-auto"
type="button"
data-toggle="collapse"
data-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar top-bar"></span>
<span class="icon-bar middle-bar"></span>
<span class="icon-bar bottom-bar"></span>
</button>
<div class="collapse navbar-collapse text-right" id="navbarNav">
<ul class="navbar-nav ml-auto flex-nowrap">
{% for page in site.pages %}
{% if page.permalink == '/' %} {% assign about_title = page.title %} {% endif %}
{% endfor %}
<!-- About -->
<li class="nav-item {% if page.permalink == '/' %}active{% endif %}">
<a class="nav-link" href="{{ '/' | relative_url }}">
{{- about_title }}
{% if page.permalink == '/' %}
<span class="sr-only">(current)</span>
{% endif %}
</a>
</li>
<!-- Other pages -->
{% assign sorted_pages = site.pages | sort: 'nav_order' %}
{% for p in sorted_pages %}
{% if p.nav and p.autogen == null %}
{% if p.dropdown %}
{% assign has_active_child = false %}
{% for child in p.children %}
{% if page.title == child.title %}
{% assign has_active_child = true %}
{% endif %}
{% endfor %}
<li class="nav-item dropdown {% if page.title == p.title or has_active_child %}active{% endif %}">
<a
class="nav-link dropdown-toggle"
href="#"
id="navbarDropdown"
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
{{- p.title }}
{% if page.title == p.title or has_active_child %}
<span class="sr-only">(current)</span>
{% endif %}
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
{% for child in p.children %}
{% if child.title == 'divider' %}
<div class="dropdown-divider"></div>
{% else %}
<a
class="dropdown-item {% if page.title == child.title %}active{% endif %}"
href="{% if child.permalink contains '://' %}{{ child.permalink }}{% else %}{{ child.permalink | relative_url }}{% endif %}"
>
{{- child.title -}}
</a>
{% endif %}
{% endfor %}
</div>
</li>
{% else %}
{% assign parent_link = p.permalink | remove: 'index.html' %}
<li class="nav-item {% if page.url contains parent_link %}active{% endif %}">
{%- if p.permalink contains '://' -%}
{%- assign url = p.permalink -%}
{%- elsif p.permalink contains '/blog/' -%}
{%- assign url = '/blog/' -%}
{%- else -%}
{%- assign url = p.url -%}
{%- endif %}
<a class="nav-link" href="{{ url | relative_url }}">
{{- p.title }}
{% if page.url contains p.url %}
<span class="sr-only">(current)</span>
{% endif %}
</a>
</li>
{% endif %}
{% endif %}
{% endfor %}
{% if site.search_enabled %}
<!-- Search -->
<li class="nav-item">
<button id="search-toggle" title="Search" onclick="openSearchModal()">
<span class="nav-link">ctrl k <i class="fa-solid fa-magnifying-glass"></i></span>
</button>
</li>
{% endif %}
{% if site.enable_darkmode %}
<!-- Toogle theme mode -->
<li class="toggle-container">
<button id="light-toggle" title="Change theme">
<i class="fa-half-sun-moon" id="light-toggle-system"></i>
<i class="fa-solid fa-moon" id="light-toggle-dark"></i>
<i class="fa-solid fa-sun" id="light-toggle-light"></i>
</button>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
{% if site.enable_progressbar %}
<!-- Scrolling Progress Bar -->
<progress id="progress" value="0">
<div class="progress-container">
<span class="progress-bar"></span>
</div>
</progress>
{% endif %}
</header>

View File

@ -0,0 +1,48 @@
<div class="news">
{% if page.latest_posts != blank %}
{% assign latest_posts_size = site.posts | size %}
<div
class="table-responsive"
{% if page.latest_posts.scrollable and latest_posts_size > 3 %}
style="max-height: 60vw"
{% endif %}
>
<table class="table table-sm table-borderless">
{% assign latest_posts = site.posts %}
{% if page.latest_posts.limit %}
{% assign latest_posts_limit = page.latest_posts.limit %}
{% else %}
{% assign latest_posts_limit = latest_posts_size %}
{% endif %}
{% for item in latest_posts limit: latest_posts_limit %}
<tr>
<th scope="row" style="width: 20%">{{ item.date | date: '%b %d, %Y' }}</th>
<td>
{% if item.redirect == blank %}
<a class="news-title" href="{{ item.url | relative_url }}">{{ item.title }}</a>
{% elsif item.redirect contains '://' %}
<a class="news-title" href="{{ item.redirect }}" target="_blank">{{ item.title }}</a>
<svg width="2rem" height="2rem" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
<path
d="M17 13.5v6H5v-12h6m3-3h6v6m0-6-9 9"
class="icon_svg-stroke"
stroke="#999"
stroke-width="1.5"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
></path>
</svg>
{% else %}
<a class="news-title" href="{{ item.redirect | relative_url }}">{{ item.title }}</a>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% else %}
<p>No posts so far...</p>
{% endif %}
</div>

View File

@ -1,200 +0,0 @@
{% if site.enable_google_verification or site.enable_bing_verification %}
<!-- Website verification -->
{% if site.enable_google_verification -%}
<meta name="google-site-verification" content="{{ site.google_site_verification }}" />
{%- endif -%}
{% if site.enable_bing_verification -%}
<meta name="msvalidate.01" content="{{ site.bing_site_verification }}" />
{%- endif -%}
{%- endif %}
<!-- Standard metadata -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>
{%- if site.title == "blank" -%}
{%- capture title -%}{{ site.first_name }} {{ site.middle_name }} {{ site.last_name }}{%- endcapture -%}
{%- else -%}
{%- capture title -%}{{ site.title }}{%- endcapture -%}
{%- endif -%}
{% if page.url == '/blog/index.html' %}
{{ site.blog_nav_title }} | {{ title }}
{%- elsif page.title != "blank" and page.url != "/" -%}
{%- if page.title == nil or page.title == "" -%}
{{ page.date | date: "%Y" }} | {{ title }}
{%- else -%}
{{ page.title }} | {{ title }}
{%- endif -%}
{%- else -%}
{{ title }}
{%- endif -%}
</title>
<meta name="author" content="{{ site.first_name }} {{ site.middle_name }} {{ site.last_name }}" />
<meta name="description" content="{%- if page.description -%}{{ page.description }}{%- else -%}{{ site.description }}{%- endif -%}" />
{%- if page.keywords or site.keywords %}
<meta name="keywords" content="{%- if page.keywords -%}{{ page.keywords }}{%- else -%}{{ site.keywords }}{%- endif -%}" />
{%- endif %}
{%- if site.serve_og_meta %}
<!-- OpenGraph -->
<meta property="og:site_name" content="{{ title }}" />
<meta property="og:type" content="website" />
<meta property="og:title" content="{%- if page.title -%}{{ title }} | {{ page.title }}{%- else -%}{{ title }}{%- endif -%}" />
<meta property="og:url" content="{{ page.url | prepend: site.baseurl | prepend: site.url | remove_first: 'index.html' }}" />
<meta property="og:description" content="{%- if page.description -%}{{ page.description }}{%- else -%}{{ site.description }}{%- endif -%}" />
{% if page.og_image or site.og_image -%}
<meta property="og:image" content="{%- if page.og_image -%}{{ page.og_image }}{%- else -%}{{ site.og_image }}{%- endif -%}" />
{%- endif %}
<meta property="og:locale" content="{{ site.lang }}" />
<!-- Twitter card -->
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="{%- if page.title -%}{{ page.title }}{%- else -%}{{ title }}{%- endif -%}" />
<meta name="twitter:description" content="{%- if page.description -%}{{ page.description }}{%- else -%}{{ site.description }}{%- endif -%}" />
{% if page.og_image or site.og_image -%}
<meta name="twitter:image" content="{%- if page.og_image -%}{{ page.og_image }}{%- else -%}{{ site.og_image }}{%- endif -%}" />
{%- endif %}
{% if site.twitter_username -%}
<meta name="twitter:site" content="@{{ site.twitter_username }}" />
<meta name="twitter:creator" content="@{{ site.twitter_username }}" />
{%- endif %}
{%- endif %}
{%- if site.serve_schema_org %}
<!-- Schema.org -->
{%- comment -%} Social links generator for "sameAs schema" {%- endcomment %}
{% assign sameaslinks = "" | split: "," %}
{%- if site.orcid_id -%}
{%- capture link -%}https://orcid.org/{{ site.orcid_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.scholar_userid -%}
{%- capture link -%}https://scholar.google.com/citations?user={{ site.scholar_userid }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.semanticscholar_id -%}
{%- capture link -%}https://www.semanticscholar.org/author/{{ site.semanticscholar_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.publons_id -%}
{%- capture link -%}https://publons.com/a/{{ site.publons_id }}/{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.research_gate_profile -%}
{%- capture link -%}https://www.researchgate.net/profile/{{site.research_gate_profile}}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.github_username -%}
{%- capture link -%}https://github.com/{{ site.github_username }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.telegram_username -%}
{%- capture link -%}https://telegram.me/{{ site.telegram_username }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.linkedin_username -%}
{%- capture link -%}https://www.linkedin.com/in/{{ site.linkedin_username }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.twitter_username -%}
{%- capture link -%}https://twitter.com/{{ site.twitter_username }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.medium_username -%}
{%- capture link -%}https://medium.com/@{{ site.medium_username }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.quora_username -%}
{%- capture link -%}https://www.quora.com/profile/{{ site.quora_username }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.blogger_url -%}
{%- capture link -%}{{ site.blogger_url }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.work_url -%}
{%- capture link -%}{{ site.work_url }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.wikidata_id -%}
{%- capture link -%}https://www.wikidata.org/wiki/{{ site.wikidata_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.strava_userid -%}
{%- capture link -%}https://www.strava.com/athletes/{{ site.strava_userid }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.keybase_username -%}
{%- capture link -%}https://keybase.io/{{ site.keybase_username }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.gitlab_username -%}
{%- capture link -%}https://gitlab.com/{{ site.gitlab_username }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.dblp_url -%}
{%- capture link -%}{{ site.dblp_url }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.stackoverflow_id -%}
{%- capture link -%}https://stackoverflow.com/users/{{ site.stackoverflow_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.kaggle_id -%}
{%- capture link -%}https://www.kaggle.com/{{ site.kaggle_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.lastfm_id -%}
{%- capture link -%}https://www.last.fm/user/{{ site.lastfm_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.spotify_id -%}
{%- capture link -%}https://open.spotify.com/user/{{ site.spotify_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.pinterest_id -%}
{%- capture link -%}https://www.pinterest.com/{{ site.pinterest_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.unsplash_id -%}
{%- capture link -%}https://unsplash.com/@{{ site.unsplash_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.instagram_id -%}
{%- capture link -%}https://instagram.com/{{ site.instagram_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.facebook_id -%}
{%- capture link -%}https://facebook.com/{{ site.facebook_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if site.discord_id -%}
{%- capture link -%}https://discord.com/users/{{ site.discord_id }}{%- endcapture -%}
{%- assign sameaslinks = sameaslinks | push: link -%}
{%- endif -%}
{%- if sameaslinks != blank -%}
{%- assign sameaslinks = sameaslinks | split: "" -%}
{%- endif -%}
<script type="application/ld+json">
{
"author":
{
"@type": "Person",
"name": "{{ site.first_name }} {{ site.middle_name }} {{ site.last_name }}"
},
"url": "{{ page.url | prepend: site.baseurl | prepend: site.url }}",
"@type": "WebSite",
"description": "{%- if page.description -%}{{ page.description }}{%- else if site.description -%}{{ site.description }}{%- endif -%}",
"headline": "{%- if page.title -%}{{ page.title }}{%- else -%}{{ site.title }}{%- endif -%}",
{% if sameaslinks != blank -%}
"sameAs": {{ sameaslinks }},
{%- endif %}
"name": "{{ site.first_name }} {{ site.middle_name }} {{ site.last_name }}",
"@context": "https://schema.org"
}
</script>
{%- endif %}

Some files were not shown because too many files have changed in this diff Show More