logo

Dodatni tipovi blokova (EBT) - Novo iskustvo rada sa Layout Builder-om❗

Dodatni tipovi blokova (EBT) – stilizovani, prilagodljivi tipovi blokova: slajdšouvi, kartice sa tabovima, kartice, akordeoni i mnogi drugi. Ugrađena podešavanja za pozadinu, DOM Box, javascript dodatke. Iskusite budućnost kreiranja rasporeda već danas.

Demo EBT moduli Preuzmite EBT module

❗Dodatni tipovi pasusa (EPT) – Novo iskustvo rada sa pasusima

Dodatni tipovi pasusa (EPT) – analogni skup modula zasnovan na pasusima.

Demo EPT moduli Preuzmite EPT module

Scroll

9.8. Rad sa formularima u Drupalu. Dodavanje konfiguracionog formulara programatski.

27/05/2025, by Ivan

U ovom tutorijalu bavićemo se Drupal Form API-jem i kreirati formular za podešavanja modula. Već smo napravili module za prikaz stranice i bloka, sada ćemo napraviti konfiguracioni formular u koji ćemo smestiti podatke za povezivanje sa uslovnom uslugom. Recimo da na sajtu treba da sačuvamo API ključ i API Client ID, na primer za Google Maps API.

Primere koda možete pogledati na github-u:
https://github.com/levmyshkin/drupalbook8

Ove podatke možemo čuvati u settings.php i dodati ta podešavanja u git. Ali to nije sigurno, bolje je pristup servisima čuvati u bazi podataka.

Settings form

Dodajmo još jednu rutu za naš formular:

modules/custom/drupalbook/drupalbook.routing.yml

drupalbook.settings:
  path: '/admin/structure/drupalbook/settings'
  defaults:
    _form: '\Drupal\drupalbook\Form\DrupalbookSettingsForm'
    _title: 'DrupalBook Settings form'
  requirements:
    _permission: 'administer site configuration'

Za razliku od prethodnih ruta, ovde u defaults navodimo ne _controller, već _form. To je zato što ne pravimo Controller klasu za formular, već form klasu. Hajde da kreiramo fajl za klasu formulara:

modules/custom/drupalbook/src/Form/DrupalbookSettingsForm.php

Treba da napravite poseban folder Form u src folderu za vaše forme. To omogućava da kod modula organizujete u posebne foldere i lakše pronađete potrebni kod po imenu foldera.

Dodajte sledeći kod formulara i analiziraćemo svaki blok koda i kako radi:

<?php

namespace Drupal\drupalbook\Form;
 
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
 
/**
 * Konfiguriše primer podešavanja za ovaj sajt.
 */
class DrupalbookSettingsForm extends ConfigFormBase {
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'drupalbook_admin_settings';
  }
 
  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'drupalbook.settings',
    ];
  }
 
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('drupalbook.settings');
 
    $form['drupalbook_api_key'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('API Key'),
      '#default_value' => $config->get('drupalbook_api_key'),
    );
 
    $form['drupalbook_api_client_id'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('API Client ID'),
      '#default_value' => $config->get('drupalbook_api_client_id'),
    );
 
    return parent::buildForm($form, $form_state);
  }
 
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Uzimamo konfiguraciju
    $this->configFactory->getEditable('drupalbook.settings')
      // Postavljamo poslatu vrednost u konfiguraciju
      ->set('drupalbook_api_key', $form_state->getValue('drupalbook_api_key'))
      // Možete postaviti više podešavanja odjednom sa više poziva set()
      ->set('drupalbook_api_client_id', $form_state->getValue('drupalbook_api_client_id'))
      ->save();
 
    parent::submitForm($form, $form_state);
  }
}

Već smo se bavili namespace i use naredbama, Drupal koristi automatsko povezivanje samo potrebnih klasa:

\drupalbook\Form;
 
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

Za kreiranje konfiguracionog formulara nasleđujemo ConfigFormBase klasu, što implicira da će podaci sa forme biti sačuvani u konfiguraciji.

extends ConfigFormBase {

Zatim navodimo jedinstveni ID forme. Ako ID forme počinje imenom modula, sigurno će biti jedinstven:

function getFormId() {
  return 'drupalbook_admin_settings';
}

Navodimo grupu konfiguracija u kojoj ćemo čuvati podatke:

function getEditableConfigNames() {
  return [
    'drupalbook.settings',
  ];
}

Sada pogledajmo kako pravimo sama polja forme. Mogućnosti Form API-ja i dostupna polja možete proučiti u dokumentaciji:

https://api.drupal.org/api/drupal/elements/8.5.x

Do sada smo koristili samo textfield:

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Textfield.php/class/Textfield/8.5.x

Ali često se sreću i drop-down liste:

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Select.php/class/Select/8.5.x

Checkbox-ovi i radio dugmad:

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Checkboxes.php/class/Checkboxes/8.5.x

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Radios.php/class/Radios/8.5.x

Probajte da dodate polja u formu, ne ograničavajte se samo na textfield.

function buildForm(array $form, FormStateInterface $form_state) {
  $config = $this->config('drupalbook.settings');

Formu pravimo kao niz $form iz kog se kasnije gradi HTML. Varijabla $form_state čuva sve podatke sa forme koje šaljemo, uključujući vrednosti svih polja, form_id, CSRF token za zaštitu. $form_state omogućava i prenos podataka između koraka višestepenog formulara, što ćemo koristiti u nekoj od narednih lekcija. Takođe, svaki put kada se forma šalje preko AJAX-a, forma se ponovo gradi, i $form_state omogućava da se sačuva prethodno stanje forme pre klika na dugme za slanje. Ako dođe do greške (na primer, nije popunjeno obavezno polje), svi podaci će ostati sačuvani u poljima kroz $form_state. Zato $form i $form_state uvek idu zajedno.

Ovde takođe učitavamo podatke iz konfiguracije. Možda ste već sačuvali neke vrednosti u drupalbook.settings i $config nije prazan, pa će se trenutne vrednosti prikazati u poljima kroz #default_value, koje koristi get() metod konfiguracije.

$form['drupalbook_api_key'] = array(
  '#type' => 'textfield',
  '#title' => $this->t('API Key'),
  '#default_value' => $config->get('drupalbook_api_key'),
);
 
$form['drupalbook_api_client_id'] = array(
  '#type' => 'textfield',
  '#title' => $this->t('API Client ID'),
  '#default_value' => $config->get('drupalbook_api_client_id'),
);

Na kraju metode vraćamo $form i $form_state da bi forma bila izgrađena:

return parent::buildForm($form, $form_state);

Sledeća je metoda submitForm(), koja se poziva ako je forma uspešno poslata bez grešaka. Ako niste popunili obavezno polje i Drupal prijavi grešku, submitForm se neće pozvati. Ako želite da proverite podatke pri slanju, koristite validateForm(), koji se izvršava i ako ima grešaka, i može poništiti slanje ako podaci nisu validni. Validate ćemo obraditi u narednim lekcijama o formama.

U submitForm() uzimamo vrednosti iz polja i ažuriramo konfiguraciju drupalbook.settings:

public function submitForm(array &$form, FormStateInterface $form_state) {
  $this->configFactory->getEditable('drupalbook.settings')
    ->set('drupalbook_api_key', $form_state->getValue('drupalbook_api_key'))
    ->set('drupalbook_api_client_id', $form_state->getValue('drupalbook_api_client_id'))
    ->save();
 
  parent::submitForm($form, $form_state);
}

Pozivamo i roditeljsku metodu submitForm koja prikazuje poruku o uspešnom snimanju forme. Tu liniju možete komentarisati i napisati svoju poruku:

//parent::submitForm($form, $form_state);
drupal_set_message($this->t('Moj super formular je sačuvan!'));

Zapamtite da očistite keš da bi ruta proradila. Sada možete probati svoj formular u akciji. Kada vam treba API ključ, možete koristiti ovaj kod:

$config = \Drupal::config('drupalbook.settings');
$api_key = $config->get('drupalbook_api_key');
$api_client_id = $config->get('drupalbook_api_client_id');

Ovaj kod će raditi u bilo kom modulu ili funkciji za pripremu (preprocess), jer Drupal ima jedinstven sistem konfiguracije.

To je to za narednu lekciju o formama, u narednoj ćemo analizirati kako napraviti višestepene forme.

Primere koda možete pogledati na github-u:
https://github.com/levmyshkin/drupalbook8