Form API Drupal 7 kreiranje formi na Drupalu
U prethodnim lekcijama upoznali smo se sa hook-ovima hook_block_info(), hook_block_view(), hook_menu(), hook_permission() i sada možemo programski kreirati koliko god želimo stranica i blokova. U ovoj lekciji upoznaćemo se sa Form API Drupal 7 za kreiranje formi. Napravićemo formu za administraciju funkcija modula i pokušati koristiti što više poznatih hook-ova kako bismo učvrstili znanja.
Za početak ćemo prikazati 3 bloka, mislim da vam to neće biti teško.
function sitemade_block_info(){
$blocks = array(); // inicijalizujemo prazan niz
$blocks[1]['info'] = 'Spisak korisnika'; // naslov bloka za admin panel
$blocks[2]['info'] = 'Spisak nodova';
$blocks[3]['info'] = 'Spisak termina';
return $blocks; // vraćamo spisak blokova
}
function sitemade_block_view($delta = ''){
$block = array(); // inicijalizujemo prazan niz za blok
switch ($delta){
case 1: // ista delta kao u hook_block_info()
$block['subject'] = 'Korisnici'; // prikazujemo naslov bloka
$block['content'] = ''; // inicijalizujemo praznu string promenljivu
$query = db_select('users', 'u') // upit za izbor korisnika
->fields('u', array('uid', 'name')) // biramo polja
->orderBy('u.uid', 'DESC') // sortiramo opadajuće
->range(0, 5) // biramo pet korisnika
->execute(); // izvršavamo upit
$users = $query->fetchAll(PDO::FETCH_ASSOC); // dobijamo rezultat kao niz
foreach($users as $user){
$block['content'] .='
'; // base_path() vraća putanju do korena sajta } break; case 2: $block['subject'] = 'Nodovi'; // naslov bloka $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'] = 'Termini'; // naslov bloka $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; }
Očistite keš da bi se naši novi blokovi pojavili u admin panelu. Prikažite ove blokove u levom sidebar-u:

Sada napravimo stranicu u admin panelu gde ćemo kasnije staviti formu za administraciju ovih blokova:
function sitemade_permission(){
return array(
'admin content blocks' => array(
'title' => t('Admin content blocks'),
'description' => t('Nodes, Users, Terms'),
),
);
}
function sitemade_menu(){
$items = array(); // inicijalizujemo niz menija
$items['admin/config/content/content_blocks'] = array(
'title' => 'Blokovi korisnika, nodova, termina',
'description' => 'Administracija blokova',
'page callback' => '_sitemade_content_blocks',
'access arguments' => array('admin content blocks'),
);
return $items; // vraćamo spisak stranica
}
function _sitemade_content_blocks(){
$content = 'Lorem ipsum!';
return $content;
}
Stranica je kreirana, trebalo bi da se pojavi placeholder na adresi admin/config/content/content_blocks:

Takođe podesimo dozvole za administratora da vidi ovu stranicu (za to smo koristili hook_permission()).

Sada ćemo menjati kod hook-ova. Prvo napravimo formu za administraciju. Šta ćemo administrirati u ovim blokovima? Predlažem naslov bloka i broj prikazanih entiteta (nodova, korisnika, termina).
Prvo ćemo promeniti svojstvo 'page callback' u hook_menu:
function sitemade_menu(){
$items = array();
$items['admin/config/content/content_blocks'] = array(
'title' => 'Blokovi korisnika, nodova, termina',
'description' => 'Administracija blokova',
'page callback' => 'drupal_get_form',
'page arguments' => array('_sitemade_content_blocks'),
'access arguments' => array('admin content blocks'),
);
return $items;
}
Opis funkcije drupal_get_form():
drupal_get_form($form_id)
Omotač za drupal_build_form() kada nije potreban $form_state.
Parametri drupal_get_form()
$form_id je jedinstveni identifikator forme. Ako funkcija sa tim imenom postoji, ona se poziva kao konstruktor forme. Moduli sa sličnim $form_id mogu koristiti hook_forms() da mapiraju ID-eve na konstruktor funkcija.
Dodatni argumenti prosleđeni drupal_get_form pozvaće se i prosleđuju konstruktoru forme. Na primer, forma node_edit zahteva objekat noda kao argument pri pozivu. Ovo se može uraditi hook_form_alter() i hook_FORM_ID_alter() preko $form_state['build_info']['args'].
Vraćena vrednost drupal_get_form()
Niz forme.
Sada ćemo prepisati funkciju _sitemade_content_blocks() da vraća niz forme.
function _sitemade_content_blocks(){
$form = array(); // inicijalizacija niza forme
$form['nodes-title'] = array(
'#type' => 'textfield',
'#title' => t('Naslov bloka nodova'),
'#default_value' => variable_get('node_block', ''),
'#size' => 60,
'#maxlength' => 64,
'#description' => t('Naslov bloka za Nodove'),
);
$form['node-selected'] = array(
'#type' => 'select',
'#title' => t('Nodovi u bloku'),
'#options' => array(
1 => t('1'),
2 => t('2'),
3 => t('3'),
4 => t('4'),
5 => t('5'),
6 => t('6'),
7 => t('7'),
8 => t('8'),
9 => t('9'),
10 => t('10'),
),
'#default_value' => variable_get('node_block_range', 5),
'#description' => t('Broj nodova prikazanih u bloku'),
);
$form['users-title'] = array(
'#type' => 'textfield',
'#title' => t('Naslov bloka korisnika'),
'#default_value' => variable_get('user_block', ''),
'#size' => 60,
'#maxlength' => 64,
'#description' => t('Naslov bloka za Korisnike'),
);
$form['user-selected'] = array(
'#type' => 'select',
'#title' => t('Korisnici u bloku'),
'#options' => array(
1 => t('1'),
2 => t('2'),
3 => t('3'),
4 => t('4'),
5 => t('5'),
6 => t('6'),
7 => t('7'),
8 => t('8'),
9 => t('9'),
10 => t('10'),
),
'#default_value' => variable_get('user_block_range', 5),
'#description' => t('Broj korisnika prikazanih u bloku'),
);
$form['terms-title'] = array(
'#type' => 'textfield',
'#title' => t('Naslov bloka termina'),
'#default_value' => variable_get('user_block', ''),
'#size' => 60,
'#maxlength' => 64,
'#description' => t('Naslov bloka za Termine'),
);
$form['term-selected'] = array(
'#type' => 'select',
'#title' => t('Termini u bloku'),
'#options' => array(
1 => t('1'),
2 => t('2'),
3 => t('3'),
4 => t('4'),
5 => t('5'),
6 => t('6'),
7 => t('7'),
8 => t('8'),
9 => t('9'),
10 => t('10'),
),
'#default_value' => variable_get('term_block_range', 5),
'#description' => t('Broj termina prikazanih u bloku'),
);
$form['actions'] = array('#type' => 'actions'); // dodajemo dugme za čuvanje
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Sačuvaj'),
);
return $form;
}
'#type' - tip elementa.
'#title' - naslov.
'#description' - opis.
'#options' - opcije padajuće liste.
'#default_value' - podrazumevana vrednost, u ovom slučaju učitavamo iz promenljivih.
Kao rezultat, forma za administraciju treba da izgleda ovako:

Prikazali smo formu, sada treba da napravimo njenu obradu. Za obradu ćemo koristiti hookove hook_formID_validate(), hook_formID_submit(), za proveru i obradu forme.
Generisanje formi
Funkcije dostupne za obradu i prikaz HTML formi u Drupalu.
Drupal koristi ove funkcije da omogući kompatibilnu obradu i prikaz formi, pojednostavljujući kod i smanjujući količinu HTML koda koji moduli moraju da generišu. Glavna funkcija za to je drupal_get_form(), koja generiše HTML kod forme. Forma može biti programatski izgrađena bez korisničkog unosa pomoću drupal_form_submit().
drupal_get_form() prihvata, obrađuje i prikazuje generisani HTML kod forme za module automatski. Ispod je primer korišćenja drupal_get_form() i ostalih funkcija za generisanje formi.
<?php
$form = drupal_get_form('my_module_example_form');
...
function my_module_example_form($form, &$form_state) {
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Pošalji'),
);
return $form;
}
function my_module_example_form_validate($form, &$form_state) {
// Validacija forme.
}
function my_module_example_form_submit($form, &$form_state) {
// Obrada podataka iz forme.
}
?>
Ili sa dodatnim argumentima:
<?php
$extra = "dodatno";
$form = drupal_get_form('my_module_example_form', $extra);
...
function my_module_example_form($form, &$form_state, $extra) {
$form['submit'] = array(
'#type' => 'submit',
'#value' => $extra,
);
return $form;
}
?>
Sada napišimo obradu naše forme da bi vrednosti koje stižu sa forme bile sačuvane u Drupal promenljivama. Instaliraćemo modul Devel koji omogućava funkciju dsm() za ispis nizova i objekata. Zatim ćemo dodati još jedan hook u modul:
function sitemade_content_blocks_submit($form, &$form_values){
dsm($form_values);
}
Ovo će omogućiti prikaz vrednosti sa forme na ekranu:

Sada lako možemo upisati vrednosti u promenljive:
function sitemade_content_blocks_submit($form, &$form_values){
//dsm($form_values);
variable_set('node_block', $form_values['values']['nodes-title']);
variable_set('user_block', $form_values['values']['users-title']);
variable_set('term_block', $form_values['values']['terms-title']);
variable_set('node_block_range', $form_values['values']['node-selected']);
variable_set('user_block_range', $form_values['values']['user-selected']);
variable_set('term_block_range', $form_values['values']['term-selected']);
}
Forma je spremna, nakon slanja vrednosti se čuvaju pomoću variable_set(), a zatim se podrazumevane vrednosti polja popunjavaju pomoću variable_get.

Još treba izmeniti hook hook_block_view() da bi naslovi blokova i broj linkova u njima takođe bili učitani preko variable_get().
function sitemade_block_view($delta = ''){
$block = array(); // inicijalizujemo prazan niz bloka
switch ($delta){
case 1: // ista delta kao u hook_block_info()
$block['subject'] = variable_get('user_block', 'Korisnici'); // prikazujemo naslov bloka
$block['content'] = ''; // inicijalizujemo promenljivu za sadržaj
$query = db_select('users', 'u') // upit za korisnike
->fields('u', array('uid', 'name')) // biramo polja
->orderBy('u.uid', 'DESC') // sortiramo opadajuće
->range(0, variable_get('user_block_range', 5)) // broj korisnika
->execute(); // izvršavamo upit
$users = $query->fetchAll(PDO::FETCH_ASSOC); // dobijamo rezultat kao niz
foreach($users as $user){
$block['content'] .='
'; // base_path() vraća putanju do korena sajta } break; case 2: $block['subject'] = variable_get('node_block', 'Nodovi'); // naslov bloka $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(); $nodes = $query->fetchAll(PDO::FETCH_ASSOC); foreach($nodes as $node){ $block['content'] .='
'; } break; case 3: $block['subject'] = variable_get('term_block', 'Termini'); // naslov bloka $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(); $terms = $query->fetchAll(PDO::FETCH_ASSOC); foreach($terms as $term){ $block['content'] .='
'; } break; } return $block; }
Sada možete videti rezultat na glavnoj stranici. I ne zaboravite: "Kad odlazite – očistite keš"!
