ITitleFromOtherFields

The title of our content type has to be restricted to be constructed out of the content of other fields from the model schema during instance creation.

Once the instance is created, the relevant fields should no more be editable, as should not be the title field.

I know about the directives.omitted directive. The hard part is where to generate the title after the user hits "Save" during Instance creation add form logic.

I thought about an own factory which does this during instance creation. But i cannot locate code for the default dexterity factory. Registering it should be possible once i find it.

Are there other places possible to put the logic of field computation ? Replacing the Plone templates to show a computed value in stead of the title looks like very much work to find every place where the title field is referenced.

Then the part with editable fields in the AddForm, which should only be readonly on the EditForm. As i can only specify a field readonly for the whole shema, can i use two different schemas, one for add, one for edit purposes ? A custom Add or Edit Form should do the trick, but maybe there is a more trivial approach.

Thank you for your thoughts about this problems.

EDIT:

I found the DexterityFactory class in plone.dexterity.factory.py, and its only usage i can find is in plone.dexterity.fti.py. There is the register helper-function

def register(fti):
    """Helper method to:                                                                                                                    
                                                                                                                                            
    - register an FTI as a local utility                                                                                                    
    - register a local factory utility                                                                                                      
    - register an add view                                                                                                                  
    """

    fti = aq_base(fti)  # remove acquisition wrapper                                                                                        
    site = getUtility(ISiteRoot)
    site_manager = getSiteManager(site)

    portal_type = fti.getId()

    fti_utility = queryUtility(IDexterityFTI, name=portal_type)
    if fti_utility is None:
        site_manager.registerUtility(
            fti, IDexterityFTI, portal_type, info="plone.dexterity.dynamic"
        )

    factory_utility = queryUtility(IFactory, name=fti.factory)
    if factory_utility is None:
        site_manager.registerUtility(
            DexterityFactory(portal_type),
            IFactory,
            fti.factory,
            info="plone.dexterity.dynamic",
        )

So maybe i should site_manager.registerUtility with my own, adapted Factory ? But how to suppress the registering of the default, dexterity factory for my content type beforehand ?

Would updating the title after content creation work for you?

in your content schema module

def sync_articles_data_to_rdbms(context, event):
    """ This function is triggered by
            zope.lifecycleevent.interfaces.IObjectAddedEvent
            zope.lifecycleevent.interfaces.IObjectModifiedEvent
    """

in configure.zcml

  <subscriber
    for=".content.produkte.IProdukte
         zope.lifecycleevent.interfaces.IObjectAddedEvent"
    handler=".content.produkte.sync_articles_data_to_rdbms"
  />  
  <subscriber
    for=".content.produkte.IProdukte
          zope.lifecycleevent.interfaces.IObjectModifiedEvent"
    handler=".content.produkte.sync_articles_data_to_rdbms"
  />

This i will give a try, Thank you !

EDIT: Is there a way to set the plone-id in such an handler, after creation of the object ? The Plone-ID (and the url) should reflect the calculated title.

EDIT2: Changing the title in the IObjectAddedEvent is possible and works. Changing the Plone-ID does not work. No Document gets created at all and a not found reply is returned.

I found a solution.

According to the INameFromFileName behavior i have implemented a INameFromFields one which uses a NameFromFields Adapter:

  <plone:behavior
      name="mein.inhaltstyp.namefromfields"
      title="Erzeuge Titel und Kurznamen aus Feldern."
      description="Automatisches generieren von Titel und Plone-ID aus Datum, Typ und Pfad."
      provides="mein.inhaltstyp.interfaces.INameFromFields"
      />

  <adapter factory=".adapterdatei.NameFromFields" />

adapterdatei.py

from plone.app.content.interfaces import INameFromTitle
from mein.inhaltstyp.interfaces import INameFromFields
import datetime

UEBERSETZUNGSTABELLE = {
    'inhaltstyp': 'TYP',
    'Unbekannt': 'xxx'
}

@implementer(INameFromTitle)
@adapter(INameFromFields)
class NameFromFields(object):

    def __new__(cls, context):
        instance = super(NameFromFields, cls).__new__(cls)
        aktuelle_zeit = datetime.datetime.now()
        datum = aktuelle_zeit.strftime('%Y-%m-%d')
        portal_type = context.getPortalTypeName()
        if portal_type in UEBERSETZUNGSTABELLE:
            dokumenttyp = UEBERSETZUNGSTABELLE[portal_type]
        else:
            dokumenttyp = UEBERSETZUNGSTABELLE['Unbekannt']
        titel = '-'.join((datum, dokumenttyp, context.feld))
        instance.title = titel
        if safe_hasattr(context, 'title') and not context.title:
            context.title = titel
        return instance

    def __init__(self, context):
        pass

interfaces.py

class INameFromFields(Interface):
    """An object that supports gettings it name from one of its fields.                                                       
    """

    feld = schema.TextLine(
        title=(u'Ein Feld des Dokumentes'),
        description=u"Ein Feld des Dokumentes. Erscheint im Titel und der URL.",
        required=True,
    )

Now the shortame (plone-ID) and title gets generated according to the code in the adapter. The title field never shows up to the user (directives.omitted in schema) and the "Field" ist only editable in the AddForm. Although with the edit shortname behavior it could be edited afterwards. With the event-subscriber the title could then be changed accordingly.

The request of implementation thanks to the ZCA of Zope/Plone accomplished.

There's a IShortName behavior iirc. Removing it from the FTI should disable the field afaik.

Torsten Kuehnel via Plone Community wrote at 2024-2-11 19:20 +0000:

...
The title of our content type has to be restricted to be constructed out of the content of other fields from the model schema during instance creation.

Once the instance is created, the relevant fields should no more be editable, as should not be the title field.

I know about the directives.omitted directive. The hard part is where to generate the title after the user hits "Save" during Instance creation add form logic.

Maybe in an event handler for a zope.lifecycleevent event
(IObjectCreatedEvent, IObjectAddedEvent ,,,).