Adding Memberdata Properties

by Joel Burton last modified Dec 30, 2008 03:01 PM
Contributors: Joel Burton

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.