Page Layout¶
PageLayoutOdtTemplate extends OdtTemplate with helpers for changing selected page geometry in styles.xml.
Use it when the LibreOffice template owns the page design but the application needs to adjust margins, dimensions, or orientation programmatically.
Page margins¶
use OdtTemplateEngine\PageLayoutOdtTemplate;
$template = new PageLayoutOdtTemplate(
__DIR__ . '/templates/report.odt'
);
$template->setPageMargins(
'1.5cm', // top
'1.5cm', // right
'1.5cm', // bottom
'1.5cm' // left
);
By default, the method resolves the master page named Standard and updates the page layout referenced by that master page.
A different master page can be supplied explicitly:
General page layout options¶
setPageLayout() currently supports:
$template->setPageLayout([
'margin-top' => '1cm',
'margin-right' => '1.2cm',
'margin-bottom' => '1cm',
'margin-left' => '1.2cm',
'page-width' => '29.7cm',
'page-height' => '21cm',
'orientation' => 'landscape',
]);
Supported keys are:
margin-topmargin-rightmargin-bottommargin-leftpage-widthpage-heightorientation(portraitorlandscape)
Empty values and invalid orientation values cause a runtime exception rather than silently producing an invalid layout request.
How page layout is resolved¶
ODF page geometry is not stored directly on the document body. The relevant relationship is approximately:
styles.xml
│
├── style:master-page
│ │
│ └── style:page-layout-name
│ │
│ ▼
└── style:page-layout
│
└── style:page-layout-properties
├── fo:margin-top
├── fo:margin-right
├── fo:margin-bottom
├── fo:margin-left
├── fo:page-width
├── fo:page-height
└── style:print-orientation
PageLayoutOdtTemplate follows this reference rather than assuming a fixed generated style name.
If the requested master page does not exist, does not reference a page layout, or the referenced layout has no properties node, the API throws an exception with the corresponding structural problem.
Template-first page design¶
Programmatic page layout should complement the template rather than replace it.
Prefer LibreOffice for stable design decisions such as:
- headers and footers;
- page styles and master-page structure;
- multi-column document design;
- fixed frames and visual branding.
Use PageLayoutOdtTemplate when application data or a layout variant genuinely needs to change page geometry.
Flow is not pagination¶
Paragraph options such as keep-with-next, keep-together, widows,
orphans, break-before, and break-after express native paragraph-flow
intent. They do not select a page style, define page geometry, or calculate
physical page placement. Writer lays out content and computes pagination.
The C01 capability sample
contrasts generated paragraph-flow properties with the authored master-page
succession and page-number field in its template. This does not define a PHP
page-style API.
Why this is a separate class¶
Page layout changes operate on styles.xml and have different responsibilities from normal placeholder replacement. Keeping them in PageLayoutOdtTemplate makes that advanced behavior explicit while preserving OdtTemplate as the normal entry point.
The implementation also overrides list-indentation adjustment so page margins are not accidentally affected by the historical list-style cleanup path.
Example: complex CV¶
S01b uses PageLayoutOdtTemplate because the LibreOffice template defines the two-column CV structure while PHP adjusts the page margins and fills the two large generated regions.
$template = new PageLayoutOdtTemplate(
__DIR__ . '/templates/template_S01b_cv_structured.odt'
);
$template->setPageMargins('0cm', '0.8cm', '0cm', '0cm');
This is a good example of the intended division of responsibility: LibreOffice owns the durable page composition; PHP owns dynamic document content and selected geometry.
Related resources¶
- S01b — Professional CV · Structured Template — complex CV / page-layout usage
PageLayoutOdtTemplateTest— integration coverage for page-layout changes
See ODT Internals for the role of styles.xml and master pages in the package.