Computed field for Title [SOLVED]

Is it possible to have 'Title" as a computed field

From  first_name + last_name:


    def title(self):
        if hasattr(self, 'first_name') and hasattr(self, 'last_name'):
            return self.first_names + ', ' + self.last_name
        else:
            return 'No Body'

If it is: would it be possible to do it from a behavior, or do I need to add a (python) content type?

If you want to override or redefine the implementation Title() of an existing content type then I would possibly use Python money patching for providing a custom implementation. If the Title() implementation come from a base class then you need to perform extra checks inside your own implementation that your own magic only applies to the desired content-types. I doubt that it is possible to provide a custom Title implementation through a behavior based on my recent struggle to extend and modify existing behaviors.

You can use the strategy detailed by the blog below:

https://davidjb.com/blog/2010/04/plone-and-dexterity-working-with-computed-fields/

I cheap way (probably not the most elegant) is to inherit from Item or Container (depends on your need), override the Title method (and return what you need in there) and use the new class in your profiles/default/types/yourtype.xml as base <property name="klass">.

1 Like

Thanks

I was hoping to do it from a behavior, but from the answers and the code it looks like I need to do it from the content type.

If you have the content-type code in your own hands then do it of course inside the class itself. Using a behavior in such a case would be nonsense and overkill.

Probably, but I might need it a few places (Actor, Director, etc) and maybe later in life…

Inheritance is your friend

The complication here is that you want the title field computed from names. If you really want just a behavior solution, you can consider just creating a full_name method in your behavior with name fields. Then you call the method in your views if you need the full name.

If you use a custom class solution (PersonItem/PersonContainer) you can also reuse it. But it is not as convenient as a behavior.

Yes, I discovered that that is possible (so now I learned something new).
That is what I am doing now, since it makes it possible for me to make 'a couple of alternatives to show my customer which 'have no idea about how he want it to look / work)...

        # -*- coding: utf-8 -*-
    from plone.dexterity.content import Container
    from plone.supermodel import model
    from zope.interface import implementer
    from datetime import date

    # from medialog.casting import _


    class IActor(model.Schema):
        """ Marker interface and Dexterity Python Schema for Actor    """
        # model.load('actor.xml')


    @implementer(IActor)
    class Actor(Container):
        """
        """
        #@property
        def title(self):
            if hasattr(self, 'first_name') and hasattr(self, 'last_name'):
                return '{0} {1}'.format(self.first_name, self.last_name)
            else:
                return 'NN'

        #def setTitle(self, value):
        #    actor-1 etc for url is better so dont do anything here
        #    return

        @property
        def age(self):
            days_in_year = 365.2425
            if hasattr(self, 'born'):
                age = int((date.today() - self.born).days / days_in_year)
                return age
                #return str("%02d" % age)

I don't think that your age calculation is accurate.

Check https://stackoverflow.com/questions/2217488/age-from-birthdate-in-python

I added a comment to this blogpost with another way of solving this
https://davidjb.com/blog/2010/04/plone-and-dexterity-working-with-computed-fields/

2 Likes

Plone Foundation Code of Conduct