Load and tokenize a localized text template¶
This operation loads a text template — from a configured filesystem directory or from an assembly's embedded manifest resources — for a requested culture, then hands the loaded text to the shared base class to record the original text and parse {token}-style placeholders for later replacement. Both concrete loaders (clsFileResourceManager and clsAssemblyResourceManager) implement the same culture fallback chain independently, each against its own storage medium.
| Field | Value |
|---|---|
| Operation ID | OP-RES-01 |
| Trigger | Caller instantiates clsFileResourceManager (with a resource directory) or clsAssemblyResourceManager (with an Assembly) and calls LoadResource(inResourceName, inTemplateExtension, inCultureCode) (or the single-argument overload, which defaults the culture code to the current UI culture) |
| Inputs | Resource name, template file extension (defaults to html on the base overload), culture code, and — for the file-based loader — the configured resource directory, or — for the assembly-based loader — the target Assembly and an optional namespace override |
| Outputs | Populated Text and ReplacedText on the loader instance, and a parsed Tokens list; no content is loaded and prior state is left unchanged if no matching file/resource is ever found |
| Primary components | clsFileResourceManager.LoadResource, clsAssemblyResourceManager.LoadResource, clsResourceManager.Initialize, clsResourceManager.LoadTokens |
| Entry point | Resources\SAIF.Resources\clsFileResourceManager.vb, Resources\SAIF.Resources\clsAssemblyResourceManager.vb, Resources\SAIF.Resources\clsResourceManager.vb |
Steps¶
- Select a loader. The caller instantiates either
clsFileResourceManager(constructed with a resource directory, trimmed of a trailing backslash) orclsAssemblyResourceManager(constructed with anAssembly, defaulting to the executing assembly). - Build the exact-culture resource identifier.
- File loader: builds the path
{ResourceDirectory}\{inResourceName}_{inCultureCode}.{inTemplateExtension}(omitting the culture segment entirely when the culture code is empty). - Assembly loader: resolves the namespace (the supplied
inNamespace, or the assembly's own name when none is supplied) and builds the manifest resource name{namespace}.{inResourceName}_{inCultureCode}.{inTemplateExtension}(again omitting the culture segment when empty). - Attempt to load the exact-culture resource.
- File loader: checks
IO.File.Existsfor the built path. - Assembly loader: calls
Dll.GetManifestResourceStreamfor the built resource name. - Fall back to a two-letter culture if the exact match is not found. If the requested culture code is longer than two characters, the loader retries steps 2–3 using only the first two characters of the culture code (for example,
en-USretries asen). - Fall back to no culture suffix if the two-letter match is also not found. If the (possibly already-shortened) culture code is still non-empty, the loader retries steps 2–3 with an empty culture code, which resolves to the unsuffixed default resource name.
- If no exact, two-letter, or unsuffixed resource exists, the loader returns without loading any content —
Text,ReplacedText, andTokensremain at their prior (or initial empty) state. - Read the found content.
- File loader: opens an
IO.StreamReaderon the resolved path and reads the full text withReadToEnd. - Assembly loader: opens the manifest resource stream and reads the full text with
ReadToEndthrough anIO.StreamReader. - Initialize the shared state. The loader calls
clsResourceManager.Initialize(text), which stores the raw text inText, copies it intoReplacedText, and callsLoadTokens(). - Parse simple tokens.
LoadTokensmatches the pattern{token-start}(?<token>[a-zA-Z0-9_]*){token-end}(delimiters default to{and}) against the loaded text and adds aTokenentry (name, pattern, raw value) for every match. - Parse content-bearing tokens.
LoadTokensthen matches the pattern{token-start}(?<token>[a-zA-Z0-9_]*):(?<content>.*){token-end}for colon-delimited tokens and adds aTokenentry that also records the captured content, using a token-specific pattern for later replacement. - Return the token list.
LoadTokensreturns the populatedTokenslist, now available on the loader instance for use by Replace a token in loaded text.
Process flow¶
The following diagram visualizes the culture fallback and tokenization flow shared by both concrete resource loaders.
flowchart TD
Start([Caller calls LoadResource]) --> BuildExact[Build exact-culture path<br>or manifest resource name]
BuildExact --> FoundExact{Resource found?}
FoundExact -->|Yes| Read[Read full template text]
FoundExact -->|No| TwoLetter{Culture code<br>longer than 2 chars?}
TwoLetter -->|Yes| BuildTwo[Retry with first<br>two characters]
BuildTwo --> FoundTwo{Resource found?}
FoundTwo -->|Yes| Read
FoundTwo -->|No| NoSuffix{Culture code<br>still non-empty?}
TwoLetter -->|No| NoSuffix
NoSuffix -->|Yes| BuildDefault[Retry with empty<br>culture code]
BuildDefault --> FoundDefault{Resource found?}
FoundDefault -->|Yes| Read
FoundDefault -->|No| EndNoLoad([Return without loading;<br>prior state unchanged])
NoSuffix -->|No| EndNoLoad
Read --> Init[Initialize stores Text<br>and ReplacedText]
Init --> Tokens[LoadTokens parses<br>simple and content tokens]
Tokens --> End([Tokens available for replacement])
Failure and edge-case behavior¶
- If neither the exact-culture, two-letter-culture, nor unsuffixed resource exists,
LoadResourcereturns silently without loading content or raising an error;Text,ReplacedText, andTokensretain whatever state they held before the call. - The two-letter fallback only triggers when the supplied culture code is longer than two characters, so a culture code already at two characters (e.g.,
en) skips directly to the unsuffixed fallback if the two-letter form is not found. - An empty culture code on the initial call goes straight to the unsuffixed resource name, since the fallback conditions for both the two-letter and no-suffix retries require a non-empty starting culture code.
- The assembly loader resolves its own assembly's name as the default namespace whenever the caller omits
inNamespace, so callers embedding resources under a different namespace must supply it explicitly. - Both loaders implement the identical three-tier fallback chain independently in their own
LoadResourceoverrides rather than sharing a common fallback helper.*
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Related documentation¶
Sources¶
Resources\SAIF.Resources\clsResourceManager.vbResources\SAIF.Resources\clsFileResourceManager.vbResources\SAIF.Resources\clsAssemblyResourceManager.vb