How can dynamic page numbers be inserted into added slides?

Question:

When adding slides via a modified python-pptx, placeholders appear for the slide number on each slide. Instead of the actual slide number, however, the words “Slide Number” appears in that field.

Other answers mention using a static text box, but we need the placeholder to be used, as we transfer create slides to a variety of client masters. A standard textbox would not correctly adjust to varied layouts. We also need the box to float, so that we can place photos behind it on some pages. Finally, it must be dynamic, as we often shuffle pages afterward, so passing it the index as a static number would cause issues.

Is there a string or command that can be inserted into the placeholder that would automatically pull the slide’s position in the deck? The master uses the combination “<#>”, but this doesn’t work when passed as a string.

Apologies for my ignorance, I’ve only been working with python and python-pptx for a couple weeks (huge thanks to its creators!).

Asked By: emmartin

||

Answers:

An “auto-update” slide-number in PowerPoint is a field. The XML looks like this:

<a:fld id="{1F4E2DE4-8ADA-4D4E-9951-90A1D26586E7}" type="slidenum">
  <a:rPr lang="en-US" smtClean="0"/>
  <a:t>2</a:t>
</a:fld>

So the short answer to your question is no. There is no string you can insert in a textbox that triggers this XML to be inserted and there is no API support for adding fields yet either.

The approach would be to get a <a:p> element for a textbox and insert this XML into it using lxml calls (a process commonly referred to as a “workaround function” in other python-pptx posts).

You can get the a:p element like so:

p = textbox.text_frame.paragraphs[0]._p

Something like this might work, and at least provides a sketch of that approach:

from pptx.oxml import parse_xml
from pptx.oxml.ns import nsdecls

# ---get a textbox paragraph element---
p = your_textbox.text_frame.paragraphs[0]._p

# ---add fld element---
fld_xml = (
    '<a:fld %s id="{1F4E2DE4-8ADA-4D4E-9951-90A1D26586E7}" type="slidenum">n'
    '  <a:rPr lang="en-US" smtClean="0"/>n'
    '  <a:t>2</a:t>n'
    '</a:fld>n' % nsdecls("a")
)
fld = parse_xml(fld_xml)
p.append(fld)

The number enclosed in the a:t element is the cached slide number and may not be automatically updated by PowerPoint when opening the presentation. If that’s the case, you’ll need to get it right when inserting, but it will be automatically updated when you shuffle slides.

Answered By: scanny

Here’s an example of how I used it in my code:

Test_Layout = X.slide_layouts[1] 
test_Layout = X.slides.add_slide(Test_Layout) # Adding first slide    

shapes = test_Layout.shapes
left = top = width = height = Inches(1)
txBox = test_Layout.shapes.add_textbox(left, top, width, height) 
txBox.left = Inches(9.22)
txBox.top = Inches(7.03)

# ---get a textbox paragraph element---
p = txBox.text_frame.paragraphs[0]._p

# ---add fld element---
fld_xml = (
    '<a:fld %s id="{1F4E2DE4-8ADA-4D4E-9951-90A1D26586E7}" type="slidenum">n'
    '  <a:rPr lang="en-US" smtClean="0"/>n'
    '  <a:t>2</a:t>n'
    '</a:fld>n' % nsdecls("a")
)
fld = parse_xml(fld_xml)
p.append(fld)

The question now is how do I change the color and font number?

Answered By: Carlos
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.