API dei Blocchi
Panoramica
I blocchi in Drupal 8 in realtà consistono in due strutture API separate, per creare un’interfaccia utente simile a quella supportata da Drupal nelle precedenti versioni. Queste due API sono la Block Plugin API, che è un’API autonoma e riutilizzabile, e la Block Entity API, che è la variante specifica di Drupal 8 per posizionare i blocchi e controllarne la visibilità.
Creazione di blocchi con la Block Plugin API
Creare blocchi definiti nel codice del tuo modulo richiede di imparare e comprendere l’API dei plugin e, in particolare, la scoperta dei plugin basata su annotazioni, che è il meccanismo che Drupal 8 utilizza per trovare il codice che definisce il tuo blocco.
Creare un blocco personalizzato definito dal tuo modulo include i seguenti passaggi:
- Creare un plugin di blocco usando le annotazioni
- Estendere la classe Drupal\Core\Block\BlockBase
- Implementare i metodi dell’interfaccia Drupal\Core\Block\BlockPluginInterface richiesti per il tuo caso d’uso.
Rendere visibile il tuo blocco a Drupal e agli utenti
Drupal utilizza lo standard PSR-4 per la scoperta. Supponendo che il nome del modulo sia fax, il codice per il tuo/i blocco/chi personalizzato/i deve essere collocato in fax/src/Plugin/Block/. Ogni file in questa cartella deve avere lo stesso nome della classe che contiene. Se vogliamo definire la classe FaxBlock, essa deve trovarsi nel file fax/src/Plugin/Block/FaxBlock.php e avere un contenuto simile al seguente esempio:
namespace Drupal\fax\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a 'Fax' block.
*
* @Block(
* id = "fax_block",
* admin_label = @Translation("Fax block"),
* )
*/
class FaxBlock extends BlockBase {
// Override BlockPluginInterface methods here.
}
La proprietà id nell’annotazione definisce un identificatore univoco leggibile dalla macchina per il tuo blocco e il nome del blocco che sarà visibile ad altro codice. L’annotazione admin_label definisce il nome leggibile del blocco che sarà usato nell’interfaccia di amministrazione. Le proprietà disponibili delle annotazioni possono essere trovate in \Drupal\Core\Block\Annotation\Block (proprietà pubbliche).
I due metodi più comuni da sovrascrivere sono:
BlockPluginInterface::build()– deve restituire un render array che definisce il contenuto che vuoi mostrare nel tuo blocco.BlockBase::access()– controlla la visibilità del blocco. Deve restituire un oggettoAccessResult.
Aggiungere impostazioni di configurazione personalizzate al tuo blocco
Puoi anche aggiungere parametri di configurazione personalizzati al form di configurazione del blocco, sovrascrivendo i metodi BlockPluginInterface::blockForm() e BlockPluginInterface::blockSubmit(), e poi utilizzando BlockBase::setConfigurationValue() e BlockBase::getConfiguration().
Nell’esempio seguente aggiungiamo un nuovo campo di testo nel metodo blockForm(), e poi salviamo i dati forniti dall’utente in blockSubmit(). Il codice mostra come i valori possono essere recuperati in fase di build del form, validati e aggiornati con i metodi appropriati.
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
/**
* Provides a 'Fax' block.
*
* @Block(
* id = "fax_block",
* admin_label = @Translation("Fax block"),
* )
*/
class FaxBlock extends BlockBase implements BlockPluginInterface {
// Access method here ...
/**
* {@inheritdoc}
*/
public function build() {
$config = $this->getConfiguration();
$fax_number = isset($config['fax_number']) ? $config['fax_number'] : '';
return [
'#markup' => $this->t('The fax number is @number!', ['@number' => $fax_number]),
];
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$form = parent::blockForm($form, $form_state);
// Retrieve existing configuration for this block.
$config = $this->getConfiguration();
// Add a form field to the existing block configuration form.
$form['fax_number'] = [
'#type' => 'textfield',
'#title' => t('Fax number'),
'#default_value' => isset($config['fax_number']) ? $config['fax_number'] : '',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
// Save our custom settings when the form is submitted.
$this->setConfigurationValue('fax_number', $form_state->getValue('fax_number'));
}
/**
* {@inheritdoc}
*/
public function blockValidate($form, FormStateInterface $form_state) {
$fax_number = $form_state->getValue('fax_number');
if (!is_numeric($fax_number)) {
$form_state->setErrorByName('fax_number', t('Needs to be an integer'));
}
}
}
Puoi anche usare il metodo BlockBase::getConfiguration() all’interno di build() per ottenere i dati di configurazione e mostrarli ai tuoi utenti. Il metodo access() del tuo blocco può contenere logiche più complesse per determinare se il blocco debba essere visualizzato.
Esempio di metodo per la condizione di accesso:
/**
* {@inheritdoc}
*/
public function access(AccountInterface $account, $return_as_object = FALSE) {
return \Drupal\Core\Access\AccessResult::allowedIf($account->isAuthenticated());
}
Puoi anche creare le tue condizioni di caching.
Esempio di metodo che usa i tag di cache. Scopri di più sui tag di cache.
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return \Drupal\Core\Cache\Cache::mergeTags(parent::getCacheTags(), ['node_list']);
}
Se vuoi cambiare il tempo massimo di cache del blocco a 0. Maggiori informazioni sul max-age della cache.
public function getCacheMaxAge() {
// If you want to disable caching for this block.
return 0;
}