This is a feature request for usability improvement to LINQ Reporting Engine.
Even though overall it’s 1000x better and easier to use, it does have one drawback that the old mail merge approach didn’t suffer from.
In the old system, when you had nested repeats, you could tell easily where each block ended, because the TableEnd tag had to respecify the field name being enumerated:
«TableStart:Documents»
«DocumentName»
«TableStart:Pages»
«PageNumber»
«TableStart:Sentences»
«SentenceText»«TableEnd:Sentences»
«TableEnd:Pages»
«TableEnd:Documents»
In the new approach, it isn’t and can’t be specified, so that semantic information is lost and all the /foreach tags look the same, and which /foreach closes which foreach is dictated only by the order they come up in (which can change due to content edits in between them):
<<foreach [in Documents]>>
<<[DocumentName]>>
<<foreach [in Pages]>>
<<[PageNumber]>>
<<foreach [in Sentences]>>
<<[SentenceText]>><</foreach>>
<</foreach>>
<</foreach>>
When this stuff is far apart from each other (and especially if some of the foreaches are not on their own left-aligned line, but in the end of a table cell, or after a bunch of content, or whatever), it’s not clear which /foreach is which, a key piece of information for adding content in the right place!
I think a good way to solve this would be to allow the template user to optionally specify what enumeration is being closed, like TableEnd: did in the old mail merge, and if that doesn’t match up with the opening tag, the engine can meaningfully crash:
<<[SentenceText]>><</foreach [Sentences]>>
<</foreach [Documents]>> <-- this would throw, as Pages comes before Documents
<</foreach [Pages]>>
The same problem exists with nested <<if>>
tags, so we need a solution for that too (though it doesn’t have to be the same approach for both).
Matching up the <</if>>
tag by repeating the condition (the engine would just match verbatim) would be fine for boolean fields:
<<if [IsComply]>>
(...)
<</if [IsComply]>>
, but for anything more complex than that, it would be tacky and weird to have to maintain the condition in both places, so that’s probably not the right solution even though it probably is for /foreach tags.
If there was some sort of syntax to allow comments in tags, that could be helpful, because then you could do
<<if [DCFs.Any(f => f.IsS)] /*sCheck*/ >>
(...)
<</if /*sCheck*/ >>
The problem with that is, it’s just a text comment it isn’t actually checked, so if content in between changed such that this <</if>>
isn’t closing the condition that the comment claims it is, no one would know it had gone stale and it would mislead the template maintainer.
Maybe some sort of syntax to “name” if tags, so that again, if the <</if>>
wasn’t in the right place to be closing the <<if>>
that it’s named, the reporting engine could throw an error:
<<if [DCFs.Any(f => f.IsS)] #sCheck#>>
<<if [IsComply]>> (...)
<</if #sCheck#>> <-- this would throw, as it's actually closing IsComply
I’m attaching a real-world example of an area in a template that’s hard to maintain because of nested <<foreach>
> and <<if>>
tags whose corresponding close tags are not easily spotted:
hard to maintain templates.png (27.4 KB)
All I’ve been able to do for the template maintainer end users is lighten and shrink non-output syntax, which is a little nicer for readability but doesn’t go very far.
I could consider using unique text or background colors for each tag in order to make their closing partner obvious, but there are only so many usable and distinct colors, and that would have the same not-checked-for-staleness problem that comments would…
Any thoughts, or techniques I’m missing?