cck mezo elrejtese

black71 képe

hogyan lehetne megoldani, hogy tartalom bekuldesnel cck mezo jelolheto legyen pl. checkbox -al lathato/nem lathato es "nem lathato" ertket kapott mezo ennek megfeleloen a tartalomban ne jelenjen meg.

tolmi képe

Mondjuk nem tudom nekem miért kell épp checkbox, de nekem csak olyan problémám volt, hogy ha nincs kitöltve a CCK mező, vagy speciálisan van kitöltve, ne tegye ki/jelenítse meg a mezőt.

Erre én ha gyors megoldás kellett, akkor contemplate-et használtam, ha meg volt rá idő, akkor tisztességesen megírtam egy node.tpl.php-t. Mindkettőben lekezelhető a megjelenítés, a contemplate meg segít, hogy egy-egy node-nak milyen változói vannak és még mintaadatot is ad a gyors fejlesztéshez.

Innen már csak egy lépés, hogy ha neked mindenáron checkbox kell, felvedd CCK mezőként az összes érintett mezőre vonatkozó checkboxot és contemplate-ben vagy sminkfájlban lekezeld az értékeiket.

Ui.: Effektíve ha megcsinálod contemplate-ben, akkor már csak egy copy&paste a megfelelő node-neve.tpl.php-ba attól hogy szuper kis megoldásod legyen.

0
0

--
Tolmács Márk
Drupal bandita

black71 képe

node.tpl.php lessz a befuto ha nincs valami kesz megoldas, bar a vegere hagynam nehogy egy esetleges smink csere es feledekenyseg miatt szemelyes adatok legyenek olvashatoak.

0
0

Drupal 5.x, 7.x

pp képe

Éppen ezért már a nodeapi load-jába sem szabad betölteni ezeket. Ezek a mezők nem "nem láthatóak", hanem "nem hozzáférhetőek". Az előbbi egy dizájn kérdés, az utóbb adatvédelmi. A dizájn való csak a sminkbe, az adatvédelemhez meg külön modult kell fejleszteni.

Miért nem készítesz ehhez egy modult? Ami hozzáad egy plusz mezőt nem egy vasziszpúder, mondjuk cck widget-et lenne hozzé érdemes fejelszteni, de itt és most nem egy univerzális, mindenki számára használható, a közösség számára visszaosztott megoldás a cél, hanem egy gyors instant megoldás(nocomment.).

pp

0
0
black71 képe

ez lenne a legjobb, csak egyenlore meg nem latom at a drupal mukodeset, vagyis hogy mi hogyan kapcsolodik egymashoz es igy amit egyebkent egysorral meglehetne oldani agyalok rajta hogyan kezdjek hozza.

0
0

Drupal 5.x, 7.x

pp képe

Nem kell itten agyalni:

http://api.drupal.org/api/file/developer/examples/nodeapi_example.module/5

pp
(ja és nehogy azt mond, hogy nemmegyazangol mert itt php-van azt meg érted ;))

0
0
black71 képe

ez a link azonos az api modullal?

0
0

Drupal 5.x, 7.x

aries képe

Nem, egy példa a dokumentációból.

0
0
pp képe

Ez nem egy modul, hanem egy tutorial, ami bemutatja hogyan tudsz adat elemeket hozzáadni egy node-hoz. adatbázis táblát létre kell hoznod hozzá

CREATE TABLE nodeapi_example (
nid int(10) unsigned NOT NULL default '0',
rating int(10) unsigned NOT NULL default '0',
PRIMARY KEY (nid)
)

pp
0
0
black71 képe

nem volt elerheto az url.

latom hogy valami szavazos tutorial, ki/be kapcsolasi lehetoseggel.

nem ertem az egeszet.
pl. azt ertem hogy a theme_nodeapi_example_rating() erteket a templatenek adja at, de az erteket honnan kapja? ilyen es ehez hasonlo dolgok miatt nem megy egyenlore. nem eleg ha csak ossze kattintgatasbol all a drupal tudomany, illetve az sem ha php-ban megtud irni valamit az ember.

0
0

Drupal 5.x, 7.x

aries képe

Teljesen igaz, javaslom a fejlesztői dokumentációk elolvasását először a drupal.org-on. Utána világos lesz.

0
0
black71 képe

A tutorial hibas

$form['workflow']['nodeapi_example_'. $type] = array(
// csere a kovetkezore
$form['workflow']['nodeapi_example'] = array(

jelentkezem ha valami nem megy.
thx az eddigieket.

0
0

Drupal 5.x, 7.x

pp képe

Én (mivel az aláírásodban Drupal 5.10 szerepel) az ötöshöz tartozó linket küldtem. Nem lehet, hogy hatos Drupal-on kísérletezgetsz?
Mi volt a hibajelenség?

pp

0
0
black71 képe

az adatbazisba a fentebb irt $type valtozo meglete miatt a variable tablaba helytelenul kerul bejegyzesre a sor pl. private_field_page_page es emiatt az ellenorzesnel elhasal mivel a private_field_page -et keresi.
egyebkent teljesen hasznalhatatlan volt az egesz mindaddig mig a nodeapi_example nevet nem csereltem le. ezt igazan en sem ertettem hogy miert.

0
0

Drupal 5.x, 7.x

Pasqualle képe

0
0
black71 képe

az a modul teljesen eltuntet mezoket az arra nem jogosultak elol, es ez minden node -ra ervenyes es a lathatosagot csak az admin tudja befojasolni.

0
0

Drupal 5.x, 7.x

black71 képe

elkeszitettem a tutorial alapjan a Private Filed nevu modult, bar meg ez nem cck -s mezo hatha valakinek jol jon.
a fajlokat a private_field nevu konyvtarba kell tenni.

private_field.info fajl tartalma:

name = Private Field
description = Defines simple private text field types.
package = Private
version = "5.x-1"
project = "drupal"

private_field.install fajl tartalma:

/**
 * Implementation of hook_install().
 */
 
function private_field_install() {
	switch ($GLOBALS['db_type']) {
		case 'mysql':
		case 'mysqli':
			$query = db_query("CREATE TABLE IF NOT EXISTS {private_field} (
			`nid` INT UNSIGNED NOT NULL DEFAULT '0',
			`pf_text` VARCHAR( 255 ) NULL ,
			`pf_option` INT UNSIGNED NOT NULL DEFAULT '0',
			PRIMARY KEY (`nid`)
			) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
		break;
	}
 
	/**
	 * Vizsgálat a sikeres adatbázis tábla készítésre
	 */
	$query?drupal_set_message(t('Privát mező telepítése sikeres.')):drupal_set_message(t('Privát mező telepítése sikertelen.'));
}
 
function private_field_uninstall() {
	db_query('DROP TABLE {private_field}');
	db_query("DELETE FROM {variable} WHERE name like 'private_field%'");
}

private_field.module fajl tartalma:

function private_field_form_alter($form_id, &$form) {
	if (isset($form['type'])) {
		$type = $form['type']['#value'];
	} elseif (isset($form['orig_type'])) {
		$type = $form['orig_type']['#value'];
	} else {
		return;
	}
 
	$enabled = variable_get('private_field_'. $type, 0);
 
	switch ($form_id) {
		case 'node_type_form':
		$form['workflow']['private_field'] = array(
		'#type' => 'radios',
		'#title' => t('Privát mező'),
		'#default_value' => $enabled,
		'#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
		'#description' => t('Felhasználó szabályozhatja a mező láthatóságát.'),
		);
		break;
 
		case $type .'_node_form':
		if ($enabled) {
			$form['private_field_text'] = array(
			'#type' => 'textfield',
			'#title' => t('Privát mező'),
			'#required' => TRUE,
			'#default_value' => $form['#node']->private_field_text,
			'#size' => 30,
			'#maxlength' => 255,
			'#weight' => 0,
			);
			$form['private_field_option'] = array(
			'#type' => 'radios',
			'#title' => t('Privát mező beállítás'),
			'#default_value' => $form['#node']->private_field_option,
			'#options' => array(0 => t('Kikapcsolva'), 1 => t('Bekapcsolva')),
			'#description' => t('Bekapcsolva a "Privát mező" értékét csak tartalom szerzője látja.'),
			'#weight' => 0,
			);
		}
		break;
	}
}
 
 
function private_field_nodeapi(&$node, $op, $teaser, $page) {
	switch ($op) {
 
		case 'load':
		$object = db_fetch_object(db_query('SELECT pf_text, pf_option FROM {private_field} WHERE nid = %d', $node->nid));
		return array('private_field_text' => $object->pf_text, 'private_field_option' => $object->pf_option);
		break;
 
		case 'insert':
		db_query("INSERT INTO {private_field} (nid, pf_text, pf_option) VALUES (%d, '%s', %d)", $node->nid, $node->private_field_text, $node->private_field_option);
		break;
 
		case 'update':
		db_query('DELETE FROM {private_field} WHERE nid = %d', $node->nid);
		db_query("INSERT INTO {private_field} (nid, pf_text, pf_option) VALUES (%d, '%s', %d)", $node->nid, $node->private_field_text, $node->private_field_option);
		break;
		case 'delete':
		db_query('DELETE FROM {private_field} WHERE nid = %d', $node->nid);
		break;
 
		case 'view':
		global $user;
		$text = false;
		if (!$node->private_field_option || ($user->uid == $node->uid)) {
			$text = $node->private_field_text;
		}
		$node->content['private_field'] = array(
		'#value' => theme('private_field_text', $text),
		'#weight' => -1,
		);
		break;
	}
}
 
 
function theme_private_field_text($text) {
	$output = false;
	if(!empty($text)) {
		$output .= '<div class="private_field_text">';
		$output .= t($text);
		$output .= '</div>';
	}
	return $output;
}

a modul telepitese utan a tartalom tipusnal lehet beallitani a tipushoz.

0
0

Drupal 5.x, 7.x

tolmi képe

Mi lenne ha beraknád a drupal.org-ra mint modult?

0
0

--
Tolmács Márk
Drupal bandita

black71 képe

olvasni es halgatni tudok angolul (ertem is), de beszelni es irni nem tudok :)
a masik ok nincs benne megjegyzes, leiras stb..

0
0

Drupal 5.x, 7.x

black71 képe

az eredeti cck -s text mezot modositva elkeszitettem a cck -hoz a Private Field modult.

keszitsd el a cck_private_field konyvtarat es masold be a fajlokat.

cck_private_field.info fajl:

name = CCK Private Field
description = Defines private field types.
dependencies = content
package = CCK
 
version = "5.x-1"
project = "private"

cck_private_field.module fajl:

// $Id: text.module,v 1.41.2.16 2008/03/21 23:52:35 yched Exp $
 
/**
 * @file
 * Defines simple text field types.
 */
 
/**
 * Implementation of hook_field_info().
 */
function cck_private_field_field_info() {
  return array(
    'cck_private_field' => array('label' => t('Private')),
  );
}
 
/**
 * Implementation of hook_field_settings().
 */
function cck_private_field_field_settings($op, $field) {
  switch ($op) {
    case 'form':
      $form = array();
      $options = array(0 => t('Plain text'), 1 => t('Filtered text (user selects input format)'));
      $form['cck_private_field_processing'] = array(
        '#type' => 'radios',
        '#title' => t('Text processing'),
        '#default_value' => isset($field['cck_private_field_processing']) ? $field['cck_private_field_processing'] : 0,
        '#options' => $options,
      );
      $form['max_length'] = array(
        '#type' => 'textfield',
        '#title' => t('Maximum length'),
        '#default_value' => isset($field['max_length']) ? $field['max_length'] : '',
        '#required' => FALSE,
        '#description' => t('The maximum length of the field in characters. Leave blank for an unlimited size.'),
      );
      $form['allowed_values'] = array(
        '#type' => 'textarea',
        '#title' => t('Allowed values list'),
        '#default_value' => isset($field['allowed_values']) ? $field['allowed_values'] : '',
        '#required' => FALSE,
        '#rows' => 10,
        '#description' => t('The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database and it must match the field storage type, %type. The label is optional and the key will be used as the label if no label is specified.', array('%type' => $field['type'])),
      );
      $form['advanced_options'] = array(
        '#type' => 'fieldset',
        '#title' => t('PHP code'),
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
      );
      $form['advanced_options']['allowed_values_php'] = array(
        '#type' => 'textarea',
        '#title' => t('Code'),
        '#default_value' => $field['allowed_values_php'],
        '#rows' => 6,
        '#description' => t('Advanced Usage Only: PHP code that returns a keyed array of allowed values. Should not include &lt;?php ?&gt; delimiters. If this field is filled out, the array returned by this code will override the allowed values list above.'),
      );
      return $form;
 
    case 'save':
      return array('cck_private_field_processing', 'max_length', 'allowed_values', 'allowed_values_php');
 
    case 'database columns':
      $columns = array(
        'value' => array('type' => 'varchar', 'not null' => TRUE, 'default' => "''", 'sortable' => TRUE),
        'format' => array('type' => 'int', 'length' => 10, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
        'pf_option' => array('type' => 'int', 'length' => 10, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
      );
      if ($field['max_length'] == 0 || $field['max_length'] > 255) {
        $columns['value']['type'] = 'longtext';
      }
      else {
        $columns['value']['length'] = $field['max_length'];
      }
      if ($field['cck_private_field_processing'] == 0) {
        unset($columns['format']);
      }
      return $columns;
 
    case 'arguments':
      $arguments = content_views_field_arguments($field);
      $alias = "content: $field[field_name]";
      $argument = array(
        'handler' => 'cck_private_field_views_argument_handler',
        'option' => 'string',
        'help' => t('Set the option to the number of initial characters to filter by. Leave empty for full term; use 1 for an A/B/C style glossary.'),
      );
      $arguments[$alias] = array_merge($arguments[$alias], $argument);
      return $arguments;
 
    case 'filters':
      $allowed_values = cck_private_field_allowed_values($field);
       if (count($allowed_values)) {
         return array(
           'default' => array(
            'list' => $allowed_values,
             'list-type' => 'list',
             'operator' => 'views_handler_operator_andor',
             'value-type' => 'array',
            ),
          );
        }
      else {
        return array(
          'like' => array(
            'operator' => 'views_handler_operator_like',
            'handler' => 'views_handler_filter_like',
          ),
        );
      }
      break;
  }
}
 
function cck_private_field_views_argument_handler($op, &$query, $argtype, $arg = '') {
  $name = explode(':', is_array($argtype) ? $argtype['type'] : $argtype);
  $field_name = trim($name[1]);
  $field      = content_fields($field_name);
  $db_info    = content_database_info($field);
  $value      = $db_info['columns']['value']['column'];
  $table      = 'node_data_'. $field['field_name'];
 
  switch($op) {
    case 'summary':
      $query->ensure_table($table);
      $query->add_field($value, $table);
 
      $length = intval($arg);
      $fieldinfo['field'] = $length <= 0 ? "$table.$value" : "LEFT($table.$value, $length)";
      $fieldinfo['fieldname'] = 'letter';
      return $fieldinfo;
 
    case 'sort':
      break;
 
    case 'filter':
      $query->ensure_table($table);
      $query->add_field($value, $table);
 
      $length = intval($argtype['options']);
      $where = $length <= 0 ? "$table.$value = '%s'" : "LEFT($table.$value, $length) = '%s'";
      $query->add_where($where, $arg);
      break;
 
    case 'link':
      return l(strtoupper($query->letter), "$arg/$query->letter");
 
    case 'title':
      return check_plain(strtoupper($query));
  }
}
 
/**
 * Implementation of hook_field().
 */
function cck_private_field_field($op, &$node, $field, &$items, $teaser, $page) {
  switch ($op) {
    case 'validate':
      $allowed_values = cck_private_field_allowed_values($field);
 
      if (is_array($items)) {
        foreach ($items as $delta => $item) {
          $error_field = $field['field_name'] .']['. $delta .'][value';
          if ($item['value'] != '') {
            if (count($allowed_values) && !array_key_exists($item['value'], $allowed_values)) {
              form_set_error($error_field, t('Illegal value for %name.', array('%name' => t($field['widget']['label']))));
            }
          }
        }
      }
      if ($field['max_length'] > 0) {
        foreach ($items as $delta => $data) {
          $error_field = $field['field_name'] .']['. $delta .'][value';
          if (strlen($data['value']) > $field['max_length']) {
            form_set_error($error_field, t('%label is longer than %max characters.', array('%label' => $field['widget']['label'], '%max' => $field['max_length'])));
          }
        }
      }
      break;
  }
}
 
/**
 * Implementation of hook_field_formatter_info().
 */
function cck_private_field_field_formatter_info() {
  return array(
    'default' => array(
      'label' => t('Default'),
      'field types' => array('cck_private_field'),
    ),
    'plain' => array(
      'label' => t('Plain text'),
      'field types' => array('cck_private_field'),
    ),
    'trimmed' => array(
      'label' => t('Trimmed'),
      'field types' => array('cck_private_field'),
    ),
  );
}
 
/**
 * Implementation of hook_field_formatter().
 *
 * The $node argument is necessary so that filter access can be checked on
 * node preview.
 */
function cck_private_field_field_formatter($field, $item, $formatter, $node) {
  global $user;
  if (!$item['pf_option'] || ($user->uid == $node->uid) || user_access("access administration pages")) {
  	if (!isset($item['value'])) {
  		return '';
  	}
  } else {
  	return '';
  }
 
  if ($allowed_values = cck_private_field_allowed_values($field)) {
    return $allowed_values[$item['value']];
  }
 
  switch ($formatter) {
    case 'plain':
      $text = strip_tags($item['value']);
      break;
 
    case 'trimmed':
      $text = node_teaser($item['value'], $field['cck_private_field_processing'] ? $item['format'] : NULL);
      break;
 
    case 'default':
      $text = $item['value'];
  }
  if ($field['cck_private_field_processing']) {
    return check_markup($text, $item['format'], is_null($node) || isset($node->in_preview));
  }
  else {
    return check_plain($text);
  }
}
 
 
/**
 * Implementation of hook_widget_info().
 */
function cck_private_field_widget_info() {
  return array(
    'cck_private_field' => array(
      'label' => t('Private Text Field'),
      'field types' => array('cck_private_field'),
    ),
  );
}
 
/**
 * Implementation of hook_widget_settings().
 */
function cck_private_field_widget_settings($op, $widget) {
  switch ($op) {
    case 'form':
      $form = array();
      $form['rows'] = array(
        '#type' => 'textfield',
        '#title' => t('Rows'),
        '#default_value' => $widget['rows'] ? $widget['rows'] : 1,
        '#required' => TRUE,
      );
      return $form;
 
    case 'validate':
      if (!is_numeric($widget['rows']) || intval($widget['rows']) != $widget['rows'] || $widget['rows'] <= 0) {
        form_set_error('rows', t('"Rows" must be a positive integer.'));
      }
      break;
 
    case 'save':
      return array('rows');
  }
}
 
/**
 * Implementation of hook_widget().
 */
function cck_private_field_widget($op, &$node, $field, &$items) {
  switch ($op) {
    case 'form':
      $form = array();
      $pf_option = array();
 
      $form[$field['field_name']] = array('#tree' => TRUE);
 
      if ($field['multiple']) {
        $form[$field['field_name']]['#type'] = 'fieldset';
        $form[$field['field_name']]['#description'] = t($field['widget']['description']);
        $delta = 0;
        foreach ($items as $data) {
          if ($data['value']) {
            if ($field['widget']['rows'] == 1) {
              $form[$field['field_name']][$delta]['value'] = array(
                '#type' => 'textfield',
                '#title' => ($delta == 0) ? t($field['widget']['label']) : '',
                '#default_value' => $data['value'],
                '#required' => ($delta == 0) ? $field['required'] : FALSE,
                '#maxlength' => $field['max_length'] ? $field['max_length'] : NULL,
                '#weight' => $field['widget']['weight'],
              );
            }
            else {
              $form[$field['field_name']][$delta]['value'] = array(
                '#type' => 'textarea',
                '#title' => ($delta == 0) ? t($field['widget']['label']) : '',
                '#default_value' => $data['value'],
                '#required' => ($delta == 0) ? $field['required'] : FALSE,
                '#rows' => $field['widget']['rows'],
                '#weight' => $field['widget']['weight'],
              );
            }
            if ($field['cck_private_field_processing']) {
              $form[$field['field_name']][$delta]['format'] = filter_form($data['format'], $form[$field['field_name']][$delta]['value']['#weight'] + 1, array($field['field_name'], $delta, 'format'));
            }
            $pf_option[] = $delta;
            $delta++;
          }
        }
        foreach (range($delta, $delta + 2) as $delta) {
          if ($field['widget']['rows'] == 1) {
            $form[$field['field_name']][$delta]['value'] = array(
              '#type' => 'textfield',
              '#title' => ($delta == 0) ? t($field['widget']['label']) : '',
              '#default_value' => '',
              '#required' => ($delta == 0) ? $field['required'] : FALSE,
              '#maxlength' => $field['max_length'] ? $field['max_length'] : NULL,
              '#weight' => $field['widget']['weight'],
            );
          }
          else {
            $form[$field['field_name']][$delta]['value'] = array(
              '#type' => 'textarea',
              '#title' => ($delta == 0) ? t($field['widget']['label']) : '',
              '#default_value' => '',
              '#required' => ($delta == 0) ? $field['required'] : FALSE,
              '#rows' => $field['widget']['rows'],
              '#weight' => $field['widget']['weight'],
            );
          }
          if ($field['cck_private_field_processing']) {
            $form[$field['field_name']][$delta]['format'] = filter_form($items[$delta]['format'], $form[$field['field_name']][$delta]['value']['#weight'] + 1, array($field['field_name'], $delta, 'format'));
          }
          $pf_option[] = $delta;
        }
      }
      else {
        if ($field['widget']['rows'] == 1) {
          $form[$field['field_name']][0]['value'] = array(
            '#type' => 'textfield',
            '#title' => t($field['widget']['label']),
            '#default_value' => isset($items[0]['value']) ? $items[0]['value'] : '',
            '#required' => $field['required'],
            '#description' => t($field['widget']['description']),
            '#maxlength' => $field['max_length'] ? $field['max_length'] : NULL,
            '#weight' => $field['widget']['weight'],
          );
        }
        else {
          $form[$field['field_name']][0]['value'] = array(
            '#type' => 'textarea',
            '#title' => t($field['widget']['label']),
            '#default_value' => $items[0]['value'],
            '#required' => $field['required'],
            '#rows' => $field['widget']['rows'],
            '#description' => t($field['widget']['description']),
            '#weight' => $field['widget']['weight'],
          );
        }
        if ($field['cck_private_field_processing']) {
          $form[$field['field_name']][0]['format'] = filter_form($items[0]['format'], $form[$field['field_name']][0]['value']['#weight'] + 1, array($field['field_name'], 0, 'format'));
        }
        $pf_option[] = 0;
      }
 
      foreach ($pf_option as $v) {
      	$form[$field['field_name']][$v]['pf_option'] = array(
      	'#type' => 'radios',
      	'#title' => t('Private option'),
      	'#default_value' => $items[$v]['pf_option']?$items[$v]['pf_option']:0,
      	'#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
      	'#description' => t('Bekapcsolva a "Privát mező" értékét csak tartalom szerzője látja.'),
      	);
      }
      return $form;
 
    case 'process form values':
      // Don't save empty fields except the first value
      foreach ($items as $delta => $item) {
        if ($item['value'] == '' && $delta > 0) {
          unset($items[$delta]);
        }
      }
      break;
  }
}
 
/**
 *  Create an array of the allowed values for this field
 */
function cck_private_field_allowed_values($field) {
  static $allowed_values;
 
  if ($allowed_values[$field['field_name']]) {
    return $allowed_values[$field['field_name']];
  }
 
  $allowed_values[$field['field_name']] = array();
  if ($field['allowed_values_php']) {
    ob_start();
    $result = eval($field['allowed_values_php']);
    if (is_array($result)) {
      $allowed_values[$field['field_name']] = $result;
    }
    ob_end_clean();
  }
  if (!$allowed_values[$field['field_name']]) {
 
    $list = explode("\n", $field['allowed_values']);
    $list = array_map('trim', $list);
    $list = array_filter($list, 'strlen');
    foreach ($list as $opt) {
      list($key, $value) = explode('|', $opt);
      $allowed_values[$field['field_name']][$key] = $value ? $value : $key;
    }
  }
  return $allowed_values[$field['field_name']];
}

a privatra allitott mezo tartalmat a szerzo es az admin latja.

0
0

Drupal 5.x, 7.x