The marvil.co website. https://marvil.co/
Find a file
Jorge Martinez abcd93ea1d
All checks were successful
Build and Push Docker latest / docker-latest (push) Successful in 12s
fix: Add Chinese CV
2026-10-01 17:28:27 +08:00
.forgejo/workflows feat: add Docker workflow for building and pushing images to local registry 2026-04-14 17:31:52 -06:00
backend feat: add Chinese site 2026-10-01 17:07:30 +08:00
frontend fix: Add Chinese CV 2026-10-01 17:28:27 +08:00
.gitignore feat: add Chinese site 2026-10-01 17:07:30 +08:00
LICENSE feat: add AGPLv3 license 2026-03-01 13:44:42 -06:00
README.md feat: add Chinese site 2026-10-01 17:07:30 +08:00

marvil.co

This is the code repository for my personal portfolio website, marvil.co. It showcases my projects, blog posts, and other professional information.

The frontend is generated at build time using Node.js and served through Cloudflare Workers. The frontend is built with vanilla JavaScript, HTML, and CSS to ensure fast load times and optimal performance. It is built from Markdown into static HTML files using a custom static site generator.

Some parts of the site, such as the microblog, utilize client-side JavaScript to enhance user experience with dynamic content (the posts themselves).

This repository is organized into two main directories:

frontend/

This directory contains the blog (regular blog and portfolio section), the static site generator, and all static assets (images, CSS, JS).

backend/

This directory is a Dockerized Node.js application that handles more dynamic features such as the microblog, contact form submissions, comments and reactions, the guestbook, and an admin panel for managing content.

Note: Use NatalieHill.metascraper to remove the metadata from images in blog posts before uploading them.

Build

cd backend && docker build \
-t code.marvil.co/marvil.co/website:latest \
-t 10.0.0.6:7920/marvil.co/website:latest . \
&& docker push 10.0.0.6:7920/marvil.co/website:latest

English and Chinese editions

Both sites use the same templates, assets, and home-server API. From frontend/build:

npm run build       # frontend/dist, marvil.co
npm run build:cn    # frontend/dist-cn, marvil.cn
npm run serve:cn    # preview with dist-cn as the server root
npm run deploy     # English Worker
npm run deploy:cn  # Chinese Worker

The Worker names in frontend/wrangler.jsonc and frontend/wrangler.cn.jsonc are marvil-co and marvil-cn. Set the English name to your existing Worker name before deploying if it differs. Custom-domain configuration requires the domains in your Cloudflare account. Deployments are separate; build both editions after adding a translation so their language links agree. No deployment is performed by the build commands.

Add Chinese Markdown as post.zh-CN.md beside the corresponding post.md, with the same metadata structure. Translate titles, subtitles, categories, image descriptions, body text, and reader-facing portfolio fields. Keep author IDs, slugs, technology names, media paths, and URLs intact. Chinese language/locale and the author display name are supplied by the builder. Draft directories beginning with _ remain unpublished. Only translated articles appear in Chinese listings and feeds. Links to untranslated articles lead to their original edition.

Supply these before launching:

  • frontend/static/files/Cheng_Yuan_CV.pdf (the download link is already present).
  • Your WeChat ID in locale.wechatId in frontend/build/locales.js.

The builder generates frontend/dist-cn/res/images/wechat-qr.svg from locale.wechatQrPayload, the exact URL decoded from your WeChat contact QR (including its query string). The SVG is preloaded and displayed at 280×280 CSS pixels; no raster sizes or fallback images are needed. If you reset your contact QR, update this payload and rebuild. Chinese pages use local assets and system Chinese fonts. The microblog remains available only on .co. Finance content and its design sources have been removed. Each build clears its own output to prevent unpublished pages surviving.

Backend migrations

Numbered SQL files in backend/src/migrations run automatically during database initialization, before either API starts. Each migration and its ledger entry execute in one transaction; failures stop startup. You can also run npm run migrate from backend, with DATA_DIR set to the parent directory containing db/marvil.db (default /data).

001_remove_financial_comments.sql deletes financial comments, descendant replies, and their reaction/vote records. This migration is destructive and has no automatic rollback; preserve a database backup before deploying the updated backend. The public and admin APIs no longer accept the finance article type. The migration has not been run against your server database here.