Trim lines in template files
- prokki
- Member | 3
Hi
Is there a possibility to trim lines in templates? I am currently working with text mails and indentations are really important. Especially in (nested) loops lines has to be adjusted. The following is a simple example, I need much more loops and conditions inside loops:
--------------------------------------------------------------------------------
{foreach $stations as $station}
{$station->getSomething()} - {$station->getSomethingElse()}
{foreach $station->getWindow() as $window}
{$window->getTotalPrice()}
{if $window->isFrench()}
[....]
{/if}
{/foreach}
--------------------------------------------------------------------------------
{/foreach}
The result should look like
--------------------------------------------------------------------------------
Something - Something else
Price: 123.00
--------------------------------------------------------------------------------
Something - Something else
Price: 123.00
--------------------------------------------------------------------------------
but actually it looks like
--------------------------------------------------------------------------------
Something - Something else
Price: 123.00
--------------------------------------------------------------------------------
Something - Something else
Price: 123.00
--------------------------------------------------------------------------------
I have tried to work with spaceless
or strip
but either
- the output looks weird, i.e. no line breaks at all or
- the template looks weird afterwards, so it is even better to skip these filters – and then the template still looks unreadable.
--------------------------------------------------------------------------------
{foreach $stations as $station}
{$station->getSomething()} - {$station->getSomethingElse()}
{foreach $station->getWindow() as $window}
{$window->getTotalPrice()} {if $window->isFrench()}[....]{/if}{/foreach}
--------------------------------------------------------------------------------
{/foreach}
I am looking for something like {<<
to trim all leading
whitespaces until the last line break or {spaceless-leading}
or
whatever. Example:
--------------------------------------------------------------------------------
{<< foreach $stations as $station}
{<< $station->getSomething()} - {$station->getSomethingElse()}
{<< foreach $station->getWindow() as $window}
{<< $window->getTotalPrice()}
{<< if $window->isFrench()}
[....]
{<< /if}
{<< /foreach}
--------------------------------------------------------------------------------
{<< /foreach}
Has anyone an idea?
Best,
Falko
- prokki
- Member | 3
CZechBoY wrote:
try |strip
Like I mentioned above, i tried to use the strip
filter but to
be honest, I haven't found a way to use strip
without destroying
the template layout. strip
removes also newlines, so either
- I have to change every line and add add several additional blocks that it works (which again destroys the readable template) or
- the complete text is in one line.
Just to remind you: It is not a html template, it is a text template file which is used for text mails, so I need to keep the newlines.
Last edited by prokki (2019-10-30 09:26)
- nightfish
- Member | 517
@prokki Do you ever need to keep leading spaces? If not, you could use regexp to strip all leading spaces from the template output. Something along the lines of:
<?php
$data = '
some spaces
even more spaces
no spaces
empty line above
';
var_dump(preg_replace('~^ +~m', '', $data));
If you need to preserve some of the spaces, then you'll need to mark the
lines (e.g. with <<
).
<?php
$data = '
some spaces
<<even more spaces # this space is trimmed, the rest is kept as-is
no spaces
empty line above
';
var_dump(preg_replace('~^ +<<~m', '', $data));
- prokki
- Member | 3
Hi @CZechBoY and @nightfish
I tried to implement your suggested solutions and followed now the
stripWithoutNewLines
advise.
<?php
class Strings
{
public static function ltrimStreamWS(string $buffer, $replaceBy = ''): string
{
$replacedFirst = preg_replace("/^(?:\\h+)/", sprintf("%s", (string)$replaceBy), $buffer);
$replaced = preg_replace("/\n(?:\\h+)/", sprintf("\n%s", (string)$replaceBy), $replacedFirst);
return $replaced;
}
}
class Macros extends Latte\Macros\MacroSet
{
[...]
$me->addMacro('trimLeadingWhitespaces', [$me, 'macroTrimLeadingWhitespaces'], [$me,
public function macroTrimLeadingWhitespaces(MacroNode $node, PhpWriter $writer): void
{
if ($node->modifiers) {
throw new CompileException('Modifiers are not allowed in ' . $node->getNotation());
}
$node->data->capture = true;
$node->data->replaceBy = empty($node->args) ? null : $writer->write('%node.word');
}
public function macroEndTrimLeadingWhitespaces(MacroNode $node, PhpWriter $writer): void
{
if (!$node->data->capture) {
throw new CompileException('Missing start block {trimLeadingWhitespaces}.');
}
$node->data->capture = false;
$node->openingCode = \sprintf('<?php ob_start(function ($s) { return Strings::ltrimStreamWS($s, %s); }, 4096); ?>', empty($node->data->replaceBy) ? '""' : $node->data->replaceBy);
$node->closingCode = '<?php ob_end_flush(); ?>';
}
}
?>
--------------------------------------------------------------------------------
{trimLeadingWhitespaces}
{foreach $stations as $station}
{$station->getSomething()} - {$station->getSomethingElse()}
{foreach $station->getWindow() as $window}
{$window->getTotalPrice()}
{if $window->isFrench()}
[....]
{/if}
{/foreach}
--------------------------------------------------------------------------------
{/foreach}
{/trimLeadingWhitespaces}
I think it is not the best solution but so far it works. Thanks for your help!
Best,
Falko