The documentation comes from the Markdown files in the source code, so is always up-to-date but available only in English. Enjoy!
This is the available syntax for writing Word and Email templates.
The main benefit of Signum Templating infrastructure is that the template defines not only the look of the report, but also the query.
If you make a mistake you'll typically find it at Upload-template-time. Not when running it. And if the entities of models change the synchronizer will fix the templates.
@[TotalAmount]
: Access column TotalAmount
in the Query (implicit query provider)@[q:TotalAmount]
: Access column TotalAmount
in the Query (explicity query provider)@[Customer.Name]
: Access Customer
column in the Query and joins with customer table to get the Name
@[Entity.CreationDate]
: Access CreationDate
field in the main entity that is not shown by default in the query.@[m:ShortAddress]
: Access property ShortAddress
in the model (EmailModel or WordModel)@[m:HtmlToWord(Content)]
: Calls method HtmlToDocx
in the WordModel, useful for complex computations or for translating Html to Word markup. public static IEnumerable<OpenXmlElement> HtmlToWord(string html, WordTemplateParameters p)
{
return HtmlToWordConverter.HtmlToWord(html, p);
}
@[g:Now]
: Access keys globaly registered for every template (company address, date time, etc..)@[t:Product.Name]
: Joins with Product table, gets the name, and the TranslatedInstanceEntity
name if exists.@[TotalAmount:0.00]
: (Custom)[https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx]@[TotalAmount:C]
: (Standard)[https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx]Allows to conditionally show elements depending on a condition.
* @if[IsCancelled]
* Your account is cancelled
* @else
* Your account is accepted
* @endif
The @else
branch is optional and there is no support (yet) for @elseif
.
Values: In case of an expression from a ValueProvider will be dynamically casted to boolean (null
, 0
and ""
are considered false
).
@if[IsCancelled]
: If IsCancelled is true@if[Name]
: If name is not null or empty@if[ShippingAddress]
: If Shipping address is not null**Comparisons:'' Values can also be compared to Expression Operation ConstantValue
Examples:
@if[State=Cancelled]
@if[Name!=John]
switch (operationString)
{
case "=":
case "==": return FilterOperation.EqualTo;
case "<=": return FilterOperation.LessThanOrEqual;
case ">=": return FilterOperation.GreaterThanOrEqual;
case "<": return FilterOperation.LessThan;
case ">": return FilterOperation.GreaterThan;
case "^=": return FilterOperation.StartsWith;
case "$=": return FilterOperation.EndsWith;
case "*=": return FilterOperation.Contains;
case "%=": return FilterOperation.Like;
case "!=": return FilterOperation.DistinctTo;
case "!^=": return FilterOperation.NotStartsWith;
case "!$=": return FilterOperation.NotEndsWith;
case "!*=": return FilterOperation.NotContains;
case "!%=": return FilterOperation.NotLike;
}
Values in a comparison are parsed using FilterValueConverter.TryParse
, this means:
null
keyword is not supported, instead just write nothing. Example: @if[Name!=]
|
, usefull for IsIn
@if[State==Cancelled]
is right but @if[State==OrderState.Cancelled]
is wrong@if[User==[CurrentUser]]
@if
(or @any
) can contain ANDs and ORs in the conditions, using the operator AND
, OR
, &&
or ||
. Example: @if[FirstName=John AND LastName=Connor]
Allows to repeat some block of text for each element
* @foreach[Entity.Lines.Element]
* Your @[Entity.Lines.Element.Quantity] @[Entity.Lines.Element.Product.Name] cost @[Entity.Lines.Element.Product.UnitPrice] each, and @[Entity.Lines.Element.SubTotalPrice] in total
* @endforeach
You can also avoid repetition by declaring an alias
* @foreach[Entity.Lines.Element] as $e
* Your @[$e.Quantity] @[$e.Product.Name] cost @[$e.Product.UnitPrice] each, and @[$e.SubTotalPrice] in total
* @endforeach
When using a foreach on a model, or global value provider it works as expected. When using a foreach on a query however it does the following:
Element
).Entity.Lines.Element
* ProductName: @[Entity.Lines.Element.Name] <--- WRONG Ambiguous
* @foreach[Entity.Lines.Element]
* ProductName: @[Entity.Lines.Element.Name] <--- RIGHT Unambiguous
* @endforeach
This also means that you can make some counter-intuitive nested @foreach
* @foreach[Entity.Lines.Element.Product.Category]
CATEGORY @[Entity.Lines.Element.Product.Category]
* @foreach[Entity.Lines.Element]
* ProductName: @[Entity.Lines.Element.Name]
* @endforeach
* @endforeach
Allows you to do something like
* @any[Entity.Lines.Element.Product.IsDiscontinued=true]
* Some products are discontinued
* @notany
* All products available
* @endany
Conditions and loops use a combination of tokens, for WordReports they can be in the same line, in different paragraph or different rows of a table, but all the tokens should be at the same level in the underlying tree structure.
RIGHT:
* @if[IsCancelled]
* Your account is cancelled
* @else
* Your account is accepted
* @endif
WRONG:
* @if[IsCancelled]
* Your account is cancelled
* @else Your account is accepted @endif
WRONG:
* @if[Canceled]
* Your account is cancelled
* @else
* Your account is accepted
* @endif
The underlying tree structure is invisible using Microsoft Word, but resembles HTML.
Any kind of node can declare aliases of the expression they are using:
@if[User.Role!=] as $r
@foreach[Entity.Line.Element] as $l
@[Entity.Product] as $p
But you can also use a @declare
token to only create an alias.
@declare[Entity.ShippingAddress] as $sa
@[$sa.Address]
@[$sa.City]
In WordTemplates use crazy colors (like green or magenta) for tokens that should not be rendered (@if, @declare, @foreach) as a poor man syntax hightlight.
The template will be easier to understand and the errors easier to spot in the generated report.
© Signum Software. All Rights Reserved.
Powered by Signum Framework