Reputation: 73
I am trying to create a loop in HTML in PowerShell ISE, like this:
{foreach $obj in $objects}
<h1>$obj.Name<h1>
{/foreach}
But it only prints the last one in the list of objects. What do?
Upvotes: 1
Views: 231
Reputation: 437428
Use an expandable (interpolating) here-string and embed a foreach
statement via $(...)
, the subexpression operator:
# Sample objects.
$objects = [pscustomobject] @{ name = 'foo1' },
[pscustomobject] @{ name = 'foo2' }
# Use an expandable (double-quoted) here-string to construct the HTML.
# The embedded $(...) subexpressions are *instantly* expanded.
@"
<html>
$(
$(
foreach ($obj in $objects) {
" <h1>$($obj.Name)<h1>"
}
) -join "`n"
)
</html>
"@
Output:
<html>
<h1>foo1<h1>
<h1>foo2<h1>
</html>
If you want to define the above strings as a template, so you can perform expansion (string interpolation) repeatedly, on demand, use a verbatim here-string, and expand on demand - based on the then-current variable values via $ExecutionContext.InvokeCommand.ExpandString()
:
# Use a verbatim (single-quoted) here-string as a *template*:
# Note the @' / @' instead of @" / @"
$template = @'
<html>
$(
$(
foreach ($obj in $objects) {
" <h1>$($obj.Name)<h1>"
}
) -join "`n"
)
</html>
'@
# Sample objects.
$objects = [pscustomobject] @{ name = 'foo1' },
[pscustomobject] @{ name = 'foo2' }
# Expand the template now.
$ExecutionContext.InvokeCommand.ExpandString($template)
'---'
# Define different sample objects.
$objects = [pscustomobject] @{ name = 'bar1' },
[pscustomobject] @{ name = 'bar2' }
# Expand the template again, using the new $objects objects.
$ExecutionContext.InvokeCommand.ExpandString($template)
Output:
<html>
<h1>foo1<h1>
<h1>foo2<h1>
</html>
---
<html>
<h1>bar1<h1>
<h1>bar2<h1>
</html>
Note:
$ExecutionContext.InvokeCommand.ExpandString()
is a bit obscure, it would be nice to have a cmdlet that provides the same functionality, named, say, Expand-String
or Expand-Template
, as proposed in GitHub issue #11693.Upvotes: 1