A Cumulus banner script is a small PHP program that paints a few current values onto a PNG. Setup is three host facts—GD compiled in, a TrueType file PHP can read, and a decision whether to draw on every HTTP hit or on a timer—plus one Cumulus fact: a processed extra file or an uploaded realtime.txt that already exists. This dotted URL, /projects.phpggbanner, is that bring-up. It is not the mapping of which tags belong on a 468×60 strip.
The rendering and “live” claim belong on the slash twin, rendering a Cumulus station banner from web tags with PHP GD. This hostname does not rehost the historical generator. Saratoga lists CU-GD-banner 3.0 (20 October 2009) as a living-upstream ZIP under Saratoga’s notices (last checked 13 August 2026). Modern TNET Weather does not maintain that script.
Historical context
Operators wanted a status image a forum or sidebar could hot-link. Cumulus already knew how to substitute <#temp> in extra files. PHP’s GD extension rasterized a handful of those values. Typical inputs were a processed extra file or the optional realtime.txt packet. The script sat on the web host. Cumulus wrote the file; PHP allocated a truecolor image and emitted PNG.
GD is a PHP extension, not a TNET download. Confirm it on the host before you unpack any banner ZIP. The PHP GD manual is the reference (last checked 13 August 2026). TrueType drawing uses imagettftext, which needs FreeType in that same GD build.
Enable GD and confirm formats
On the web host, open phpinfo() or run gd_info() in a throwaway script you delete afterward.
You need:
- A GD section at all (
extension=gdinphp.ini, or the distro packagephp-gd). - PNG support, because a status strip should not be JPEG if you can avoid recompression.
- FreeType support, if you intend unit glyphs (
°,µin some fonts, or even a reliableC/Fat small sizes).
If GD is absent, every banner script fails with a fatal on imagecreatetruecolor. That is a host ticket, not a Cumulus setting. If GD is present but FreeType is not, you can still call imagestring with built-in bitmap fonts; those fonts are weak at °C and hPa. Fix FreeType before you tune layout.
Do not enable GD by copying a php_gd.dll from an unlabeled archive. Use the PHP build’s own extension.
Memory: GD allocates in ways that may not count against memory_limit the same way depending on whether PHP uses the bundled GD. A 468×60 truecolor image is small. A mistaken loop that loads a photographic background at camera resolution is not. Cap background files in the config.
TrueType path
Banner scripts of this family almost always have a configuration constant for the .ttf file, not JpGraph’s TTF_DIR. Point it at an absolute path.
Prefer a font directory outside the web root so visitors cannot download the TTF. The PHP user must be able to read the file. Relative paths fail when cron’s working directory is not the script directory—the same class of bug as JPGraph includes.
Use a font you are licensed to embed in a generated PNG. Do not lift a TTF out of a recovered skin ZIP without reading its license. Test with a string that includes the degree sign and your unit tokens. A box substituted for ° means the font lacks the glyph or the path is wrong.
If you serve both metric and imperial banners, that is still one font and two processed source files (or one source with unit tokens already in the packet). Do not install two PHP copies to change C to F.
Input file: processed tags, not a live pull
GD does not speak web tags. Cumulus must substitute them before the drawing calls.
The clean path: an extra-web-file template that assigns PHP variables from tags ($temp = '<#temp rc=y>'; and neighbors), with Process ticked, uploaded to the host on the standard or realtime interval. The banner script requires that local file. MX documents tags on the Webtags page (last checked 13 August 2026). Use rc=y where you need a script-friendly decimal point.
The alternative: parse uploaded realtime.txt. Enable generation and FTP first; default is off. Classic field 3 is temperature, 15 is the temperature unit token, 2 is hh:mm:ss. Later MX appended fields. Pin the Cumulus version in the banner config.
Use one source. Do not have the script fetch Cumulus over HTTP inside the image request. That doubles failure modes (logger down and host DNS) and turns every forum refresh into a request storm toward the logger.
The TNET web-tags project is the extra-file pattern behind many templates. Wire that include first; then point the banner at it.
Cron versus on-demand
Two runtimes, one drawing function.
On-demand. banner.php is the img src. Every hit allocates an image, paints, and streams PNG. Setup is simple. Cost is CPU on every embed, including scrapers and signature caches. It also trains the URL to look like a live API. It is not. The pixels are a derived rendering of the last file on disk. If you choose on-demand, still send Cache-Control with a max-age on the order of the Cumulus interval (RFC 9111), and key any internal cache to the source file’s mtime.
Cron (or scheduled HTTP). A timer writes banner.png next to the script. The public img src is the static PNG. Setup needs a scheduler: host cron, or Toolbox HTTP Requests calling the generator URL if the shared host has no cron (Toolbox, last checked 13 August 2026). Match the timer to the Cumulus interval, not to one second. Fine Offset / EasyWeather-class stations often update on the order of 48 seconds; a one-second banner cron is cosmetic.
Prefer cron when the banner is hot-linked from many forums. Prefer on-demand only while you are testing fonts and layout, then switch to a written PNG for production. Do not run both writers against the same output path.
Permissions: the PHP user must be able to write banner.png. World-writable 777 is not a setup step; it is an incident. Create the file once with the correct owner, or write into a dedicated directory with a sticky, narrow mode.
The gallery disk-layout article is where example PNGs and metric/imperial folders belong. Generated output should not overwrite the example tree.
What not to configure
- Do not pass the font path, the source path, or the output path on the query string. That is a file-write gadget, not a banner.
- Do not point
imgsrcat a PHP file that also sends HTML (BOM, notices, a leftover<br>). One byte of warning text beforeheader('Content-Type: image/png')corrupts the image. Log errors to a file, not to stdout. - Do not share a cache directory with JPGraph without separate names. A graph timeout is not a banner timeout.
- Do not treat a recovered ZIP as configured. You still need GD, a font path, and an input file on this host.
The analog thermometer is a different canvas and a different script. Do not reuse the banner cron to write both unless each has its own output filename.
Practical checklist
- Confirm GD, PNG, and FreeType; delete the phpinfo probe when done.
- Place a licensed TTF at an absolute, readable path outside the web root if possible.
- Process a webtag extra file (or enable
realtime.txtupload) andrequireit locally. - Choose cron (static PNG) or on-demand (script
src); do not mix writers. - If cron is unavailable, schedule an HTTP hit from Toolbox, not from visitor traffic.
- Set output permissions for the PHP user only.
- Cache or
max-ageon the order of the Cumulus interval, keyed to sourcemtime. - Do not fetch the logger over HTTP from inside the image request.
Modern relevance
MX JSON and HTTP interfaces obtain the same scalars another way. A GD banner remains a human-facing summary for places that still want a PNG without JavaScript. The setup duties did not move: extension, font path, scheduler, local input file.
Choosing which atmospheric fields survive a 60-pixel height is a grouping problem. TNET’s public account of evidence labels is how the service works. Freshness of source files is data sources and methodology. This page stays on installing the painter.
The Cumulus hub indexes related projects.
Sources
- PHP image processing and GD (last checked 13 August 2026)
- PHP imagettftext
- Cumulus Wiki: Webtags (last checked 13 August 2026)
- Cumulus Wiki: realtime.txt (last checked 13 August 2026)
- Cumulus Wiki: Toolbox (last checked 13 August 2026)
- Saratoga Weather: Legacy Scripts (last checked 13 August 2026)
- RFC 9111: HTTP Caching
- TNET: how the service works