Working with slide layouts

A slide layout is a template part that describes the placeholder and formatting structure a slide can inherit from a slide master. In PresentationML it is rooted at <p:sldLayout/>; in ooxmlsdk it is represented as a slide layout part reached through relationships.

Slide layout structure

The layout root can contain common slide data, header/footer settings, timing, transition, color map override, and extension data.

<p:sldLayout
  xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
  type="title">
  <p:cSld name="Title Slide">
    <p:spTree>
      <p:nvGrpSpPr>
        <p:cNvPr id="1" name=""/>
        <p:cNvGrpSpPr/>
        <p:nvPr/>
      </p:nvGrpSpPr>
      <p:grpSpPr/>
      <!-- placeholder and shape definitions -->
    </p:spTree>
  </p:cSld>
</p:sldLayout>

Important attributes include:

AttributeMeaning
typeLayout kind, such as title, blank, or title and content
matchingNameName used when matching layouts during template changes
preserveWhether the layout should be kept when no slide uses it
showMasterSpWhether master slide shapes are shown
showMasterPhAnimWhether master placeholder animations are shown
userDrawnWhether user-drawn data should be preserved

A layout is normally reached from a slide part. This example opens a presentation, walks the slides, follows each slide layout relationship, and returns the layout XML.

#![allow(unused)]
fn main() {
pub fn get_slide_layout_xml(path: &Path) -> Result<Vec<String>, Box<dyn std::error::Error>> {
  let document = PresentationDocument::new_from_file_with_settings(path, lazy_settings())?;
  let presentation_part = document.presentation_part()?;
  let mut layouts = Vec::new();

  for slide_part in presentation_part.slide_parts(&document) {
    if let Some(layout_part) = slide_part.slide_layout_part(&document) {
      layouts.push(
        layout_part
          .data_as_str(&document)?
          .unwrap_or_default()
          .to_string(),
      );
    }
  }

  Ok(layouts)
}
}

Layout parts can also relate back to a slide master and to dependent resources such as images, charts, diagrams, embedded packages, and theme overrides. Use the generated part accessors where available, because they resolve relationship ids without hard-coding package paths.

Editing notes

Creating a valid layout from scratch requires a coordinated slide master, layout part, relationship entries, content type overrides, and placeholder XML. In Rust, prefer copying an existing layout and making small schema-aware edits unless your code owns all of those package updates and validates the saved presentation.