Personal tools
You are here: Home Documentation How-tos Adding Memberdata Properties
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Adding Memberdata Properties

This How-to applies to: Any version.
This How-to is intended for: Integrators, Customizers

Adding new properties to members and having them appear on the membership preference forms.

The memberdata storage policy is the responsibility of the portal_memberdata tool/component. This tool is responsible for listing what attributes you are storing on the Member's (using a PropertyManager interface) and how they are stored (on the portal_memberdata as a BTree Object). So lets say for instance we want to store a boolean called, 'subscribe' and a 'favorite_food' string. This is the same way you would do it in CMF as well--except your HTML would be a tad simpler and you have to do the validation manually.

  • open up the /manage (Zope Management Interface, aka ZMI) of the Plone site in your browser.

  • select the portal_memberdata tool in the ZMI and click the Properties tab

    • Name: subscribe Value: 1 Type: boolean
    • Name: favorite_food Value: Type: string
  • now we must customize the personalize_form. This is not being automatically generated (yet) so you will end up having to type lots of boilerplate code.

    • go to plone_prefs/personalize_form and click Customize

    • now below visible_ids DIV you will want to paste the following code:

      <div class="row">
          <div class="label">
              <span i18n:translate="label_display_names">Subscribe</span>
      
              <div id="subscribe_help"
                   i18n:translate="help_subscribe" 
                   class="help" 
                   style="visibility:hidden">
              Allows you to opt-in or opt-out of the newsletter subscription service.
              </div>                
          </div>
          <div class="field"
                   tal:define="subscribe python:request.get('subscribe', member.getProperty('subscribe'));
                               tabindex tabindex/next;"> 
              <input type="radio" 
                     class="noborder" 
                     name="subscribe" 
                     value="on"
                     id="cb_subscribe" 
                     checked="checked"
                     tabindex=""
                     onfocus="formtooltip('subscribe_help',1)" 
                     onblur="formtooltip('subscribe_help',0)"
                     tal:attributes="tabindex tabindex;" 
                     tal:condition="subscribe" 
                     />
              <input type="radio" 
                     class="noborder" 
                     name="subscribe" 
                     value="on"
                     id="cb_subscribe"
                     tabindex=""
                     onfocus="formtooltip('subscribe_help',1)" 
                     onblur="formtooltip('subscribe_help',0)" 
                     tal:attributes="tabindex tabindex;" 
                     tal:condition="not: subscribe" 
                     />
              
              <label for="cb_subscribe" i18n:translate="yes">Yes</label>
              
              <br />
              
              <input type="radio" 
                     class="noborder" 
                     name="subscribe" 
                     value=""
                     id="cb_unsubscribe"
                     tabindex=""
                     onfocus="formtooltip('subscribe_help',1)" 
                     onblur="formtooltip('subscribe_help',0)" 
                     tal:attributes="tabindex tabindex;" 
                     tal:condition="subscribe" 
                     />
              
              <input type="radio" 
                     class="noborder" 
                     name="subscribe" 
                     value=""
                     id="cb_unsubscribe" 
                     checked="checked"
                     tabindex=""
                     onfocus="formtooltip('subscribe_help',1)" 
                     onblur="formtooltip('uubscribe_help',0)" 
                     tal:attributes="tabindex tabindex;" 
                     tal:condition="not: subscribe" 
                     />                                  
              <label for="cb_unsubscribe" i18n:translate="no">No</label>
          </div>
      </div>
      <div class="row"
           tal:define="error_favorite_food errors/favorite_food | nothing;
                       favorite_food python:request.get('favorite_food', member.getProperty('favorite_food'));">
          <div class="label">
              <span i18n:translate="label_favorite_food">Favorite Food</span>
              <div id="favorite_food_help"
                   i18n:translate="help_favorite_food" 
                   class="help" 
                   style="visibility:hidden">
              You can change your favorite food here.
              </div>
          </div>                
          <div class="field" tal:attributes="class python:test(error_favorite_food, 'field error', 'field')"> 
              <div tal:condition="error_favorite_food" 
                   tal:replace="structure string:$error_favorite_food <br />" />                                    
              <input type="text" 
                     name="favorite_food" 
                     size="25"
                     tabindex=""
                     value="member.favorite_food html_quote"
                     onfocus="formtooltip('full_name_help',1)" 
                     onblur="formtooltip('full_name_help',0)" 
                     tal:attributes="value favorite_food;
                                     tabindex tabindex/next;" />
          </div>
      </div>
      
  • if you wanted to make favorite_food a required field you would edit the validate_personalize script in plone_scripts/form_scripts/validate_personalize and you could add validation rules to it. You will notice that the validation is wired up to the form for this field.

Note: This can also be done with CMFMember, which adds additional capabilities, such as workflow, to members, but at the cost of higher complexity.

by Joel Burton last modified February 7, 2006 - 13:03 All content is copyright Plone Foundation and the individual contributors.

Select/Multi-select value

Posted by Jock Coats at July 15, 2006 - 16:53

I notice you don't cover the select/multi-select type here, but I wonder if you would know - what I would like to do is to have a field that retrieves a list of groups for the user to select from. Is this possible using this mechanism of adding portal_memberdata properties or do I need to get more complicated (membrane, remember, CMFMember subclassing or whatever?)

Select values

Posted by Joel Burton at September 12, 2006 - 13:34
No, there's no need to use CMFMember (which, sadly, won't work with PAS and Plone 2.5) or membrane/remembmer (which, AFAICT, aren't yet really working software) for this.

The solution described above is just rolling our own form changes for new fields; if you want to have a list of groups coming from somewhere for a drop-down menu, you can just query the groups_tool for that (see the API for the groups tool; you can ask it for the list of groups).

Keep in mind that the overall goal here was to show you how to add new _memberdata_properties_; if you want to assign a user to group(s), you could gather that info on the membership preference form, but you wouldn't add it to the portal_memberdata tool; instead, you'd want to use the API (also findable on the groups_tool) for add-a-member-to-a-group.

Location of validate_personalize script

Posted by Chris Bier at July 24, 2006 - 20:48

plone_scripts/form_scripts/validate_personalize

is

portal_skins/plone_form_scripts/validate_personalize

in Plone 2.1.3 and possibly others

This recipe was written in Plone 1.0 days

Posted by Joel Burton at September 12, 2006 - 13:36
None of the concepts are outdated, but, yes the validation script has moved.

Also, the preferred CSS class names for forms changed since this was written; the HTML should be updated to use the nicer-style, newer stuff. Just take a look at hthe existing personalize_form and you can see that the div blocks for each field on an HTML form are slightly different.

how does custom fields relate to LDAP users?

Posted by Maurizio Pinotti at September 11, 2006 - 07:40
first of all, thanks for this paper, I found it very useful!

but my goal goes further: I want to bind the custom field I created to an LDAP attribute. I am using LDAPUserFolder to add Plone users from an LDAP, and this LDAP has an "e-mail" attribute for all users. I want to read the value from the LDAP and put it in the "e-mail" field of Plone, and vice-versa: I want to overwrite the LDAP attribute whenever the user changes his/her Plone e-mail!

is it possible to do such a thing?

It is possible; it's not directly related

Posted by Joel Burton at September 12, 2006 - 13:40
You can store user memberdata in LDAP; you'll have to seek help in a different place for this.

However, adding _new_ memberdata fields doesn't change this; if you're using LDAP for your memberdata storage, your new fields will be stored as well. This recipe just demonstrates how to add new fields to memberdata and put them on the form/validation/script.

Plone 2.5 corrections

Posted by Jacob Nordfalk at October 22, 2006 - 20:28
In Plone 2.5 the code is in portal_skins/custom/personalize_form and should be:



<div class="field"
tal:define="subscribe python:request.get('subscribe', member.getProperty('subscribe'));">
<label for="subscribe" i18n:translate="label_subscribe">Subscribe</label>

<br/>
<input type="radio"
class="noborder"
name="subscribe"
value="on"
id="cb_subscribe"
checked="checked"
tabindex=""
onfocus="formtooltip('subscribe_help',1)"
onblur="formtooltip('subscribe_help',0)"
tal:attributes="tabindex tabindex;"
tal:condition="subscribe"
/>

<input type="radio"
class="noborder"
name="subscribe"
value="on"
id="cb_subscribe"
tabindex=""
onfocus="formtooltip('subscribe_help',1)"
onblur="formtooltip('subscribe_help',0)"
tal:attributes="tabindex tabindex;"
tal:condition="not: subscribe"
/>


<label for="cb_subscribe" i18n:translate="yes">Yes</label>




<input type="radio"
class="noborder"
name="subscribe"
value=""
id="cb_unsubscribe"
tabindex=""
onfocus="formtooltip('subscribe_help',1)"
onblur="formtooltip('subscribe_help',0)"
tal:attributes="tabindex tabindex;"
tal:condition="subscribe"
/>

<input type="radio"
class="noborder"
name="subscribe"
value=""
id="cb_unsubscribe"
checked="checked"
tabindex=""
onfocus="formtooltip('subscribe_help',1)"
onblur="formtooltip('uubscribe_help',0)"
tal:attributes="tabindex tabindex;"
tal:condition="not: subscribe"
/>
<label for="cb_unsubscribe" i18n:translate="no">No</label>
</div>





<div class="field"
tal:define="error_favorite_food errors/favorite_food | nothing;
favorite_food python:request.get('favorite_food', member.getProperty('favorite_food'));">

<label for="fullname" i18n:translate="label_favorite_food">Favorite Food</label>

<div class="formHelp" i18n:translate="help_favorite_food">
You can change your favorite food here.
</div>
<input type="text"
name="favorite_food"
size="25"
tabindex=""
value="member.favorite_food html_quote"
tal:attributes="value favorite_food;" />


<div class="field" tal:attributes="class python:test(error_favorite_food, 'field error', 'field')">
<div tal:condition="error_favorite_food"
tal:replace="structure string:$error_favorite_food <br />" />
</div>
</div>




Plone 2.5 corrections

Posted by Jacob Nordfalk at October 22, 2006 - 20:46
Sorry, its in portal_skins/plone_prefs/personalize_form

Thanks for the code and instructions, next step....

Posted by Lucas Gates at June 4, 2007 - 17:16
I am a beginner Plone admin and I've cut and pasted the code and can see the radio buttons/field on the Personal Preferences form. What should I do now to have the user's entry store in the corresponding table, etc.? If this info was already covered in this topic, I apologize. Not being very familiar with Plone nomenclature has limited me in this manner. Thanks!

Displaying the new properties

Posted by Mike Combs at October 11, 2007 - 22:02
If you'd like to display the new member properties when people search for users, customize the 'portal_skins/plone_forms/member_search_results' page template.

You'll see the code that displays the user's "card". Just add lines to it to look up the member from the userid, then access the properties you've added (in this example, phone_day)::

<div class="card" tal:define="userid result/getMemberId;
home python:container.portal_membership.getHomeUrl(userid, verifyPermission=1);
portrait python: here.portal_membership.getPersonalPortrait(userid);
member python:mtool.getMemberById(userid);
tFullname python:member.getProperty('fullname');
tLocation python:member.getProperty('location');
tPhone python:member.getProperty('phone_day');">

Then, just display the properties as part of the card::

<a href="#" tal:attributes="href home">
<img src="defaultUser.gif"
alt=""
border="0"
width="75"
height="100"
tal:attributes="src portrait/absolute_url" />
<br />
<span tal:content="tFullname">John Doe</span>
</a>
<br />
<span tal:content="tLocation">Boston, MA</span><br />
<span tal:content="tPhone">978/555-1212</span>
</div>

Setting properties when a user joins

Posted by Mike Combs at October 11, 2007 - 22:12
If you want to give users the opportunity to fill in their preferences/properties when they join the site, add the fields to 'portal_skins/plone_login/join_form'.

to add a boolean property

Posted by ento at February 1, 2008 - 04:57
(Plone 2.5.3)

I had to customize portal_skins/plone_form_scripts/personalize to make the personalize_form work with a custom boolean member property. Assuming the property name is 'has_apple'

* Add to the Parameter List: has_apple=None
* Insert the following code:

if has_apple is None and REQUEST is not None:
has_apple=0
else:
has_apple=1
REQUEST.set('has_apple', has_apple)

Without this, personalize_form did not update the member data and the checkbox appeared always on (= the default property value).

one more line..

Posted by ento at February 1, 2008 - 09:45
modify one more line in portal_skins/plone_form_scripts/personalize

member.setProperties(listed=listed, ext_editor=ext_editor, visible_ids=visible_ids, has_apple=has_apple)

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by