Plone username as non editable field value of a schema in dexterity content

I am using Plone 4.
I am creating content by dexterity plone.
I want plone username to be one of the schema field.
I want it to be fixed. User should not change that value.

I tried the following.
This will not set fixed value, but shows username as
default value. This is also not working. Here i get error
NameError: global name 'context' is not defined

def usvalue():
membership = getToolByName(context,'portal_membership')
currentuser = membership.getAuthenticatedMember()
return currentuser

class Imycontent(model.Schema):
"""
this is exp content my
"""

usname = schema.TextLine(
   title=_(u'user name'),
   defaultFactory=usvalue(),
   
)

How to get username as non editable field value in content schema?

def usvalue():
    import plone.api
    membership = getToolByName(plone.api.portal.get(),'portal_membership')
    currentuser = membership.getAuthenticatedMember()
    return currentuser.getUserName()

easier and shorter:

def usvalue():
    from plone import api
    return api.user.get_current().getUserName()

I would also add that, I don't know if it is a typo, the field definition as an error

usname = schema.TextLine(
   title=_(u'user name'),
   defaultFactory=usvalue(),
)

must be:

  defaultFactory=usvalue,

without parenthesis.

http://docs.plone.org/external/plone.app.dexterity/docs/advanced/defaults.html

Why not using the existent owner or the Creator value?

To clarify a bit further for people starting out with Dexterity, There's no concept of 'transient', computed or calculated fields in Dexterity, so you can't add these to a schema. The idea is that since we use an object oriented programming language the function/method as listed by zopyx and hvelarde is added to the Class that is the python defintion of every object you create as this Dexterity content type.

When you start out with Dexterity the focus is on defining the fields and how to 'get this schema into Plone', either through the web, in XML-schema or in python schema. In the FTI (Factory Type Information) for a content type (CT) this field schema, the views on that CT and other properties like the mentionned class are bundled.

If work your way through the Plone Training documentation on training.plone.org (pick the dexterity chapters if you're in a hurry) you'll see that in chapter 15 in the FTI the klass property of the conent type is set to plone.dexterity.content.Container which is the base class from which dextery CT's inherit.

If you want to add more to this base class for your own CT, you create a new class, MyContentType, inherit from the base class, add the method for your calculated field as a property and you switch the klass property in the FTI to your own class.

I realise this still is very terse in writing and I skipped a lot, but hopefully it gives other people starting out a bit more context and reference to where to start reading/learning more.

1 Like

The problem with Dexterity that is that approach is completely broken in reality especially when it comes to behaviors (I wrote several blog posts on this issue). Archetypes good or bad...working with Archetypes was already 10 years ago more consistent and straight forward than working with Dexterity nowadays.

-aj

Fortunately Archetypes is still (fully?) supported in Plone 5, so developers can still use Archetypes at least until Plone 6. Or differently stated, we still have 4-5 years to improve Dexterity and get the wrinkles out.

Alas, no framework is perfect and a Dexterity vs Archetypes discussion in this thread will probably not benefit Topic Starter.

On plain schema level this is true, but behaviors are made for this.

In order to stick the users id in a Dexterity style way to the content I'd create a behavior, one field, but do not turn it into a form field provider. The behavior adapter class itself has a r/w property "initial_editor" (or however you like to call it).

Next I'd add a object event subscriber to the behaviors marker interface and IObjectAddedEvent. In the subscriber code do adapt the class with the behaviors adapter interface and use it to set the current users id. Thats it.

Later on in custom view-code the behavior can be used to fetch the value and display it. If it should be displayed somewhere by default a viewlet bound to the behavior marker interface may do the job.