# Writing a Scripted Subject Hierarchy Plugin -- documentation lacking

**URL:** <https://discourse.slicer.org/t/writing-a-scripted-subject-hierarchy-plugin-documentation-lacking/45252>\
**Category:** Development\
**Tags:** documentation, subject-hierarchy, extensions\
**Created:** [November 27, 2025, 1:33pm UTC](https://discourse.slicer.org/t/writing-a-scripted-subject-hierarchy-plugin-documentation-lacking/45252 "2025-11-27T13:33:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![shai-ikko](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/shai-ikko/32/15765_2.png) [@shai-ikko](https://discourse.slicer.org/u/shai-ikko)\
**Post date:** [November 27, 2025, 1:33pm UTC](https://discourse.slicer.org/t/writing-a-scripted-subject-hierarchy-plugin-documentation-lacking/45252/1 "2025-11-27T13:33:42Z")

</div>

Hi,

Recently I’ve been writing an internal-use Subject Hierarchy plugin. I ran into some difficulties that stem, IMO, from lacking documentation, so I want to share what I’ve learned with a view to getting some comments and eventually improving the docs.

The first, and most important issue, is the context. For a class to serve as a Subject Hierarchy Plugin, it needs to

- Be written in the main file of an Extension Module
- Be named exactly as the module, with the suffix `SubjectHierarchyPlugin`

That is, if your module is named `Kawabanga`, the plugin class must reside in `Kawabanga.py` and be named `KawabangaSubjectHiearachyPlugin`.

This is followed, but not explicitly declared, in [the example plugin](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#subject-hierarchy-plugin-offering-view-context-menu-action) in the script repository; that example is also a bit misleading, because it is (correctly) described as an example for a special plugin (one that operates in views, rather than in the subject hierarchy).

Other plugins which claim to serve as examples – e.g. `SegmentEditorSubjectHierarchyPlugin` in the sources – don’t actually follow these rules, and so they are misleading.

When fixing the documentation, we should also modernize the examples – currently, the way to iterate over children is presented in the script repository as

```auto
children = vtk.vtkIdList()
shNode.GetItemChildren(parent, children)
for i in range(children.GetNumberOfIds()):
  child = children.GetId(i)
  ...

```

but with modern Python and Slicer, this can be done with

```auto
shNode.GetItemChildren(parent, children:=[])
for child in children:
  ...

```

I will come back to this later, but wanted to raise this while fresh in mind and maybe get some feedback.

Thanks!

---

<div class="post-metadata">

**Author:** ![cpinter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cpinter/32/7995_2.png) [@cpinter](https://discourse.slicer.org/u/cpinter)\
**Post date:** [November 27, 2025, 2:19pm UTC](https://discourse.slicer.org/t/writing-a-scripted-subject-hierarchy-plugin-documentation-lacking/45252/2 "2025-11-27T14:19:27Z")

</div>

Just very quickly due to not having any time today.

> No documentation

You’re right, this could be improved.

> That is, if your module is named `Kawabanga`, the plugin class must reside in `Kawabanga.py` and be named `KawabangaSubjectHiearachyPlugin`.

I’m pretty sure that this is not correct. Please look at for example `SlicerHeart\ValveAnnulusAnalysis\HeartValveLib\HeartValvesSubjectHierarchyPlugin.py`

> but with modern Python and Slicer

Actually, I think what we’d suggest would be `slicer.util.getSubjectHierarchyItemChildren`, but what you’re suggesting is great too. Honestly I’d need to look at how it works exactly.

---

<div class="post-metadata">

**Author:** ![shai-ikko](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/shai-ikko/32/15765_2.png) [@shai-ikko](https://discourse.slicer.org/u/shai-ikko)\
**Post date:** [December 3, 2025, 4:18pm UTC](https://discourse.slicer.org/t/writing-a-scripted-subject-hierarchy-plugin-documentation-lacking/45252/3 "2025-12-03T16:18:40Z")

</div>

> [@cpinter](#):
>
> > That is, if your module is named `Kawabanga`, the plugin class must reside in `Kawabanga.py` and be named `KawabangaSubjectHiearachyPlugin`.
> 
> I’m pretty sure that this is not correct. Please look at for example `SlicerHeart\ValveAnnulusAnalysis\HeartValveLib\HeartValvesSubjectHierarchyPlugin.py`

So, yes, my claim was inaccurate. The plugin class doesn’t really need to be in the same file as the main module. Its name only has to match the name of the module it is actually in, that is:

- If the module name ends with `SubjectHierarchyPlugin`, the plugin class must have the same name;
- Otherwise, the plugin class must be named as the module with the suffix `SubjectHierarchyPlugin`.

That is, even if your main module is `Kawabanga.py`, you plugin class may be named `YipeeSubjectHierachyPlugin`. And then the file it is defined in can be either `YipeeSubjectHierachyPlugin.py` or `Yipee.py`, but it _must_ be one of these two.

This is enforced in `qSlicerSubjectHierarchyScriptedPlugin::setPythonSource(const QString filePath)`

More of this later.
