For the most common case, nothing special is needed: a developer can just type “Seitenübersicht” — or any text in their own language — straight into your prompt today. It’s stored as ANSI bytes in the .app, generates as ANSI source, and prints correctly whenever the machine’s codepage covers the characters — most of the time German, French, Spanish, Scandinavian, Eastern-European text on the matching codepage: type it in, done. The one thing the report needs for wide-correct output is the UNICODE attribute, and on a UNICODE report those ANSI entries widen correctly through the active codepage at print time.
The template language needs nothing new either. The whole AppGen chain (template files, the registry, prompt values stored in the .app, and the generated source) is byte/ANSI storage end to end, by design: generated source is always ANSI.
When the typed in text is outside the codepage (Greek on a Western machine, CJK, symbols) Unicode goes through the chain as an ordinary Clarion wide string literal, whose spelling is plain ASCII.
The literal form is U’…'; inside it, the metachars take decimal UTF-16 code point values (with <n{r}> repeating a value, and << for a literal <). So Greek “Σελίδα” is:
U’<931,949,955,943,948,945>’
and a mixed placekeeper like "Page — " is U’Page <8212> '. Characters above FFFFh get written as their surrogate pair, or built at runtime with the two-parameter CHR(codepoint,1). Because the spelling is ASCII, it survives the prompt entry, the .app, TXA export/import, and generation without any encoding concerns.
Two things to handle on the template side:
1. Emit the prompt value as an expression, not inside quotes. The U prefix sits outside the quote marks, so a template that wraps the entry in quotes can never receive a wide literal. So for the page-of-pages placekeeper:
#PROMPT(‘Page-of-pages text (expression):’,@S80),%PageOfPagesText,DEFAULT(‘’‘Page ‘’’)
Note: it’s the expression 'Page ', quotes included (doubled per template-source rules), because the entry is now expression-valued. The generation side emits the symbol raw:
#AT(%AfterOpeningReport)
?PageOfPages{PROP:Text} = %PageOfPagesText & ’ ’ & PAGENO()
#ENDAT
A developer who wants plain English enters 'Page ’ and the generated line is:
?PageOfPages{PROP:Text} = 'Page ’ & ’ ’ & PAGENO()
A developer who wants Greek enters U’<931,949,955,943,948,945> ’ and generation produces:
?PageOfPages{PROP:Text} = U’<931,949,955,943,948,945> ’ & ’ ’ & PAGENO()
2. The target report needs the UNICODE attribute. Wide text only survives onto the page on a REPORT,UNICODE report (EMF pages). On a report without the UNICODE attr the runtime posts error 546 once and then prints narrowed text— deliberate, so a long job isn’t killed by a diagnostic/error.
If your template ships to mixed compiler versions: the new compiler defines the flag _USTRING_, and the older ones don’t. Generate wide-Ustring code inside a COMPILE(‘…’, _USTRING_) block (older compilers OMIT it) and your template stays valid across both.