Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Add Playground
#! python3
# Share sheet extension script for adding new pages to Swift Playgrounds (experimental)
# 1. Add this script as a shortcut to the Pythonista extension (either from Pythonista's settings or the share sheet extension itself)
# 2. Tap the "Share" button in the Playground app's library.
# 3. Select the playground that you want to add a page to
# 4. Select "Run Pythonista Script" in the share sheet
# 5. Run this script, to select the chapter and page title.
# 6. At the end of the script, an "Open in..." sheet will be shown - select the Swift Playground app there. This will create a copy of the playground in your library, with the new page added to it.
# NOTE: Only tested in Pythonista 3, some minor modifications may be needed to make it work in 2.x.
import appex
import os
import shutil
import tempfile
import console
import dialogs
from PIL import Image
import plistlib
# This is the source codeof the new page, edit as needed:
swift = '''print("Hello World")
# This is the manifest (Info.plist basically) for the page, not sure what other values are supported for LiveViewMode.
manifest_tpl = '''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">
def main():
if not appex.is_running_extension():
print('Run this script from the share sheet extension in the Playgrounds app')
pg_path = appex.get_file_path()
if not pg_path or not pg_path.endswith('.playgroundbook'):
print('No Playground book found in share sheet input')
tmpdir = tempfile.gettempdir()
pg_name = os.path.split(pg_path)[1]
dest_path = os.path.join(tmpdir, pg_name)
except IOError:
shutil.copytree(pg_path, dest_path)
chapters_path = os.path.join(dest_path, 'Contents/Chapters')
chapter_names = os.listdir(chapters_path)
chapter = dialogs.list_dialog('Chapter', chapter_names)
if chapter is None:
page_title = dialogs.input_alert('New Page Title')
except KeyboardInterrupt:
chapter_path = os.path.join(chapters_path, chapter)
with open(os.path.join(chapter_path, 'Manifest.plist'), 'rb') as f:
chapter_manifest = plistlib.readPlist(f)
chapter_manifest['Pages'].append(page_title + '.playgroundpage')
with open(os.path.join(chapter_path, 'Manifest.plist'), 'wb') as f:
plistlib.dump(chapter_manifest, f)
page_path = os.path.join(chapter_path, 'Pages/' + page_title + '.playgroundpage')
os.mkdir(os.path.join(page_path, 'Resources'))
img ='test:Pythonista'), 'Resources/Pythonista.png'))
with open(os.path.join(page_path, 'Contents.swift'), 'w') as f:
manifest = manifest_tpl.replace('{{NAME}}', page_title)
with open(os.path.join(page_path, 'Manifest.plist'), 'w') as f:
if __name__ == '__main__':

This comment has been minimized.

Copy link

commented Jul 18, 2016

It works! @omz, does this mean you're working on creating an educational book for Playgrounds, or is this just for kicks?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.