diff --git a/odk/CustomTarget_build-examples.mk b/odk/CustomTarget_build-examples.mk
index 4a725ad78846..dd5a2e58732e 100644
--- a/odk/CustomTarget_build-examples.mk
+++ b/odk/CustomTarget_build-examples.mk
@@ -28,6 +28,7 @@ my_example_dirs = \
cpp/counter \
cpp/remoteclient \
python/toolpanel \
+ python/minimal-extension \
# cpp/custompanel \
diff --git a/odk/Package_examples.mk b/odk/Package_examples.mk
index fe8d927c6d85..eb6c3563c5f5 100644
--- a/odk/Package_examples.mk
+++ b/odk/Package_examples.mk
@@ -551,6 +551,13 @@ $(eval $(call gb_Package_add_files_with_dir,odk_examples,$(SDKDIRNAME)/examples,
python/toolpanel/toolpanel.component \
python/toolpanel/toolpanel.py \
python/toolpanel/toolpanels/poc.xdl \
+ python/minimal-extension/Makefile \
+ python/minimal-extension/main.py \
+ python/minimal-extension/description.xml \
+ python/minimal-extension/Addons.xcu \
+ python/minimal-extension/registration/license.txt \
+ python/minimal-extension/pkg-description/pkg-description.en \
+ python/minimal-extension/META-INF/manifest.xml \
python/DocumentHandling/DocumentConverter.py \
python/DocumentHandling/DocumentLoader.py \
python/DocumentHandling/DocumentPrinter.py \
diff --git a/odk/examples/python/minimal-extension/Addons.xcu b/odk/examples/python/minimal-extension/Addons.xcu
new file mode 100644
index 000000000000..5d40bad39a19
--- /dev/null
+++ b/odk/examples/python/minimal-extension/Addons.xcu
@@ -0,0 +1,28 @@
+
+
+
+
+
+ Sample Extension
+
+
+ com.sun.star.text.TextDocument
+
+
+
+
+ Example item
+
+
+ service:org.extension.sample.do?FirstMenuItem
+
+
+ _self
+
+
+
+
+
+
+
+
diff --git a/odk/examples/python/minimal-extension/META-INF/manifest.xml b/odk/examples/python/minimal-extension/META-INF/manifest.xml
new file mode 100644
index 000000000000..a3f7700875a3
--- /dev/null
+++ b/odk/examples/python/minimal-extension/META-INF/manifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/odk/examples/python/minimal-extension/Makefile b/odk/examples/python/minimal-extension/Makefile
new file mode 100644
index 000000000000..0cd40a43c1b3
--- /dev/null
+++ b/odk/examples/python/minimal-extension/Makefile
@@ -0,0 +1,25 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+PRJ = ../../..
+SETTINGS = $(PRJ)/settings
+
+include $(SETTINGS)/settings.mk
+include $(SETTINGS)/std.mk
+
+FILES = \
+ Addons.xcu \
+ META-INF/manifest.xml \
+ description.xml \
+ pkg-description/pkg-description.en \
+ registration/license.txt \
+ main.py
+
+$(OUT_BIN)/minimal-python.$(UNOOXT_EXT): $(FILES)
+ -$(MKDIR) $(subst /,$(PS),$(@D))
+ $(SDK_ZIP) $@ $^
diff --git a/odk/examples/python/minimal-extension/description.xml b/odk/examples/python/minimal-extension/description.xml
new file mode 100644
index 000000000000..ccbba2566dc1
--- /dev/null
+++ b/odk/examples/python/minimal-extension/description.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+ Developer
+
+
+ Minimal Python extension
+
+
diff --git a/odk/examples/python/minimal-extension/main.py b/odk/examples/python/minimal-extension/main.py
new file mode 100644
index 000000000000..225d5bbfa942
--- /dev/null
+++ b/odk/examples/python/minimal-extension/main.py
@@ -0,0 +1,68 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+import sys
+import unohelper
+import officehelper
+
+from com.sun.star.task import XJobExecutor
+
+
+# The MainJob is a UNO component derived from unohelper.Base class
+# and also the XJobExecutor, the implemented interface
+class MainJob(unohelper.Base, XJobExecutor):
+ def __init__(self, ctx):
+ self.ctx = ctx
+ # handling different situations (inside LibreOffice or other process)
+ try:
+ self.sm = ctx.getServiceManager()
+ self.desktop = XSCRIPTCONTEXT.getDesktop()
+ except NameError:
+ self.sm = ctx.ServiceManager
+ self.desktop = self.ctx.getServiceManager().createInstanceWithContext(
+ "com.sun.star.frame.Desktop", self.ctx)
+
+ def trigger(self, args):
+ desktop = self.ctx.ServiceManager.createInstanceWithContext(
+ "com.sun.star.frame.Desktop", self.ctx)
+ model = desktop.getCurrentComponent()
+ if not hasattr(model, "Text"):
+ model = self.desktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, ())
+ text = model.Text
+ cursor = text.createTextCursor()
+ text.insertString(cursor, "Hello Extension argument -> " + args + "\n", 0)
+
+
+# Starting from Python IDE
+def main():
+ try:
+ ctx = XSCRIPTCONTEXT
+ except NameError:
+ ctx = officehelper.bootstrap()
+ if ctx is None:
+ print("ERROR: Could not bootstrap default Office.")
+ sys.exit(1)
+ job = MainJob(ctx)
+ job.trigger("hello")
+
+
+# Starting from command line
+if __name__ == "__main__":
+ main()
+
+
+# pythonloader loads a static g_ImplementationHelper variable
+g_ImplementationHelper = unohelper.ImplementationHelper()
+
+g_ImplementationHelper.addImplementation(
+ MainJob, # UNO object class
+ "org.extension.sample.do", # implementation name (customize for yourself)
+ ("com.sun.star.task.Job",), ) # implemented services (only 1)
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/odk/examples/python/minimal-extension/pkg-description/pkg-description.en b/odk/examples/python/minimal-extension/pkg-description/pkg-description.en
new file mode 100644
index 000000000000..81c8f8c90102
--- /dev/null
+++ b/odk/examples/python/minimal-extension/pkg-description/pkg-description.en
@@ -0,0 +1 @@
+Example LibreOffice extension. Copyright (c) Developer 2023.
diff --git a/odk/examples/python/minimal-extension/registration/license.txt b/odk/examples/python/minimal-extension/registration/license.txt
new file mode 100644
index 000000000000..4bf8bc8df55c
--- /dev/null
+++ b/odk/examples/python/minimal-extension/registration/license.txt
@@ -0,0 +1 @@
+A very short license.