Skip to content

Switch batch-print variable syntax from :name: to {{name}} - #25

Merged
szrudi merged 3 commits into
mainfrom
feature/curly-variable-syntax
May 17, 2026
Merged

szrudi merged 3 commits into
mainfrom
feature/curly-variable-syntax

Conversation

@szrudi

@szrudi szrudi commented May 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Replace the :name: placeholder syntax (1.6.0–1.6.1) with {{name}} to stop false-matching legitimate :foo:-shaped content in QR codes, barcodes, and label text.

Why

`:name:` collides with all sorts of normal content people would actually want to encode:

  • URLs: `http://example.com:8080/path\`
  • IPv6 literals: `fe80::1`
  • Host:port: `host:8080:path`
  • Generic key:value strings, base64 padding, error messages, Vue/Angular bindings, etc.

`{{name}}` collides with Handlebars / Jinja / Mustache, which nobody is encoding inside a label. It's also the syntax most people recognise instantly because of those templating engines.

Scope

  • Two regex literals: `client/src/lib/variables.ts` and `server/app.py:_VAR_PATTERN`.
  • The "+ Add Variable" button's placeholder generator.
  • The variable-rename heuristic's placeholder rewrite.
  • Test fixtures (`useLabelStore.test.ts`, `test_batch.py`).
  • Docs: README, ARCHITECTURE (kept a one-line breadcrumb about the prior syntax).
  • Release notes for 1.6.2 with a clear migration instruction.

The detection / rename / substitution / cut-mark machinery is unchanged past the regex.

Migration

Re-save any label `.json` files that contain `:varname:` placeholders, replacing them with `{{varname}}`. Old placeholders print literally rather than being substituted. The feature shipped two days ago in 1.6.0, so the install base is essentially the project author — release note in v1.6.2 calls this out.

Version

`1.6.2` (PATCH). Strictly speaking this is a breaking label-format change, but the user-facing fix is "find and replace `:name:` with `{{name}}` in your saved files" and the install base is tiny. A MAJOR bump would be theatre.

Test plan

  • Server: 212 pytest tests pass (existing test_batch.py covers substitution, no new tests needed — the regex is the only behavioural change and the existing assertions exercise it via the new syntax)
  • Client: 52 vitest tests pass (rename heuristic, store actions all re-run against the new syntax)
  • Docker build + smoke CI will run on PR
  • Hardware sanity check on hector — single label with a `{{name}}` placeholder in a QR widget should now print substituted, while a literal `:label:` in QR content should pass through unchanged

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates batch-print variable placeholders from the colon-delimited form (:name:) to double-curly braces ({{name}}) across the client, server, tests, and documentation to avoid false matches in real-world QR/barcode/text content that commonly contains colons.

Changes:

  • Switched variable detection/substitution regexes in both client and server to {{varname}} with support for hyphenated names ([\w-]+).
  • Updated the client UI that inserts placeholders and the rename heuristic that rewrites placeholders across widgets/batch rows.
  • Refreshed tests, docs, release notes, and bumped the app version to 1.6.2.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
server/app.py Updates server-side placeholder regex and documentation for widget substitution.
server/tests/test_batch.py Updates fixtures to {{name}} and adds coverage for hyphenated variable names.
client/src/lib/variables.ts Updates client-side detection/substitution regex to {{varname}} with hyphen support.
client/src/state/useLabelStore.ts Updates rename heuristic placeholder rewrite logic to operate on {{name}}.
client/src/state/useLabelStore.test.ts Updates tests for rename/migration behavior and adds a hyphenated-name rename test.
client/src/components/BatchPanel.tsx Updates “+ Add Variable” placeholder insertion and help text to {{varname}}.
README.md Updates batch-print documentation/examples to the new placeholder syntax.
docs/ARCHITECTURE.md Documents the new syntax, rationale, and updates the rename-heuristic example.
package.json Bumps version from 1.6.1 to 1.6.2.
.github/release-notes/v1.6.2.md Adds release notes and explicit migration guidance for the syntax change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread client/src/state/useLabelStore.ts Outdated
szrudi added a commit that referenced this pull request May 17, 2026
Per Copilot review of PR #25: the inline comment said "Variable
names match \w+" but the regex now accepts [\w-]+. The conclusion
(no escaping needed) still holds — hyphen is only a regex
metacharacter inside character classes — but the comment should
describe the actual class.

Also bumps to 1.6.3 since the version-display PR will land first
as 1.6.2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
szrudi and others added 3 commits May 17, 2026 12:15
The previous :name: form (1.6.0–1.6.1) caused false matches in
legitimate QR and barcode content — URLs, IPv6 literals, port numbers
in host:port:path strings, key:value pairs, base64 padding. Switch to
double-brace Handlebars/Jinja/Mustache-style placeholders to drop the
collision risk to near zero and align with how every other template
language people have seen looks.

What changed:
- VAR_REGEX on both client (client/src/lib/variables.ts) and server
  (server/app.py:_VAR_PATTERN) now matches \{\{(\w+)\}\}.
- "+ Add Variable" generator in BatchPanel produces {{var1}}, {{var2}}.
- The variable-rename heuristic's placeholder rewrite uses the new
  syntax too.
- Tests, README, and ARCHITECTURE refreshed; ARCHITECTURE keeps a one-
  line note about the prior syntax so the change is traceable.

Migration: re-save any label JSON files that contain :varname:
placeholders, replacing them with {{varname}}. Old placeholders will
print literally rather than being substituted. Released two days ago,
so the install base is tiny — release notes spell this out.

Bumps to 1.6.2 (technically a label-format breaking change, but the
feature is so fresh and the user-facing fix is so simple that a PATCH
release with a clear migration note is the right move).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same review pass as the curly-brace switch — Rudi asked whether the
regex covered hyphens. \w doesn't, so {{first-name}} would have
printed literally. Broadened both sides to [\w-]+:

- client/src/lib/variables.ts:  /\{\{([\w-]+)\}\}/g
- server/app.py:_VAR_PATTERN:   r"\{\{([\w-]+)\}\}"

The rename heuristic already handles arbitrary detected names; new
tests confirm hyphenated names round-trip through both the server
substitution path (test_batch.py) and the client rename migration
(useLabelStore.test.ts). ARCHITECTURE updated to document the allowed
character class.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per Copilot review of PR #25: the inline comment said "Variable
names match \w+" but the regex now accepts [\w-]+. The conclusion
(no escaping needed) still holds — hyphen is only a regex
metacharacter inside character classes — but the comment should
describe the actual class.

Also bumps to 1.6.3 since the version-display PR will land first
as 1.6.2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@szrudi
szrudi force-pushed the feature/curly-variable-syntax branch from fa9896a to 125ab18 Compare May 17, 2026 10:16
@szrudi
szrudi merged commit 9ecc4d0 into main May 17, 2026
4 of 5 checks passed
@szrudi
szrudi deleted the feature/curly-variable-syntax branch May 18, 2026 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants