Nested Content Types


I am looking into whether it is possible to have a content type nested within another content type. An example use case here would be

Having a 'Region' content type that just has a title, users can go in and create instances of 'Region'

I have a second content type that represents a person, and would like to reference the 'Region' content type that they are associated with. This way if I have multiple things that have a 'Region' they can all pull from the same data source.

Is this something that is possible?


Hi Jeremy.
We have our selves folderish structure with database->hospital->patient->visit

You will need have your "region" as folderish type and then also in region in the xml of region add "person" as addable.

from plone.dexterity.content import Container

class region(Container):

in your region.xml:
  <property name="filter_content_types">True</property>
  <property name="allowed_content_types">
     <element value="person" />

I could suggest you look into plonecli, a command line tool for doing contenttypes.

This will help you do a product for your content types and the content types themselves.


That makes sense, I've got that structure created in my plone instance now, I think my next question with this 'data-model' is if I have a bunch of 'Person' content types already created, when I create a new region can I populate all of the existing 'Person' contents into a select so I can associated them with the new region?

This kind of illustrates what I'm looking for

  • Existing Child List
  • ChildOne
  • ChildTwo

  • Container
    • ChildOne <- Referencing the ChildOne in an Existing Child List
    • ChildTwo <- Referencing the ChildTwo in an Existing Child List

Is that a supported use case or is it purely a

  • Container

    • ChildOne
    • ChildTwo
    • ChildThree
  • Container

    • ChildFour <- 'Copy' of ChildOne but is a separate instance

Relationlist or Relationchoice could be a solution so you have a flexible hierarchy where you can "link" content instead of using less flexible containers. (

You can also have a similar effect by doing a custom dynamic vocabulary.



Is there a way to override how a relationlist/relationchoice renders in the view?

How relations are displayed (and more) is discussed in

Based on that, the only way to 'override' what a relationlist/choice renders as is via Python?

Is there not a way for example, if my relationlist field id is authors, can I not insert it into the view with something like...

<div tal:repeat="item context/authors">
            <p tal:content="item">text replaced by item</p>

This is how that ends up rendering -

Looks like you can, I am able to get access to the fields of the content type, from the property on the RelationValue 'to_object' z3c.relationfield/ at master · zopefoundation/z3c.relationfield · GitHub

<div tal:repeat="item context/authors">
            <p tal:content="">text replaced by item</p>

I'm now curious if there is a way to access the view template for the 'Author' content type and render using that?

So this is how I ended up approaching this,

My 'main' template, the ones that has a relationlist on the content type looks like

<div class="container">
            <div class="row">
                <div tal:repeat="item context/authors" class="col-md-4">
                    <span>Author Information: <p tal:content="">text replaced by item</p></span>
                    <div tal:replace="structure python:item.to_object.author_custom_view()">text replaced </div>

The author_custom_view template looks like

<div class="card" style="width: 18rem;">
  <div class="card-body">
    <h5 class="card-title"  tal:content="context/name">Article Author: {context/name}</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
    <a href="#" class="card-link">Card link</a>
    <a href="#" class="card-link">Another link</a>

Are there any 'gotchas' to doing it this way?

That looks ok to me, although I would advise to not use path-statements. Also your code does not account for broken relations (i.e. when python: context.authors[0].to_object is None.

Also: The chapter on relations was just updated to reflect the changes made for Issues · plone/Products.CMFPlone · GitHub 43. Relations — Plone Training 2021 documentation
These docs assume that you write custom code in your own addon though.

Plone Foundation Code of Conduct