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

Pregled: kreiranje prilagođenog polja

18/06/2025, by Ivan
Ovaj tutorijal je prvobitno objavljen na Web Wash. Međutim, Berdir je pitao da li mogu da postavim tutorijal ovde, pa eto ga.

Modul u Drupalu 7 omogućava čuvanje primera koda / isječaka u polju. Dolazi sa prilagođenim poljem pod nazivom „Polje isječaka“ i prikazuje tri elementa forme: opis, izvorni kod i režim isticanja sintakse (koji programski jezik).

Ali sada je vreme da se modul ažurira za Drupal 8.

U ovom tutorijalu pokazaću vam kako sam napravio „osnovno“ prilagođeno polje u Drupalu 8. Neću ulaziti u detalje o PSR-4, anotacijama ili pluginovima, jer bi ovaj tutorijal bio previše obiman.

Umesto toga, dodaću linkove ka drugim sajtovima koji detaljnije objašnjavaju ove koncepte.

U međuvremenu, ako tražite detaljnu dokumentaciju za Field API u Drupalu 8, pogledajte sledeće serije:

 

U Drupalu 8 polja nisu implementirana korišćenjem hookova kao u Drupalu 7. Umesto toga, kreiraju se pomoću novog Drupal 8 API-ja za pluginove. To znači da umesto implementacije hookova definišemo klase za vidžet, formatter i element polja. Većina hookova iz Drupala 7, poput hook_field_schema, hook_field_is_empty i drugih, sada su metode u klasama.

Korak 1: Implementacija elementa polja

Prvi deo posla je definisanje klase elementa polja pod imenom SnippetsItem koja proširuje klasu FieldItemBase.

1. U Drupalu 8 se klase učitavaju koristeći PSR-4.

Dakle, da definišemo klasu SnippetsItem, potrebno je da napravimo fajl SnippetsItem.php i stavimo ga u „modul“ /src/Plugin/Field/FieldType/SnippetsItem.php

/**
 * @file
 * Sadrži \Drupal\snippets\Plugin\Field\FieldType\SnippetsItem.
 */

namespace Drupal\snippets\Plugin\Field\FieldType;

use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;

Zatim u fajl dodajemo namespace Drupal\snippets\Plugin\Field\FieldType i tri use izjave: Drupal\Core\Field\FieldItemBase, Drupal\Core\Field\FieldStorageDefinitionInterface i Drupal\Core\TypedData\DataDefinition.

2. Sada treba da definišemo stvarne detalje polja, kao što su ID polja, oznaka, podrazumevani vidžet, formatter itd. Ovo je ekvivalent implementaciji hook_field_info u Drupalu 7.

U Drupalu 8 mnogi, ako ne i svi, info hookovi su zamenjeni anotacijama.

/**
 * Implementacija plugina za tip polja 'snippets'.
 *
 * @FieldType(
 *   id = "snippets_code",
 *   label = @Translation("Polje isječaka"),
 *   description = @Translation("Ovo polje čuva isječke koda u bazi podataka."),
 *   default_widget = "snippets_default",
 *   default_formatter = "snippets_default"
 * )
 */
class SnippetsItem extends FieldItemBase { }

Zato umesto implementacije hook_field_info definišemo polje kao anotaciju u komentaru iznad klase.

Atributi anotacije ne zahtevaju dodatna objašnjenja. Samo se postarajte da default_widget i default_formatter upućuju na ID anotacije vidžeta i formattera, a ne na klasu.

Ako želite da saznate više o anotacijama, posetite stranicu dokumentacije o pluginovima baziranim na anotacijama na drupal.org.

3. Sada, kada imamo klasu elementa polja, potrebno je definisati nekoliko metoda. Prvi koji ćemo pogledati je schema()

U Drupalu 7 pri kreiranju prilagođenog polja, schema se definiše pomoću hook_field_schema. U Drupalu 8 definišemo schema metodu unutar klase SnippetsItem.

Dokumentacija za Schema API sadrži opis strukture niza schema i mogućih vrednosti.
/**
 * {@inheritdoc}
 */
public static function schema(FieldStorageDefinitionInterface $field) {
  return array(
    'columns' => array(
      'source_description' => array(
        'type' => 'varchar',
        'length' => 256,
        'not null' => FALSE,
      ),
      'source_code' => array(
        'type' => 'text',
        'size' => 'big',
        'not null' => FALSE,
      ),
      'source_lang' => array(
        'type' => 'varchar',
        'length' => 256,
        'not null' => FALSE,
      ),
    ),
  );
}

4. Sada treba dodati metodu isEmpty() i definisati šta predstavlja prazan element polja. Ova metoda je analogna implementaciji hook_field_is_empty u Drupalu 7.

/**
 * {@inheritdoc}
 */
public function isEmpty() {
  $value = $this->get('source_code')->getValue();
  return $value === NULL || $value === '';
}

5. Poslednja metoda koju ćemo dodati u klasu je metoda propertyDefinitions().

/**
 * {@inheritdoc}
 */
static $propertyDefinitions;

/**
 * {@inheritdoc}
 */
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties['source_description'] = DataDefinition::create('string')
      ->setLabel(t('Opis isječka'));

    $properties['source_code'] = DataDefinition::create('string')
      ->setLabel(t('Kod isječka'));

    $properties['source_lang'] = DataDefinition::create('string')
      ->setLabel(t('Programsko okruženje'))
      ->setDescription(t('Jezik programskog koda isječka'));

    return $properties;
  }

Ova metoda služi za definisanje tipova podataka koji postoje u vrednostima polja. „Polje isječaka“ ima samo tri vrednosti: opis, kod i jezik. Zato sam ih jednostavno dodao kao stringove u metodu.

Da biste saznali više o ovome, posetite sekciju Kako Entity API implementira Typed Data API dokumentaciju na drupal.org.

Kliknite ovde da vidite ceo fajl. Napomena: potrebno ga je ažurirati za PSR-4 specifikaciju, za više informacija pogledajte https://www.drupal.org/node/2128865.

Korak 2: Implementacija vidžeta polja

Sada kada smo definisali element polja, kreiraćemo vidžet polja. Potrebno je da napravimo klasu pod imenom SnippetsDefaultWidget koja proširuje klasu WidgetBase.

1. Kreirajte fajl SnippetsDefaultWidget.php i stavite ga u „modul“ /src/Plugin/Field/FieldWidget/SnippetsDefaultWidget.php.

/**
 * @file
 * Sadrži \Drupal\snippets\Plugin\Field\FieldWidget\SnippetsDefaultWidget.
 */

namespace Drupal\snippets\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;

Proverite da li je namespace fajla Drupal\snippets\Plugin\Field\FieldWidget i dodajte sledeće use izjave: Drupal\Core\Field\FieldItemListInterface, Drupal\Core\Field\WidgetBase i Drupal\Core\Form\FormStateInterface.

2. Sledeće treba da definišemo vidžet pomoću anotacije. Ovo je ekvivalent korišćenju hook_field_widget_info u Drupalu 7.

/**
 * Implementacija plugina za vidžet 'snippets_default'.
 *
 * @FieldWidget(
 *   id = "snippets_default",
 *   label = @Translation("Podrazumevani isječci"),
 *   field_types = {
 *     "snippets_code"
 *   }
 * )
 */
class SnippetsDefaultWidget extends WidgetBase { }

Napomena: postarajte se da atribut field_types u anotaciji referiše tipove polja koristeći njihove ID-jeve. Za ovaj modul je to snippets_code, jer smo dodali id = "snippets_code" u @FieldType anotaciju.

3. Konačno, treba da definišemo stvarnu formu vidžeta. To radimo dodavanjem metode formElement() u klasu SnippetsDefaultWidget. Ova metoda je ekvivalent hook_field_widget_form u Drupalu 7.

/**
 * {@inheritdoc}
 */
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {

  $element['source_description'] = array(
        '#title' => $this->t('Opis'),
        '#type' => 'textfield',
        '#default_value' => isset($items[$delta]->source_description) ? $items[$delta]->source_description : NULL,
      );
  $element['source_code'] = array(
        '#title' => $this->t('Kod'),
        '#type' => 'textarea',
        '#default_value' => isset($items[$delta]->source_code) ? $items[$delta]->source_code : NULL,
      );
  $element['source_lang'] = array(
        '#title' => $this->t('Izvorni jezik'),
        '#type' => 'textfield',
        '#default_value' => isset($items[$delta]->source_lang) ? $items[$delta]->source_lang : NULL,
      );
  return $element;
}

Kliknite ovde da vidite ceo fajl. Napomena: potrebno ga je ažurirati za PSR-4 specifikaciju, za više informacija pogledajte https://www.drupal.org/node/2128865.

Korak 3: Implementacija formattera polja

Poslednji deo slagalice je formatter polja, koji pravimo tako što definišemo klasu pod imenom SnippetsDefaultFormatter koja proširuje klasu FormatterBase.

1. Kreirajte fajl SnippetsDefaultFormatter.php i stavite ga u „modul“ /src/Plugin/Field/FieldFormatter/SnippetsDefaultFormatter.php.

/**
 * @file
 * Sadrži \Drupal\snippets\Plugin\Field\FieldFormatter\SnippetsDefaultFormatter.
 */

namespace Drupal\snippets\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;

Proverite da li je namespace fajla Drupal\snippets\Plugin\Field\FieldFormatter i dodajte use izjave: Drupal\Core\Field\FieldItemListInterface i Drupal\Core\Field\FormatterBase.

2. Sledeće treba da definišemo formatter pomoću anotacije. Isto kao za vidžet i tip polja, ovo je ekvivalent hook_field_formatter_info.

/**
 * Implementacija plugina za formatter 'snippets_default'.
 *
 * @FieldFormatter(
 *   id = "snippets_default",
 *   label = @Translation("Podrazumevani isječci"),
 *   field_types = {
 *     "snippets_code"
 *   }
 * )
 */
class SnippetsDefaultFormatter extends FormatterBase { }

3. Sada treba dodati metodu viewElements() i definisati stvarnu logiku formatiranja polja. Ovo je ekvivalent hook_field_formatter_view u Drupalu 7.

/**
 * {@inheritdoc}
 */
public function viewElements(FieldItemListInterface $items, $langcode) {
  $elements = array();
  foreach ($items as $delta => $item) {
    // Renderovanje izlaza koristeći tema snippets_default.
    $source = array(
      '#theme' => 'snippets_default',
      '#source_description' => $item->source_description,
      '#source_code' => $item->source_code,
    );
    
    $elements[$delta] = array('#markup' => drupal_render($source));
  }

  return $elements;
}

Vredno je napomenuti da koristim prilagođeni šablon snippets_default za renderovanje isječaka pre nego što ih formatter prikaže.

Razlog za to je što nisam želeo da stavim puno logike ili HTML koda direktno u metodu viewElements().

Kliknite ovde da vidite ceo fajl. Napomena: potrebno ga je ažurirati za PSR-4 specifikaciju, za više informacija pogledajte https://www.drupal.org/node/2128865.

Zaključak

Kao što je ranije navedeno, najveća promena u Drupalu 8 je da se polja kreiraju pomoću API-ja pluginova, a ne hookova. Kada to shvatite, koncept kreiranja polja je vrlo sličan Drupalu 7. Mnoge metode u Drupalu 8 odgovaraju hookovima u Drupalu 7.

Ako želite da testirate polja za isječke koda, preuzmite 8.x-dev verziju i probajte.

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.