Source code of the yctf.ch website.
The file structure is as follows:
content/
├── data/
└── events.toml
├── pages/
│ └── ...
└── writeups/
├── <ctf-name>/
│ └── <challenge-name>/
│ ├── index.md
│ └── files/
│ ├── <files>
│ └── ...
└── ...
Mostly static pages like the home page, about page, etc. are stored in the content/pages/
directory.
Writeups are stored in the content/writeups/
directory as a git submodule pointing to the writeups repository.
For contributing writeups, see the writeups README.
To quickly get started with a new writeup, you can use the CLI tool:
uv run scripts/cli.py writeups new
This will prompt you for the required metadata and create a new writeup template in the appropriate directory.
Events are stored in the content/data/events.toml
file.
Example event entry:
[[events]]
title = {
en = "Event title in English",
fr = "Titre de l'event en français"
}
description = {
en = "Brief description of the event",
fr = "Description brève de l'event"
}
start_date = "2025-10-15T18:00:00+01:00" # ISO 8601 format
end_date = "2025-10-15T20:00:00+01:00" # ISO 8601 format
location = "Physical/Virtual location"
type = "competition" # competition, meeting, conference, training, etc.
url = "https://example.com" # Optional external link, shown as "learn more"
registration_deadline = "2025-10-14T23:59:59+01:00" # Optional deadline
To add events, you can either edit the events.toml
file directly or use the import scripts described in the Importing Content section.
- Clone the repository with submodules
git clone --recurse-submodules https://github.com/y-ctf/y-ctf.github.io.git
cd y-ctf.github.io
Or if you've already cloned without submodules:
git submodule update --init --recursive
brew install cestef/tap/zola
# or with cargo
cargo install --git https://github.com/cestef/zola
You can also download a pre-built binary from the releases page.
- Install dependencies (
pnpm
)
pnpm install
- Start the development server
pnpm dev
Writeups from CTFNote
You can import writeups from CTFNote using the CLI tool provided in this repository. Make sure you have Python or uv
installed.
# Import writeups for a specific CTF
uv run scripts/cli.py writeups import -c "<ctf-name>" -a "Bearer <API_TOKEN>"
How to retrieve the API token from CTFNote
Log in to your CTFNote account, open the developer console in your browser, and run the following command to get your token:
localStorage.getItem("JWT")
-
Commit and push changes in the writeups submodule:
cd content/writeups git add . git commit -m "add writeups for <ctf-name>" git push
-
Update the submodule reference in the main repository:
cd ../.. git add content/writeups git commit -m "update writeups submodule" git push
Events can be imported from ICS calendar files or URLs. To import events directly from CTFNote, you'll need the ICS URL and the iCalendar secret key.
# Import from a URL
uv run scripts/cli.py events import -i "https://yctf.ch/calendar.ics?key=<CALENDAR_KEY>" --event-type "competition"
# Import from a local ICS file
uv run scripts/cli.py events import -i "path/to/calendar.ics"