Form API Drupal 7 Drupal でのフォーム作成
これまでのレッスンで、フック hook_block_info()、hook_block_view()、hook_menu()、hook_permission() に触れ、今ではプログラムで必要なだけのページやブロックを作成できるようになりました。このレッスンでは、フォームを作成するための Drupal 7 の Form API を探ります。モジュール機能を管理するためのフォームを構築し、これまで学んだフックをできるだけ多く使ってスキルを固めていきます。
手始めに、3 つのブロックを表示します。これはあなたにとって難しくないはずです。
function sitemade_block_info(){
$blocks = array();
$blocks[1]['info'] = 'User list';
$blocks[2]['info'] = 'Node list';
$blocks[3]['info'] = 'Term list';
return $blocks;
}
function sitemade_block_view($delta = '') {
$block = array();
switch ($delta) {
case 1:
$block['subject'] = 'Users';
$block['content'] = '';
$query = db_select('users', 'u')
->fields('u', array('uid', 'name'))
->orderBy('u.uid', 'DESC')
->range(0, 5)
->execute();
$users = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($users as $user) {
$block['content'] .= '
'; } break; case 2: $block['subject'] = 'Nodes'; $block['content'] = ''; $query = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->orderBy('n.nid', 'DESC') ->range(0, 10) ->execute(); $nodes = $query->fetchAll(PDO::FETCH_ASSOC); foreach ($nodes as $node) { $block['content'] .= '
'; } break; case 3: $block['subject'] = 'Terms'; $block['content'] = ''; $query = db_select('taxonomy_term_data', 't') ->fields('t', array('tid', 'name')) ->orderBy('t.tid', 'DESC') ->range(0, 10) ->execute(); $terms = $query->fetchAll(PDO::FETCH_ASSOC); foreach ($terms as $term) { $block['content'] .= '
'; } break; } return $block; }
新しいブロックが管理インターフェースに表示されるように、キャッシュをクリアします。これらのブロックを左サイドバーに表示します:

次に、これら 3 つのブロックを管理するためのフォームを後で配置する管理ページを作成しましょう:
function sitemade_permission() {
return array(
'admin content blocks' => array(
'title' => t('Admin content blocks'),
'description' => t('Nodes, Users, Terms'),
),
);
}
function sitemade_menu() {
$items = array();
$items['admin/config/content/content_blocks'] = array(
'title' => 'User, node, term blocks',
'description' => 'Block administration',
'page callback' => '_sitemade_content_blocks',
'access arguments' => array('admin content blocks'),
);
return $items;
}
function _sitemade_content_blocks() {
$content = 'Lorem ipsum!';
return $content;
}
ページを作成すると、admin/config/content/content_blocks にプレースホルダーが表示されるはずです:

次に、管理者がこのページを表示できるように権限を設定しましょう(これが hook_permission() を追加した理由です):

では、フックのコードを変更します。まず、管理フォームを作成しましょう。これら 3 つのブロックで何を管理するのでしょうか? ブロックのタイトルと、表示するエンティティ(ノード、ユーザー、用語)の数を設定できるようにすることを提案します。
まず、hook_menu の 'page callback' プロパティを変更します。
function sitemade_menu() {
$items = array();
$items['admin/config/content/content_blocks'] = array(
'title' => 'User, node, term blocks',
'description' => 'Block administration',
'page callback' => 'drupal_get_form',
'page arguments' => array('_sitemade_content_blocks'),
'access arguments' => array('admin content blocks'),
);
return $items;
}
では、フォーム配列を返すように _sitemade_content_blocks() 関数を書き換えます。
function _sitemade_content_blocks() {
$form = array();
$form['nodes-title'] = array(
'#type' => 'textfield',
'#title' => t('Node block title'),
'#default_value' => variable_get('node_block', ''),
'#size' => 60,
'#maxlength' => 64,
'#description' => t('Title for node block'),
);
$form['node-selected'] = array(
'#type' => 'select',
'#title' => t('Nodes in block'),
'#options' => drupal_map_assoc(range(1, 10)),
'#default_value' => variable_get('node_block_range', 5),
'#description' => t('Number of nodes to show'),
);
$form['users-title'] = array(
'#type' => 'textfield',
'#title' => t('User block title'),
'#default_value' => variable_get('user_block', ''),
'#size' => 60,
'#maxlength' => 64,
'#description' => t('Title for user block'),
);
$form['user-selected'] = array(
'#type' => 'select',
'#title' => t('Users in block'),
'#options' => drupal_map_assoc(range(1, 10)),
'#default_value' => variable_get('user_block_range', 5),
'#description' => t('Number of users to show'),
);
$form['terms-title'] = array(
'#type' => 'textfield',
'#title' => t('Term block title'),
'#default_value' => variable_get('term_block', ''),
'#size' => 60,
'#maxlength' => 64,
'#description' => t('Title for term block'),
);
$form['term-selected'] = array(
'#type' => 'select',
'#title' => t('Terms in block'),
'#options' => drupal_map_assoc(range(1, 10)),
'#default_value' => variable_get('term_block_range', 5),
'#description' => t('Number of terms to show'),
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
フォームを表示しました。次はそれを処理する必要があります。処理には、検証と送信のためにそれぞれフック hook_formID_validate() と hook_formID_submit() を使います。
function sitemade_content_blocks_submit($form, &$form_state) {
variable_set('node_block', $form_state['values']['nodes-title']);
variable_set('user_block', $form_state['values']['users-title']);
variable_set('term_block', $form_state['values']['terms-title']);
variable_set('node_block_range', $form_state['values']['node-selected']);
variable_set('user_block_range', $form_state['values']['user-selected']);
variable_set('term_block_range', $form_state['values']['term-selected']);
}
これでフォームの準備ができました。送信後、データは variable_set() を使って保存され、後で variable_get() を使ってデフォルトのフィールド値を設定するのに使われます。

最後に、ブロックのタイトルと一覧に表示する項目数が variable_get() を使って読み込まれるように、hook_block_view() を更新します。
function sitemade_block_view($delta = '') {
$block = array();
switch ($delta) {
case 1:
$block['subject'] = variable_get('user_block', 'Users');
$block['content'] = '';
$query = db_select('users', 'u')
->fields('u', array('uid', 'name'))
->orderBy('u.uid', 'DESC')
->range(0, variable_get('user_block_range', 5))
->execute();
foreach ($query as $user) {
$block['content'] .= '
'; } break; case 2: $block['subject'] = variable_get('node_block', 'Nodes'); $block['content'] = ''; $query = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->orderBy('n.nid', 'DESC') ->range(0, variable_get('node_block_range', 5)) ->execute(); foreach ($query as $node) { $block['content'] .= '
'; } break; case 3: $block['subject'] = variable_get('term_block', 'Terms'); $block['content'] = ''; $query = db_select('taxonomy_term_data', 't') ->fields('t', array('tid', 'name')) ->orderBy('t.tid', 'DESC') ->range(0, variable_get('term_block_range', 10)) ->execute(); foreach ($query as $term) { $block['content'] .= '
'; } break; } return $block; }
これで、フロントページで結果を確認できます。そして忘れないでください:「立ち去る前に――キャッシュをクリア!」
