Template variable list#122
Merged
Merged
Conversation
1672f43 to
152cabd
Compare
Statically analyze a template without rendering it and return the structural schema of the variables, collections and nested objects it references. Useful to validate a caller's model against the template's expectations, or to generate a skeleton model to fill in. - New public API: DocxTemplate.GetTemplateSchema() -> TemplateSchema, with TemplateSchemaNode / TemplateNodeKind (Scalar/Object/Collection). - The schema is the union over all branches (if/else, switch/case, every loop body); each block type contributes via CollectSchema. - Split ProcessNode into BuildBlockTree (model-independent) + RenderNode so GetTemplateSchema can build the block tree once, cache it, and let a subsequent Process() render from the cache on the same instance. The former "destructive, do not call Process afterwards" contract is gone. - README documents the feature and its known limitations.
152cabd to
3aad106
Compare
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.
Template Schema Inspection —
GetTemplateSchema()Adds a static analysis API that inspects a template without rendering it and returns the structural schema of the variables, collections and nested objects the template references. Callers can validate their model against the template's expectations up front, or generate a skeleton model to fill in.
Public API
DocxTemplate.GetTemplateSchema()→TemplateSchemaTemplateSchemaRoots= top-level models (case-insensitive), matching theBindModelprefixes.TemplateSchemaNodeName,Kind,Properties(objects),ItemSchema(collections).TemplateNodeKindScalar|Object|Collection.What is covered
The schema is collected from the block tree and covers:
{{x}},{{(a + b)}}) — expression operands parsed viaSchemaExpressionParser.{{#items}}…{{/items}}) including nested item schemas and references to outer models.if/else),switch/case/default— reported as the union of all branches, so a caller must be prepared to bind anything reachable at runtime.Each block type contributes through a new
CollectSchema(SchemaBuilder)method (base inContentBlock, overrides inLoopBlock,ConditionalBlock,SwitchBlock/CaseBlock,RangeLoopBlock,IgnoreBlock,InlineKeyWordBlock).Schema and rendering on the same instance
GetTemplateSchema()builds the same block tree the renderer uses (which mutates the XML). To keepProcess()working afterwards, the pipeline was split into two phases:BuildBlockTree— pre-process + marker isolation + loop expansion → model-independent.RenderNode— variable replacement + extensions +loop.Expand+ cleanup → model-dependent.ProcessNode=BuildBlockTree+RenderNode(unchanged behaviour for existing callers).GetTemplateSchema()caches the built block tree per node (header/body/footer) and the resultingTemplateSchema;Process()then renders from the cache instead of rebuilding the already-extracted tree. The previous "destructive — do not callProcessafterwards, reopen the stream" contract is removed.Guards / idempotency:
GetTemplateSchema()call returns the cached result.GetTemplateSchema()afterProcess()throws a clear exception.Process()without a prior schema call, or called twice, behaves as before.Known limitations (documented on
TemplateSchema):tmpl): the referenced sub-template is a runtime template string, invisible to static analysis.:dyntable): only the collection itself is reported, not its runtime-defined rows/columns.props["key"]): the key is not statically known and is not reflected in the schema.Tests
TemplateSchemaTest,SchemaBuilderTest,SchemaExpressionParserTest.ComplexTemplateTest.ProcessComplexTemplateextended to callGetTemplateSchema()thenProcess()on the same instance.ProcessComplexTemplate(3/3) pass on net8.0 / net9.0 / net10.0.Docs
README gains a Template Schema Inspection section and a feature bullet.