Forum


Replies: 5   Views: 501
How to insert a page break after every cloned blocked
Topic closed:
Please note this is an old forum thread. Information in this post may be out-to-date and/or erroneous.
Every phpdocx version includes new features and improvements. Previously unsupported features may have been added to newer releases, or past issues may have been corrected.
We encourage you to download the current phpdocx version and check the Documentation available.

Posted by fiwoyax200  · 06-09-2023 - 11:26

Hi,

How could I modify my PHP code to add a page break after every cloned block to ensure every block is on a new page. My PHP code is as follows:

 

$variables = array(
    array(
        '1' => 'Test 1',
        '2' => 'John Doe',
        '3' => '2',
        '4' => '11/08/2021',

    ),
    array(
        '1' => 'Test 2',
        '2' => 'John Doe',
        '3' => '2',
        '4' => '11/08/2021',
    ),
);

// clone block setting the variables to be replaced
$docx->cloneBlock('FINDINGS', 1, $variables, array('removeBlockPlaceholder' => true));

// delete remaining block
$docx->deleteTemplateBlock('FINDINGS');

 

Posted by admin  · 06-09-2023 - 14:09

Hello,

You can use any of the following approaches:

  • Add the page break in the DOCX template manually (using MS Word, LibreOffice or any program you have used to create the document). The block placeholders must wrap the contents including the page break. In this case you can run:
$variables = array(
    array(
        'VAR_NAME' => 'John Doe',
        'VAR_DATE' => '11/08/2021',
    ),
    array(
        'VAR_NAME' => 'Jane Doe',
        'VAR_DATE' => '21/08/2021',
    ),
);

$docx->cloneBlock('FINDINGS', 1, $variables, array('removeBlockPlaceholder' => true));

$docx->deleteTemplateBlock('FINDINGS');

The block contens including the page break will be cloned.

  • Add a new placeholder at last block content that will be used to insert the page break (for example $VAR_BREAK$):
$BLOCK_FINDINGS$

$VAR_NAME$

$VAR_DATE$

$VAR_BREAK$

$BLOCK_FINDINGS$

In this case you need to use a WordFragment to add the page break in cloneBlock:

$breakFragment = new WordFragment($docx);
$breakFragment->addBreak(array('type' => 'page'));

$variables = array(
    array(
        'VAR_NAME' => 'John Doe',
        'VAR_DATE' => '11/08/2021',
        'VAR_BREAK' => $breakFragment,
    ),
    array(
        'VAR_NAME' => 'Jane Doe',
        'VAR_DATE' => '21/08/2021',
        'VAR_BREAK' => $breakFragment,
    ),
);

$docx->cloneBlock('FINDINGS', 1, $variables, array('removeBlockPlaceholder' => true));

$docx->deleteTemplateBlock('FINDINGS');
  • Use the firstMatch option to do block placeholder replacements instead of removing them. This approach is more complex but it's more flexible and can be useful if you can't change the template you are using to add the manual page break or the new placeholder.
$variables = array(
    array(
        'VAR_NAME' => 'John Doe',
        'VAR_DATE' => '11/08/2021',
    ),
    array(
        'VAR_NAME' => 'Jane Doe',
        'VAR_DATE' => '21/08/2021',
    ),
);

$docx->cloneBlock('FINDINGS', 1, $variables);

// rename and remove inital block placeholders
$docx->replaceVariableByText(array('BLOCK_FINDINGS' => '$BLOCK_FINDINGS_0$'), array('firstMatch' => true));
$docx->replaceVariableByText(array('VAR_NAME' => '$VAR_NAME_0$'), array('firstMatch' => true));
$docx->replaceVariableByText(array('VAR_DATE' => '$VAR_DATE_0$'), array('firstMatch' => true));
$docx->replaceVariableByText(array('BLOCK_FINDINGS' => '$BLOCK_FINDINGS_0$'), array('firstMatch' => true));
$docx->removeTemplateVariable('BLOCK_FINDINGS_0');
$docx->removeTemplateVariable('VAR_NAME_0');
$docx->removeTemplateVariable('VAR_DATE_0');
$docx->removeTemplateVariable('BLOCK_FINDINGS_0');

// remove the new first match of BLOCK_FINDINGS (this is the placeholder as the beginning of the block)
$docx->replaceVariableByText(array('BLOCK_FINDINGS' => '$BLOCK_FINDINGS_0$'), array('firstMatch' => true));
$docx->removeTemplateVariable('BLOCK_FINDINGS_0');

$breakFragment = new WordFragment($docx);
$breakFragment->addBreak(array('type' => 'page'));

// replace the new first match of BLOCK_FINDINGS (this is the placeholder as the end of the block)
$docx->replaceVariableByWordFragment(array('BLOCK_FINDINGS' => $breakFragment), array('firstMatch' => true));

// remove the new first match of BLOCK_FINDINGS (this is the placeholder as the beginning of the block)
$docx->replaceVariableByText(array('BLOCK_FINDINGS' => '$BLOCK_FINDINGS_0$'), array('firstMatch' => true));
$docx->removeTemplateVariable('BLOCK_FINDINGS_0');

// replace the new first match of BLOCK_FINDINGS (this is the placeholder as the end of the block)
$docx->replaceVariableByWordFragment(array('BLOCK_FINDINGS' => $breakFragment), array('firstMatch' => true));

Regards.

Posted by fiwoyax200  · 06-09-2023 - 14:55

Excellent, thanks for your response.

I have chosen to use the ' Add the page break in the DOCX template manually' method which works perfectly.

A slightly different issue I am having is that when I clone the block some of the values to replace the placeholders will contain HTML code which is displayed as plaintext rather than the formatting and styling.

How could I get the Word Document to display the formatting and styling of the HTML?

 

$variables = array(
    array(
        '1' => '<b>Test 1<b>',
        '2' => '<u>John Doe</u>',
        '3' => '2',
        '4' => '11/08/2021',

    ),
    array(
        '1' => '<b>Test 2<b>',
        '2' => '<u>John Doe</u>',
        '3' => '2',
        '4' => '11/08/2021',
    ),
);

 

Posted by admin  · 06-09-2023 - 15:29

Hello,

Instead of a text string you need to use a WordFragment. For example:

$htmlFragmentA = new WordFragment($docx);
$htmlFragmentA->embedHtml('<b>John Doe</b>');

$htmlFragmentB = new WordFragment($docx);
$htmlFragmentB->embedHtml('<u>Jane Doe</u>');

$variables = array(
    array(
        'VAR_NAME' => $htmlFragmentA,
        'VAR_DATE' => '11/08/2021',
    ),
    array(
        'VAR_NAME' => $htmlFragmentB,
        'VAR_DATE' => '21/08/2021',
    ),
);

$docx->cloneBlock('FINDINGS', 1, $variables, array('removeBlockPlaceholder' => true));

$docx->deleteTemplateBlock('FINDINGS');

In the examples/Templates/cloneBlock folder of the pakage you can find some other samples using cloneBlock. sample_8.php illustrates using cloneBlock with WordFragments (link and image; HTML and other WordFragments contents work in the same way).

P.S. we have removed your email address from your username

Regards.

Posted by fiwoyax200  · 06-09-2023 - 16:19

Thank you.

Is there any way that I can set the type to 'block'? as the option defined in replaceVariableByHTML?

Posted by admin  · 06-09-2023 - 16:24

Hello,

Yes, please check the API documentation page of the method (https://www.phpdocx.com/api-documentation/docx-path/clone-blocks-in-docx). The method includes the following option:

type      string  Possible values are: inline (default) or block. Used by WordFragment values.

to set the replacement type when adding WordFragments:

$docx->cloneBlock('FINDINGS', 1, $variables, array('removeBlockPlaceholder' => true, 'type' => 'block'));

Regards.