本项目未基于其他开源网站框架,版权完全归属于 NEBULIS Lab,未经授权不得使用。详见 LICENSE 文件。
This project is not based on any other open-source website framework. All rights to this project are exclusively owned by NEBULIS Lab and may not be used without authorization. See LICENSE file for details.
This guide explains how to quickly maintain and update the NEBULIS Lab website. The website uses a pure static architecture where all content is managed through JSON files, without needing to modify HTML or JavaScript code.
- Adding a New Project
- Editing Publications
- Editing People Information
- Editing News
- Image Size Requirements
-
Create a new JSON file in the
data/projects/directory -
Filename format:
<id>-<year>.json- Example:
my-project-2025.json idmust be a unique identifier (lowercase, hyphen-separated)yearmust be a 4-digit year
- Example:
-
Important: The
idfield in the JSON file must exactly match the filename (without extension)- Filename:
my-project-2025.json idin JSON:"my-project-2025"
- Filename:
Refer to the template file data/projects/template-project-2025.json. The JSON file must contain the following fields:
{
"id": "project-id-2025",
"title": "Project Title",
"authors": "Author Names",
"venue": "Conference/Journal",
"year": 2025,
"thumbnail": "image/projects/project-id/thumbnail.jpg",
"short_description": "Short description (for project card display)",
"tags": ["Tag1", "Tag2", "Tag3"],
"pdf": "https://example.com/paper.pdf",
"code": "https://github.com/example/repo",
"slides": "https://example.com/slides.pdf",
"project_page": "https://example.com/project",
"sections": [
{
"title": "Section Title",
"text": "Section content..."
}
],
"figures": [
{
"src": "image/projects/project-id/figure1.jpg",
"caption": "Figure caption"
}
],
"tables": [
{
"html": "<table>...</table>",
"caption": "Table caption"
}
],
"bibtex": "@article{...}"
}Field Descriptions:
id: Must match the filename (without extension)title: Project title (required)authors: Author information (optional)venue: Conference/journal (optional)year: Project year (recommended)thumbnail: Thumbnail image path (for project card)short_description: Short description (for project card, automatically justified)tags: Array of tags (optional)titleZh,shortDescriptionZh,tagsZh,venueZh,thumbnailAltZh: Chinese card content; paired English fields aretitle,short_description,tags,venue, andthumbnailAltvenue: Card publication label, such asNeurIPS 2026orarXiv · 2026-10-16(the arXiv first-submission date)pdf,code,slides,project_page: Links (optional, buttons will not display if field is empty string"")sections: Array of sections, each containingtitleandtextfigures: Array of figures, each containingsrcandcaptiontables: Array of tables, each containinghtmlandcaptionbibtex: BibTeX citation (optional, BibTeX section will not display if empty string"")
- Upload project images to the
image/projects/<project-id>/directory - Ensure the path in the
thumbnailfield correctly points to the image file - See Image Size Requirements below for image specifications
Important: Since GitHub Pages is a pure static environment, JavaScript cannot automatically list directory contents. Therefore, you must manually add new projects to the manifest file.
- Open
data/projects/manifest.json - Add the new project's filename (including
.jsonextension) to theprojectsarray
{
"projects": [
"new-project-2025.json",
"existing-project-2025.json",
...
]
}Note: Projects are sorted by year descending; projects from the same year keep their order in manifest.json. Within a year, list conference papers first, newest conference first, followed by preprints in descending arXiv first-submission order. Keep the English and Chinese cards in the same order.
File path: data/publications.json
This file is a JSON array, where each publication contains the following fields:
{
"year": "2024",
"title": "Paper Title",
"authors": "Author Names",
"venue": "Conference/Journal Name",
"pdf": "https://example.com/paper.pdf",
"code": "https://github.com/example/repo",
"project": "https://example.com/project",
"slides": "https://example.com/slides.pdf",
"award": "Award information (optional)"
}Editing Methods:
- Directly edit the
data/publications.jsonfile - Add new publication: Add a new object to the array
- Modify existing publication: Edit the corresponding object
- Delete publication: Remove the corresponding object from the array
File path: data/people.json
This file is a JSON array, where each person contains the following fields:
{
"name": "Chinese Name",
"nameEn": "English Name",
"role": "faculty|phd|master|undergraduate|alumni",
"program": "Faculty|PhD|Master|Undergraduate|Alumni",
"advisors": ["Advisor Name"],
"description": "English description",
"descriptionZh": "Chinese description",
"avatar": "image/user/avatar.jpg",
"homepage": "https://example.com",
"scholar": "https://scholar.google.com/...",
"github": "https://github.com/...",
"email": "email@example.com",
"status": "current|alumni",
"cohort": 2025,
"affiliation": "NEBULIS Lab"
}Editing Methods:
- Directly edit the
data/people.jsonfile - Add new member: Add a new object to the array
- Modify existing member: Edit the corresponding object
- Delete member: Remove the corresponding object from the array
Avatar Images:
- Upload to
image/user/directory - Recommended size: Square, at least 280x280 pixels
File path: data/news/
-
Create a new JSON file in the
data/news/directory -
Filename format:
news-<YYYY-MM-DD>.jsonornews-<YYYY-MM>.json- Example:
news-2025-10-29.jsonornews-2025-01.json
- Example:
-
JSON file content:
{
"id": "news-2025-10-29",
"title": "News Title",
"tag": "Tag (e.g., Announcement, Research, Infrastructure)",
"excerpt": "News excerpt",
"image": "image/news/20251029.jpg",
"date": "2025-10-29",
"link": "https://example.com/news-page"
}Field Descriptions:
id: Unique identifier, usually matches the filenametitle: News title (required)tag: News tag (optional)excerpt: News excerpt (optional)image: News image path (optional, image will not display if empty)date: Publication date (optional)link: News detail page link (optional, use"#"to indicate no link)
- Update manifest.json:
- Open
data/news/manifest.json - Add the new news filename (including
.jsonextension) to thenewsarray
- Open
{
"news": [
"news-2025-10-29.json",
"news-2025-10-27.json",
...
]
}Note: News will be displayed in the order specified in manifest.json, but will ultimately be sorted by date in descending order.
Simply edit the corresponding JSON file.
Thumbnail:
- Recommended size: 1920×1080 pixels (16:9 aspect ratio)
- Minimum size: 1280×720 pixels
- File format: JPG, PNG
- File path:
image/projects/<project-id>/thumbnail.jpg
Project Detail Page Images (figures):
- Recommended size: 1920×1080 pixels or higher (16:9 aspect ratio)
- File format: JPG, PNG
- File path:
image/projects/<project-id>/figure1.jpg
Notes:
- Project cards use a 16:9 aspect ratio for display
- Images will be automatically cropped to fit the container. It is recommended to use a 16:9 aspect ratio to avoid important content being cropped
Recommended size:
- Primary size: 1920×1080 pixels (16:9 aspect ratio)
- Minimum size: 1280×720 pixels
- File format: JPG, PNG
- File path:
image/news/<YYYYMMDD>.jpg
Notes:
- News list page displays at 160×110 pixels (approximately 1.45:1 aspect ratio)
- News detail page (feature card) uses 16:9 aspect ratio for display
- Images will be automatically cropped to fit the container. It is recommended to use a 16:9 aspect ratio
Recommended size:
- Recommended size: 280×280 pixels (square)
- Minimum size: 140×140 pixels
- File format: JPG, PNG
- File path:
image/user/<name>.jpg
Notes:
- Avatars will be displayed as circles. It is recommended to use square images
- Ensure faces are centered in the image
- JSON Format: Ensure all JSON files are correctly formatted. You can use online JSON validation tools to check
- File Paths: All image paths use relative paths, starting from the website root directory
- manifest.json: After adding a new project or news, you must update the corresponding manifest.json file
- ID Consistency: The
idfield in the project JSON file must exactly match the filename (without extension) - Empty Field Handling:
- If link fields (
pdf,code,slides,project_page) are empty strings"", the corresponding buttons will not display - If
bibtexis an empty string"", the BibTeX section will not display - If the news
imagefield is empty or missing, images will not display in the news list
- If link fields (
- Commit changes to the Git repository
- Push to GitHub
- Wait for GitHub Pages to automatically deploy (usually takes a few minutes)
- Visit the website to check the results
- Project Template:
data/projects/template-project-2025.json - When creating a new project, you can copy this template and modify the content
If you have any questions, please refer to the JSON file structure of existing projects or contact the website maintainer.
All root website pages load js/visitors.js and styles/visitors.css. One document load (including a return from the browser back/forward cache) counts as one page view. New loads have independent event IDs; retries reuse the same ID. Collection runs only on the lab's production hostnames, with URL query strings and fragments omitted.
The footer preserves the approved layout. It displays aggregate counts and IP-estimated country/region aggregates from the public statistics API. Figures remain unavailable if the API fails; demo values are never substituted. The previous visitor-preview.html route redirects to the live footer.
The durable backend is maintained separately through Sites, project appgprj_6add812d00408191b1d72643e279e253; its source and D1 schema migrations are stored in that project's source repository. The endpoint is configured in js/visitors.js. The application database stores location aggregates and delivery IDs, not complete IP addresses, cookies, or URL query strings. Delivery IDs older than 24 hours are pruned on the next accepted visit. Public GET /api/stats does not create visits.
The cached basemap in image/visitor-world.svg uses Natural Earth public-domain geometry; js/visitor-data.js uses the matching Natural Earth 1 projection. Counts begin with the first accepted live page load, reported by the API as startedAt.
Country markers use Natural Earth public-domain label positions; they represent countries/regions, not precise visitor cities. The deployed host forwards Cloudflare country headers, and the collector does not need an external IP lookup service.
Run the website regression checks with node --test tests/*.test.mjs. The backend source has its separate real-SQLite test suite.