9.8. Lavorare con i moduli in Drupal. Aggiungere un modulo di configurazione programmaticamente.
In questo tutorial, tratteremo la Form API di Drupal e creeremo un modulo di configurazione per il modulo. Abbiamo già creato moduli per visualizzare la pagina e il blocco, ora creiamo un modulo di configurazione in cui memorizzeremo i dati per connettersi a un servizio condizionale. Supponiamo di dover memorizzare la chiave API e l'ID client API sul sito, ad esempio, per l'API di Google Maps.
Esempi di codice possono essere visualizzati su GitHub:
https://github.com/levmyshkin/drupalbook8
Possiamo memorizzare questi dati in settings.php
e aggiungere queste impostazioni a git. Ma non sarà sicuro, è meglio memorizzare gli accessi ai servizi nel database.
Aggiungiamo un'altra rotta per il nostro modulo:
modules/custom/drupalbook/drupalbook.routing.yml
drupalbook.settings:
path: '/admin/structure/drupalbook/settings'
defaults:
_form: '\Drupal\drupalbook\Form\DrupalbookSettingsForm'
_title: 'Modulo di impostazioni di DrupalBook'
requirements:
_permission: 'administer site configuration'
Rispetto alle rotte precedenti, nei defaults specifichiamo non _controller, ma _form. Il fatto è che non creeremo una classe Controller per il modulo, ma una classe form. Creiamo un file per la classe del modulo:
modules/custom/drupalbook/src/Form/DrupalbookSettingsForm.php
Devi creare una cartella Form separata nella cartella src per i tuoi moduli. Questo ti permette di separare il codice del modulo in cartelle separate e puoi anche trovare facilmente il codice che ti serve in base al nome delle cartelle.
Aggiungi il codice del modulo di seguito e analizzeremo ciascuno dei blocchi di codice e come funziona:
<?php
namespace Drupal\drupalbook\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Configura le impostazioni esempio per questo sito.
*/
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) {
// Recupera la configurazione
$this->configFactory->getEditable('drupalbook.settings')
// Imposta le impostazioni di configurazione inviate
->set('drupalbook_api_key', $form_state->getValue('drupalbook_api_key'))
// Puoi impostare più configurazioni contemporaneamente facendo
// più chiamate a set()
->set('drupalbook_api_client_id', $form_state->getValue('drupalbook_api_client_id'))
->save();
parent::submitForm($form, $form_state);
}
}
Abbiamo già trattato gli operatori namespace
e use
, e che Drupal li utilizza per connettere automaticamente solo quelle classi di cui c'è bisogno:
\drupalbook\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
Per creare un modulo di configurazione, è necessario ereditare dalla classe ConfigFormBase
, ConfigFormBase
implica che salverai i dati del modulo nella configurazione.
extends ConfigFormBase {
Successivamente, specifica l'ID del modulo, deve essere unico per ogni modulo. Se scrivi l'ID del tuo modulo iniziando con il nome del modulo, sicuramente il tuo ID sarà unico:
function getFormId() {
return 'drupalbook_admin_settings';
}
Specifica il gruppo di configurazioni in cui memorizzeremo i dati:
function getEditableConfigNames() {
return [
'drupalbook.settings',
];
}
Ora vediamo come creiamo i campi del modulo stesso. Puoi valutare le capacità della Form API e i campi che puoi visualizzare leggendo la documentazione:
https://api.drupal.org/api/drupal/elements/8.5.x
Finora abbiamo utilizzato solo textfield
:
Ma spesso devi trattare con liste a discesa:
Con checkbox e radio button:
Prova ad aggiungere i tuoi campi al modulo, non limitarti ai campi di testo.
function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('drupalbook.settings');
Formiamo un array di modulo in $form
e poi costruiamo l'HTML da esso. La variabile $form_state
memorizza tutti i dati del modulo che inviamo, qui e i valori di tutti i campi, l'ID del modulo, il token CSRF per proteggere contro l'invio automatico del modulo. $form_state
consente anche di trasferire dati tra i passaggi di un modulo a più passaggi, useremo questo in una delle lezioni successive. Inoltre, ogni volta che un modulo viene inviato tramite AJAX, il modulo viene ricostruito di nuovo, e $form_state
consente di costruire una copia del modulo che era prima di fare clic sul pulsante di invio. E se il modulo non viene inviato a causa di un errore, ad esempio, se un campo non viene compilato, allora tutti i campi saranno salvati con i valori che erano memorizzati in $form_state
. Pertanto, $form
e $form_state
vanno sempre insieme.
Qui carichiamo anche i dati dalle configurazioni. Forse hai già salvato qualcosa in drupalbook.settings
e $config
non è più vuoto, questo ti permetterà di impostare i valori correnti nei campi utilizzando #default_value
in ciascuno dei campi di testo, ricevendo i dati dalle configurazioni utilizzando il metodo get()
.
['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'),
);
Alla fine del metodo, restituiamo $form
e $form_state
in modo che il modulo venga costruito.
::buildForm($form, $form_state);
Successivamente, abbiamo il metodo submitForm()
, che viene eseguito se il modulo è stato inviato e non si sono verificati errori. Se comunque hai un campo obbligatorio non compilato e Drupal genera un errore, allora submitForm
non funzionerà. Se vuoi controllare i valori dei dati inviati dal modulo, devi usare validateForm()
, la validazione funzionerà anche se ci sono errori nel modulo e usando la validazione puoi annullare l'invio del modulo e causare un errore se qualcosa non ti soddisfa nei dati. Tratteremo la validazione in uno dei prossimi tutorial sui moduli.
Nel metodo submitForm()
, percorriamo tutti i campi, raccogliamo i loro valori e aggiorniamo la configurazione drupalbook.settings
:
function submitForm(array &$form, FormStateInterface $form_state) {
// Recupera la configurazione
$this->configFactory->getEditable('drupalbook.settings')
// Imposta le impostazioni di configurazione inviate
->set('drupalbook_api_key', $form_state->getValue('drupalbook_api_key'))
// Puoi impostare più configurazioni contemporaneamente facendo
// più chiamate a set()
->set('drupalbook_api_client_id', $form_state->getValue('drupalbook_api_client_id'))
->save();
parent::submitForm($form, $form_state);
}
Chiamiamo anche il metodo genitore submitForm
, che visualizza un messaggio sull'invio riuscito del modulo. Puoi commentare questa riga e scrivere il tuo messaggio:
//parent::submitForm($form, $form_state);
drupal_set_message($this->t('Il mio modulo fantastico è stato salvato!'));
Ricorda di svuotare la cache affinché la tua rotta si applichi. Ora puoi provare il modulo in azione. Quando devi caricare la chiave API, puoi usare questo codice:
$config = \Drupal::config('example.settings');
$api_key =$config->get('drupalbook_api_key');
$api_client_id = $config->get('drupalbook_api_client_id');
Questo codice funzionerà in qualsiasi modulo o funzione preprocess, perché c'è un sistema di configurazione unico in Drupal.
Questo è tutto, nella prossima lezione sui moduli, analizzeremo come creare moduli a più passaggi.
Esempi di codice possono essere visualizzati su GitHub:
https://github.com/levmyshkin/drupalbook8