Drupal hacks: 改变CCK的“Add another item”

从今天开始,我要陆续把工作中遇到的一些跟Drupal有关的小问题发上来,希望会给其他同学一些参考。这些问题基本上都是Drupal Core和一些比较常用Contribututed Module衍生出来的,在不修改核心代码的前提下,通过Hook系统或者主题来完成我们想要的效果。

Drupal的CCK模块有一个很方便的特性:多值字段。在field的setting里面,可以选择Number of values。官方的Help是这样描述的:

Maximum number of values users can enter for this field.
‘Unlimited’ will provide an ‘Add more’ button so the users can add as many values as they like.

当选择Unlimited之后,编辑node的时候在这个field的下面会出现一个”Add another item”的按钮。这样用户可以添加无数个这样的字段。我们可以利用这个特性让用户上传无限量的文件,图片。

但是这里有一个问题,这个按钮上面的文字“Add another item”是硬编码到CCK模块里面的,这个不好。我们如果想做一个对用户友好的系统,不能让用户上传普通文件的时候显示”Add another item”, 上传图片的时候还是显示”Add another item”,我希望他们分别显示”Add another file”和”Add another image”。那我们该怎么做呢?

我的思路是:通过hook_form_alter来修改form的值。

function testmodule_form_alter(&$form, $form_state, $form_id) {
  if( $form['#id'] == 'node-form') {
    if(!isset($form['#field_info'])) {
      return;
    }
    foreach($form['#field_info'] as $key => $info) {
      if ( $info['type'] == 'field_image' ) {//假设图片的字段名是field_image
        $form[$key][$key.'_add_more']['#value'] = t('Add another image');
      }
    }
  }

这样图片字段的”Add another item”就变成”Add another image”了。但是这还不够。当你点击”Add another image”之后,这个按钮又变成了”Add another item”了,这是因为这是一个Drupal的AHAH调用。点击按钮触发了另外一个form,这个form的id不是node-form, 而是content_add_more_js。找到原因之后,我们只需要在前面的testmodule_form_alter函数里加上对content_add_more_js的修改:

if( $form_id == 'content_add_more_js' ) {
  foreach($form as $key => $element) {
    if ( isset($element[0]) && isset($element[0]['#type']) && $element[0]['#type'] == 'field_image' ) {
      $form[$key][$key.'_add_more']['#value'] = t('Add another image');
    }
  }
}

好了,大功告成。
最后完整的form_alter是这样的:

function testmodule_form_alter(&$form, $form_state, $form_id) {
  if( $form['#id'] == 'node-form') {
    if(!isset($form['#field_info'])) {
      return;
    }
    foreach($form['#field_info'] as $key => $info) {
      if ( $info['type'] == 'field_image' ) {//假设图片的字段名是field_image
        $form[$key][$key.'_add_more']['#value'] = t('Add another image');
      }
    }
  }
  if( $form_id == 'content_add_more_js' ) {
    foreach($form as $key => $element) {
      if ( isset($element[0]) && isset($element[0]['#type']) && $element[0]['#type'] == 'field_image' ) {
        $form[$key][$key.'_add_more']['#value'] = t('Add another image');
      }
    }
  }

1 Comment

  1. 不错,这种做法很符合drupal的思想,哎,想当初我刚接触drupal没多久的时候,改这个用的是很粗鲁的修改原来的文件…
    现在想想很惭愧…

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*
Get Adobe Flash playerPlugin by wpburn.com wordpress themes