Move user-facing strings and QR URLs into config.yml - #545
Open
joelhawksley wants to merge 9 commits into
Open
Conversation
Add a build-time generator (scripts/generate_branding.py) that reads config.yml and emits include/branding.h (BRAND_STR_* / URL macros) and the on-screen QR bitmaps (src/wifi_connect_qr.h, wifi_failed_qr.h) for the configured URLs. All user-facing display strings in display.cpp now come from these macros instead of inline literals. Defaults reproduce the stock TRMNL strings and URLs exactly, so an unmodified config.yml produces identical firmware. The generator runs as a PlatformIO pre-build script; QR regeneration needs the optional 'segno' package and falls back to the committed bitmaps when it is absent.
Install segno on demand in the branding generator instead of skipping QR regeneration when it is absent, and declare it in scripts/requirements.txt.
joelhawksley
marked this pull request as ready for review
August 8, 2026 01:11
Localization outputs are build artifacts and customization is confined to a single git-ignored overlay, so a white-label fork never edits a tracked file and pulling upstream never conflicts. - generate_branding.py deep-merges an optional config.local.yml over config.yml. - Stop tracking the generated headers (branding.h, wifi_connect_qr.h, wifi_failed_qr.h); they are regenerated at build time and git-ignored. - Add config.local.yml.example and document the override flow in config.yml. - CI: generate headers before build/test, and add a branding-config job that proves an override changes output without dirtying any tracked file. Defaults still reproduce the stock TRMNL strings/URLs byte-identically.
Extend the config-driven, git-ignored-artifact model to the captive portal and the e-paper logos so a white-label fork customizes them without editing tracked files. - generate_branding.py now also generates lib/wificaptive/src/WifiCaptivePage.h from the portal HTML/SVG, applying optional strings.portal_* / accent_color overrides. With no overrides it gzips the raw source, so the page content is unchanged (line endings normalize to LF). WifiCaptivePage.h is now a git-ignored build artifact; the manual portal/convert.py is removed. - Optional images.* config converts 1-bit PNGs to git-ignored *.local.h logo sidecars (pillow auto-installed on demand). The committed stock logo headers include them via __has_include, so stock builds are unchanged and need no pillow, while custom logos never modify a tracked file. - config.yml / config.local.yml.example document portal + image overrides. - CI branding-config job also verifies a portal_title override changes the generated page without dirtying tracked files.
…lder
- Portal HTML now uses {{accent_color}} placeholders (default #F86527), so the
captive-portal accent is themable via branding.accent_color. Stock output is
byte-identical after substitution.
- wifi.ap_ssid_prefix drives the setup hotspot SSID via a git-ignored
lib/wificaptive/src/wifi_ssid.local.h sidecar that WifiCaptive.h includes with
a "TRMNL" fallback, so the library needs no access to include/branding.h.
- strings.portal_api_placeholder rebrands the custom-server input hint.
- config.yml documents the new keys; defaults reproduce stock verbatim.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Moves the firmware's user-facing display text and the on-screen QR code URLs into a single
config.yml, generated into headers at build time. Defaults reproduce the stock TRMNL strings and URLs exactly, so an unmodifiedconfig.ymlbuilds identical firmware.This makes the firmware straightforward to localize the firmware without editing C++, such as for device deployments using Terminus, etc.
How it works
scripts/generate_branding.pyruns as a PlatformIO pre-build script and emits:include/branding.h— string / URL#definemacros.src/wifi_connect_qr.h,src/wifi_failed_qr.h— 66×66 G5 QR bitmaps (same formatbbep.loadG5Imagealready consumes, so no display code changes).Notes
include/branding.hand the QR headers are generated; added to.clang-format-ignorealongside the existing generated headers.trmnl,trmnl_4clr,TRMNL_X,TRMNL_X_E1003,seeed_reTerminal_E1001/E1002,WAVESHARE_397).Testing
Builds succeed for
trmnl(OG),seeed_reTerminal_E1001, andTRMNL_X_E1003(X-class), with the generator running as a pre-build step. The QR bitmaps were verified to round-trip to the encoder's QR matrix.clang-formatpasses.