code wiki / _hdl_build / nx_sitegen_video.nx
nx_sitegen_video.nx source
↩ module page · 51 lines · 3848 B
1// nx_sitegen_video.nx -- AUTO-BUILDER, VIDEO-GALLERY page type (operator's "sites like YouTube showing pets to
2// others"). Builds a complete responsive video-gallery page FROM DATA: page title + heading + a list of videos
3// (title / thumbnail / source per video) -> a grid of inline players + an onsite search. Like the game page
4// type, it is its OWN page profile (not the marketing block-walk), emitted bits-up + responsive by construction;
5// every data field is injection-ESCAPED (hs_escape). Data-driven => the same builder ships any video site by
6// swapping the list. license_tier: ORIGINAL
7import "nx_html_sanitize.nx"
8import "nx_syscalls.nx"
9
10func vid_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd, s, n); return 0 }
11// escape an untrusted data field (hs_escape) and write it to fd.
12func vid_esc(fd: i64, src: *u8) -> i64 {
13 if (src as i64) == 0 { return 0 }
14 var sl: i64 = 0
15 while src[sl] != (0 as u8) { sl = sl + 1 }
16 let dst: *u8 = sys_mmap(sl*8 + 16)
17 let n: i64 = hs_escape(src, sl, dst, sl*8 + 15)
18 sys_write(fd, dst, n)
19 return 0
20}
21
22// build a video-gallery page to fd. titles/thumbs/urls = parallel arrays of *u8 (cast to i64); n videos.
23func vid_build(fd: i64, title: *u8, heading: *u8, titles: *i64, thumbs: *i64, urls: *i64, n: i64) -> i64 {
24 vid_w(fd, "<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\">\n" as *u8)
25 vid_w(fd, "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n" as *u8)
26 vid_w(fd, "<title>" as *u8); vid_esc(fd, title); vid_w(fd, "</title>\n<style>\n" as *u8)
27 vid_w(fd, "*{box-sizing:border-box}body{margin:0;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif;color:#e8eef6;background:#0f1115}\n" as *u8)
28 vid_w(fd, ".wrap{max-width:1100px;margin:0 auto;padding:0 18px}\n" as *u8)
29 vid_w(fd, "header{background:#11151c;padding:14px 0;position:sticky;top:0;z-index:9}.brand{font-weight:700;font-size:1.15rem;color:#fff}\n" as *u8)
30 vid_w(fd, ".search{margin:14px 0;display:flex;gap:8px}.search input{flex:1;padding:11px;border-radius:8px;border:1px solid #2a2f3a;background:#0b0e14;color:#e8eef6}\n" as *u8)
31 vid_w(fd, ".grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:18px;margin:18px 0}\n" as *u8)
32 vid_w(fd, "figure{margin:0;background:#171b22;border:1px solid #232833;border-radius:10px;overflow:hidden}video{width:100%;display:block;background:#000;aspect-ratio:16/9}\n" as *u8)
33 vid_w(fd, "figcaption{padding:10px 12px;font-size:.96rem}h2{color:#fff}footer{color:#8a93a3;padding:18px 0;text-align:center}\n" as *u8)
34 vid_w(fd, "@media(max-width:600px){.grid{grid-template-columns:1fr}}\n" as *u8)
35 vid_w(fd, "</style></head><body>\n" as *u8)
36 vid_w(fd, "<header><div class=\"wrap\"><span class=\"brand\">" as *u8); vid_esc(fd, title); vid_w(fd, "</span></div></header>\n" as *u8)
37 vid_w(fd, "<div class=\"wrap\"><form class=\"search\" role=\"search\" action=\"/search\" method=\"get\"><input type=\"search\" name=\"q\" placeholder=\"Search videos...\" aria-label=\"Search videos\"></form>\n" as *u8)
38 vid_w(fd, "<section><h2>" as *u8); vid_esc(fd, heading); vid_w(fd, "</h2><div class=\"grid\">\n" as *u8)
39 var i: i64 = 0
40 while i < n {
41 vid_w(fd, "<figure><video controls preload=\"none\" poster=\"" as *u8); vid_esc(fd, thumbs[i] as *u8)
42 vid_w(fd, "\" src=\"" as *u8); vid_esc(fd, urls[i] as *u8)
43 vid_w(fd, "\"></video><figcaption>" as *u8); vid_esc(fd, titles[i] as *u8)
44 vid_w(fd, "</figcaption></figure>\n" as *u8)
45 i = i + 1
46 }
47 vid_w(fd, "</div></section></div>\n" as *u8)
48 vid_w(fd, "<footer><div class=\"wrap\">Built by the Nishi auto-builder — sovereign video gallery</div></footer>\n" as *u8)
49 vid_w(fd, "</body></html>\n" as *u8)
50 return n
51}