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 newThis 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 deadlineTo 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.ioOr if you've already cloned without submodules:
git submodule update --init --recursivebrew install cestef/tap/zola
# or with cargo
cargo install --git https://github.com/cestef/zolaYou can also download a pre-built binary from the releases page.
- Install dependencies (
pnpm)
pnpm install- Start the development server
pnpm devWriteups 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"

