inc/layout.php
Snapshot 2026.09.17-a2894de (current) · 72 lines · 6,690 bytes · tree · plain text
SHA-256
528ddb80bc30a1b40abcd9f44ff3e4024382137f3c93f39b91754e0f32409ea6| 1 | <?php |
| 2 | /* Districthive Research Labs: header and footer, in the same family as the AI |
| 3 | operations dashboard (same tokens, same top bar, same tab row). Installed at |
| 4 | research/inc/layout.php by the AI dashboard's deploy hook when that folder |
| 5 | is writable; the source lives at deploy/research/layout.php in districthive/ai. */ |
| 6 | require_once __DIR__.'/helpers.php'; |
| 7 | |
| 8 | /* Pages installed by the AI dashboard's deploy hook live beside this file, because |
| 9 | research/pages is not writable by it. The router requires this file first, so a |
| 10 | known page is served from here and the request ends. */ |
| 11 | if (!defined('RESEARCH_INC_PAGE') && preg_replace('/[^a-z]/', '', $_GET['p'] ?? '') === 'species' && is_file(__DIR__.'/species.php') && !is_file(__DIR__.'/../pages/species.php')) { |
| 12 | define('RESEARCH_INC_PAGE', 'species'); |
| 13 | require __DIR__.'/species.php'; |
| 14 | exit; |
| 15 | } |
| 16 | |
| 17 | function page_header(string $title, string $active=''): void { |
| 18 | $data=[['live','Live'],['wellness','Wellness programme'],['birds','Birds & Soundscape'],['marine','Marine'],['water','Lagoon Water'],['aquifer','Aquifer'],['weather','Weather'], |
| 19 | ['darksky','Dark Sky'],['cameras','Cameras'],['footfall','Footfall'],['resources','Resources'],['wellbeing','Wellbeing'],['heritage','Heritage'], |
| 20 | ['construction','Construction'],['control','Control site (reference shore)']]; |
| 21 | $transparency=[['health','Health'],['faults','Faults & Gaps'],['vault','Raw Vault'],['log','Activity Log'],['methods','Instruments'],['apidocs','API'],['about','About']]; |
| 22 | $inData=in_array($active, array_column($data,0), true) && $active!=='live'; |
| 23 | $inTrans=in_array($active, array_column($transparency,0), true); |
| 24 | $logo=file_exists(__DIR__.'/../assets/logo.svg') ? file_get_contents(__DIR__.'/../assets/logo.svg') : ''; |
| 25 | echo '<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">'; |
| 26 | echo '<meta name="theme-color" content="#22c55e"><link rel="icon" type="image/png" sizes="32x32" href="assets/favicon-32.png"><link rel="icon" type="image/png" sizes="16x16" href="assets/favicon-16.png"><link rel="icon" type="image/png" sizes="192x192" href="assets/icon-192.png"><link rel="apple-touch-icon" href="assets/touch-icon.png"><title>'.h($title).' | '.h(SITE_NAME).'</title>' |
| 27 | .'<meta property="og:site_name" content="Districthive"><meta property="og:type" content="website"><meta property="og:title" content="'.h(SITE_NAME).'">' |
| 28 | .'<meta property="og:description" content="The Skerðingsstaðir Experiment. Open field research from The Outpost, Districthive\'s Human Recharging Station, published as it happens.">' |
| 29 | .'<meta property="og:url" content="https://districthive.com/research/"><meta property="og:image" content="https://districthive.com/research/assets/share.png">' |
| 30 | .'<meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:image" content="https://districthive.com/research/assets/share.png">' |
| 31 | .'<link rel="stylesheet" href="assets/style.css"></head><body><div class="wrap">'; |
| 32 | echo '<header class="topbar"><h1><a href="index.php"><span class="logo" aria-hidden="true">'.$logo.'</span>Research Labs</a></h1>'; |
| 33 | echo '<span class="clock">'.gmdate('Y-m-d H:i').' UTC</span><span class="who">open field data · live</span></header>'; |
| 34 | echo '<nav class="sections" aria-label="Sections">'; |
| 35 | echo '<a href="index.php?p=live"'.($active==='live'?' aria-current="page"':'').'>Live</a>'; |
| 36 | echo '<details><summary'.($inData?' class="on"':'').'>Data</summary><div class="menu">'; |
| 37 | foreach($data as [$slug,$label]){ if($slug==='live') continue; echo '<a href="index.php?p='.$slug.'"'.($slug===$active?' aria-current="page"':'').'>'.h($label).'</a>'; } |
| 38 | echo '</div></details>'; |
| 39 | echo '<a href="index.php?p=species"'.($active==='species'?' aria-current="page"':'').'>Species</a>'; |
| 40 | echo '<a href="index.php?p=correlate"'.($active==='correlate'?' aria-current="page"':'').'>Correlate</a>'; |
| 41 | echo '<a href="index.php?p=ask"'.($active==='ask'?' aria-current="page"':'').'>Ask Grímnir</a>'; |
| 42 | echo '<a href="index.php?p=code"'.($active==='code'?' aria-current="page"':'').'>Code</a>'; |
| 43 | echo '<details><summary'.($inTrans?' class="on"':'').'>Transparency</summary><div class="menu">'; |
| 44 | foreach($transparency as [$slug,$label]){ echo '<a href="index.php?p='.$slug.'"'.($slug===$active?' aria-current="page"':'').'>'.h($label).'</a>'; } |
| 45 | echo '</div></details>'; |
| 46 | echo '<a href="https://districthive.com/ai_discover/" target="_blank" rel="noopener">AI operations</a>'; |
| 47 | echo '<a href="'.h(MAIN_SITE).'" target="_blank" rel="noopener">Discover DH</a>'; |
| 48 | echo '</nav><script>document.addEventListener("click",function(e){document.querySelectorAll("nav.sections details[open]").forEach(function(d){if(!d.contains(e.target)||e.target.closest("a"))d.removeAttribute("open");});});</script><main>'; |
| 49 | } |
| 50 | |
| 51 | /* WEB-001: the version stamp of the code snapshot that rendered this page (inc/snapshots/current.json), or '' before the first snapshot. */ |
| 52 | function code_version(): string { |
| 53 | static $v=null; |
| 54 | if($v===null){ $j=@file_get_contents(__DIR__.'/snapshots/current.json'); $d=$j?json_decode($j,true):null; $v=is_array($d)&&preg_match('/^\d{4}\.\d{2}\.\d{2}-[0-9a-f]{7}$/',(string)($d['version']??''))?(string)$d['version']:''; } |
| 55 | return $v; |
| 56 | } |
| 57 | /* A small "code" link that resolves to a file (and a function's line range) in the snapshot that rendered this page. */ |
| 58 | function code_link(string $file, ?string $fn=null, string $label='code'): string { |
| 59 | $v=code_version(); if($v==='') return ''; |
| 60 | return '<a class="codelink" href="index.php?p=code&v='.h($v).'&f='.rawurlencode($file).($fn!==null?'&fn='.rawurlencode($fn):'').'" title="the code that produced this, platform code '.h($v).'">'.h($label).'</a>'; |
| 61 | } |
| 62 | function page_footer(): void { |
| 63 | echo '</main><footer class="foot">'; |
| 64 | echo '<div class="footline">'.h(SITE_TAGLINE).'</div>'; |
| 65 | echo '<div class="footline"><a href="'.h(MAIN_SITE).'">districthive.com</a> · <a href="'.h(PROSPECTUS).'">prospectus</a> · <a href="https://districthive.com/ai_discover/">AI operations</a> · <a href="index.php?p=about">data licence & citation</a></div>'; |
| 66 | echo '<div class="footco">'.h(CO_IS).'</div>'; |
| 67 | echo '<div class="footco">'.h(CO_EE).'</div>'; |
| 68 | $cv=code_version(); |
| 69 | echo '<div class="footco">© '.date('Y').' Districthive · open research data, openly licensed · platform bespoke, documented for scrutiny'.($cv!==''?' · <a href="index.php?p=code&v='.h($cv).'">platform code '.h($cv).'</a>':'').'</div>'; |
| 70 | echo '</footer></div><script src="assets/app.js"></script></body></html>'; |
| 71 | } |
| 72 | |
Lines can be cited as inc/layout.php L120-L140, platform code 2026.09.17-a2894de; add #L120-L140 to this page's address to highlight them. Source shown for scrutiny of the research platform. All rights reserved. Not offered as installable software.