PHPWord
PHPWord copied to clipboard
New line with templateProcessor
This is:
- [x] a bug report
- [ ] a feature request
- [ ] not a usage question (ask them on https://stackoverflow.com/questions/tagged/phpword)
Expected Behavior
$myString = "Test-X \n Test-Y" `Test-X' 'Test-Y'
Current Behavior
$myString = "Test-X \n Test-Y" `Test-XTest-Y'
#838 <w:br/>\n
and </w:t><w:br/><w:t>
don't work. the problem is the same.
Failure Information
When I use the template processor, I can't insert a new line with a string.
How to Reproduce.
<?php
$templateProcessor->setValue('txt_agent_detail_evalB#'.$i.'', "test1 \n test2");
?>
Context
- PHP version: 7
- PHPWord version: 0.14
+1
Hi,
Any news about it ?
Thanks
+1
Also the </w:t><w:br/><w:t>
solution doesn't seem to work with
\PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true);
since the tags are escaped then.
+1
+1, any news ?
Did anyone came up with a fix or workaround for this already?
Since I need this urgently I came up with a dirty workaround for this problem.
As I see it the exact problem is the following:
- I want to add newlines to stuff I add via TemplateProcessor (which works by adding
</w:t><w:br/><w:t>
). - But I also want to use
outputEscapingEnabled = true
in phpword.ini so a simple & sign in the input doesn't break my word file.
Yet, output escaping uses htmlspecialchars
and therefore also escapes and breaks the newlines.
I tried to fix this problem in Phpword/Escaper/Xml.php:
There I changed the function escapeSingleValue
FROM:
protected function escapeSingleValue($input)
{
// todo: omit encoding parameter after migration onto PHP 5.4
return htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
}
TO:
protected function escapeSingleValue($input)
{
$escaped = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
// we don't want to escape the newline code, so we replace it with html tag again
$escaped_but_newlines_allowed = str_replace('</w:t><w:br/><w:t>', '</w:t><w:br/><w:t>', $escaped);
return $escaped_but_newlines_allowed;
}
So after the input is escaped with htmlspecialchars I simply revert these changes for the newlines. Not very elegant but does the job for now.
Any news on this issue?
I'm also interested by having a cleaner solution ! Some news ?
Same issue Any news?
+1 Also the
</w:t><w:br/><w:t>
solution doesn't seem to work with\PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true);
since the tags are escaped then.
+1
help please, +1
+1
+1
Here is my solution:
$templateProcessor->setValue('foo', 'Lorem.${newline}Ipsum....');
$new_line = new \PhpOffice\PhpWord\Element\PreserveText('</w:t><w:br/><w:t>');
$templateProcessor->setComplexValue('newline', $new_line);
I hope it helps.
I added </w:t><w:p/><w:t> for a new paragraph and it is working well.
Here is the templatewords and printscreen of the word document:
${alternatif_block} Alternatif-${altId} ${alternatif} ${/alternatif_block}
Here is the codes:
$replacements = array(
array('altId' => '1', 'alternatif' => 'Lorem </w:t><w:p/><w:t> ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
'),
);
$templateProcessor->cloneBlock('alternatif_block', 0, true, false, $replacements);
And here is the printscreen of output:
I added </w:t><w:p/><w:t> for a new paragraph and it is working well.
Here is the templatewords and printscreen of the word document:
${alternatif_block} Alternatif-${altId} ${alternatif} ${/alternatif_block}
Here is the codes:
$replacements = array( array('altId' => '1', 'alternatif' => 'Lorem </w:t><w:p/><w:t> ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod '), ); $templateProcessor->cloneBlock('alternatif_block', 0, true, false, $replacements);
And here is the printscreen of output:
But it works for only at first paragraph...
Here is my solution:
$templateProcessor->setValue('foo', 'Lorem.${newline}Ipsum....'); $new_line = new \PhpOffice\PhpWord\Element\PreserveText('</w:t><w:br/><w:t>'); $templateProcessor->setComplexValue('newline', $new_line);
I hope it helps.
For you this code works in all breaks or for just the first?
It replaces all ${newline} not only the first one.
@damienlaguerre tks for the quickly reply. I'll look why for me replace just the first.
Unless I'm missing something, it seems that TemplateProcessor::setComplexValue()
(cf. https://github.com/PHPOffice/PHPWord/blob/0.18.2/src/PhpWord/TemplateProcessor.php#L267-L293) only replaces one (the first) occurrence whereas TemplateProcessor::setValue()
replaces all occurrences.
However, this is not documented clearly in neither https://phpword.readthedocs.io/en/latest/templates-processing.html#setcomplexvalue nor https://phpword.readthedocs.io/en/latest/templates-processing.html#setvalue, and therefore it's not obvious if this is by design or a missing feature (or even a bug). @troosan, can you comment on this?
As a (temporary) workaround, I'm using something along the lines of
$newline = new PreserveText('</w:t><w:br/><w:t>');
while (isset($templateProcessor->getVariableCount()['newline'])) {
$templateProcessor->setComplexValue('newline', $newline);
}
to replace ${newline}
until all occurrences are replaced.
https://github.com/PHPOffice/PHPWord/issues/2038 has been labeled “WontFix”.
I'm not sure why the solution using setComplextValue with PreserveText doesn't work for me. I have to use cloneBlock to generate lines. Here is my solution:
- Update your template with a block definition:
${lines}
${line}
${/lines}
- Prepare an array of strings for replacement:
$replacements = [
['line' => 'line 1 text'],
['line' => 'line 2 text'],
...
];
- Invoke cloneBlock:
$templateProcessor->cloneBlock('lines', 0, true, false, $replacements);
I'm not sure why the solution using setComplextValue with PreserveText doesn't work for me. I have to use cloneBlock to generate lines. Here is my solution:
- Update your template with a block definition:
${lines} ${line} ${/lines}
- Prepare an array of strings for replacement:
$replacements = [ ['line' => 'line 1 text'], ['line' => 'line 2 text'], ... ];
- Invoke cloneBlock:
$templateProcessor->cloneBlock('lines', 0, true, false, $replacements);
+1 for me.