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š"!