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

Dodavanje stilskih tabela (CSS) i JavaScript (JS) u Drupal 8 modul

19/06/2025, by Ivan

Ova dokumentacija je za module. Informacije o temama pogledajte u odeljku Dodavanje stilskih tabela (CSS) i JavaScript (JS) u Drupal 8 temu.

U Drupal 8, stilovi (CSS) i JavaScript (JS) se učitavaju putem istog sistema za module (kod) i teme: biblioteka resursa. Biblioteke resursa mogu sadržavati jedan ili više CSS fajlova, jedan ili više JS fajlova i jednu ili više JS podešavanja.

Drupal koristi visok nivo principa: resursi (CSS ili JS) se i dalje učitavaju samo ako obavestite Drupal da ih treba učitati. Drupal ne učitava sve resurse (CSS/JS) na svim stranicama, jer to negativno utiče na performanse interfejsa.

Razlike u odnosu na Drupal 7

Postoje dve važne razlike u odnosu na Drupal 7 za programere:

1. Samo JavaScript potreban određenoj stranici biće dodat na tu stranicu. Konkretno, podrazumevano Drupal ne zahteva JavaScript na većini stranica koje anonimni korisnici mogu videti. To znači da jQuery više nije automatski učitan na svim stranicama.
Dakle, ako vašoj temi treba jQuery ili bilo koji drugi JavaScript (takođe definisan u biblioteci resursa), morate reći Drupalu da ih treba učitati tako što ćete deklarisati zavisnost od potrebne biblioteke resursa.

2. Javascript objekat Drupal.settings je zamenjen sa drupalSettings.

Proces

Glavni koraci za učitavanje resursa (CSS / JS):

1. Sačuvajte CSS ili JS u fajl.
2. Definišite „biblioteku“ koja može sadržavati CSS i JS fajlove.
3. „Prikačite“ biblioteku na niz za renderovanje u hook-u.

Ali u slučaju tema postoji alternativa za korak 3: teme mogu učitavati bilo koji broj biblioteka resursa na svim stranicama.

Definisanje biblioteke

Da biste definisali jednu ili više biblioteka (resursa), dodajte fajl *.libraries.yml u korenski folder vašeg modula (zajedno sa fajlom .info.yml). (Ako se vaš modul zove fluffiness, ime fajla treba biti fluffiness.libraries.yml). Svaka „biblioteka“ u fajlu je zapis koji detaljno opisuje CSS i JS fajlove (resurse), na primer:
Posebna napomena za govornike francuskog: pazite da ispravno napišete .libraries.yml! Ne .librairies.yml !! (biblioteka na francuskom znači knjižara...) ili ćete dugo tražiti šta nije u redu jer Drupal neće prijaviti grešku prilikom pokušaja da se prikači nepostojeća biblioteka ... ;)

cuddly-slider:
  version: 1.x
  css:
    layout:
      css/cuddly-slider-layout.css: {}
    theme:
      css/cuddly-slider-theme.css: {}
  js:
    js/cuddly-slider.js: {}

Možete primetiti ključeve 'layout' i 'theme' za css, kojih nema za js. To označava tip stila kojem CSS fajl pripada.

Možete postaviti težinu CSS-a sa 5 različitih nivoa stilova:

  • base: reset/normalizacija CSS-a plus stilizacija HTML elemenata. Ključ dodeljuje težinu CSS_BASE = -200
  • layout: makro raspored web stranice, uključujući bilo koje grid sisteme. Ključ dodeljuje težinu CSS_LAYOUT = -100
  • component: diskretni, višekratno upotrebljivi UI elementi. Ključ dodeljuje težinu CSS_COMPONENT = 0
  • state: stilovi povezani sa promenama komponenti na strani klijenta. Ključ dodeljuje težinu CSS_STATE = 100
  • theme: čisto vizuelni stil („look and feel“) komponente. Ključ dodeljuje težinu CSS_THEME = 200

Ovo je definisano standardom SMACSS. Dakle, ako navedete theme, to znači da CSS fajl sadrži stilove povezane sa temom, koji su isključivo vizuelni. Više informacija ovde. Ne možete koristiti druge ključeve jer će dovesti do stroge greške.

U ovom primeru pretpostavlja se da je stvarni JavaScript cuddly-slider.js u podfolderu js vašeg modula. Takođe možete imati JS iz eksternog URL-a, uključivati CSS fajlove i druge mogućnosti. Pogledajte CDN / spoljne biblioteke za detalje.

Međutim, imajte na umu da Drupal 8 više ne učitava jQuery na svim stranicama podrazumevano; Drupal 8 učitava samo ono što je potrebno. Dakle, moramo deklarisati da biblioteka cuddly-slider našeg modula zavisi od biblioteke koja sadrži jQuery. To nije modul ili tema koja pruža jQuery, već Drupal jezgro: core/jquery je zavisnost koju želimo deklarisati. (To je ime ekstenzije, zatim kosa crta i ime biblioteke, pa ako neka druga biblioteka želi zavisiti od naše cuddly-slider biblioteke, moraće da deklarira zavisnost od fluffiness/cuddly-slider, jer je fluffiness ime našeg modula.)

Dakle, da bismo obezbedili dostupnost jQuery za js/cuddly-slider.js, izmenićemo prethodno:

cuddly-slider:
  version: 1.x
  css:
    theme:
      css/cuddly-slider.css: {}
  js:
    js/cuddly-slider.js: {}
  dependencies:
    - core/jquery

Kao što se može očekivati, redosled navedenih CSS i JS resursa je i redosled njihovog učitavanja.

Podrazumevano Drupal prikači JS resurse na dnu stranice da bi se izbegli problemi poput: blokiranje učitavanja DOM sadržaja, pristupanje nedostupnom DOM elementu iz jquery koda itd. Ako je iz nekog razloga potrebno priključiti JS resurse u sekciju, moguće je koristiti opciju header, na primer:

cuddly-slider:
  version: 1.x
  header: true
  js:
    js/cuddly-slider.js: {}

Sad će js/cuddly-slider.js biti priključen na vrh stranice.

Prikačiti biblioteku na stranice

Zavisno od toga koji resursi treba da se učitaju, biblioteku resursa možete prikačiti na različite načine. Neke biblioteke su potrebne na svim stranicama, neke retko, a neke na većini, ali ne na svim.

Ali najvažnije je da ne odlučujemo da li da učitamo biblioteku prema URL-u ili ruti, nego prema tome šta je vidljivo na stranici: ako stranica sadrži '#type' => 'table', '#type' => 'dropbutton' i '#type' => 'foobar', učitaćemo samo biblioteke povezane sa svakim tim '#type'-ovima.
Ali nismo ograničeni samo na '#type': možda želimo učitati određenu biblioteku samo za određenu instancu '#type'. U tom slučaju, samo je prikačimo na niz renderovanja te instance.

Naravno, retko postoji dobar razlog da se neki resurs učita na svim stranicama (npr. neki JavaScript za analitiku koji prati učitavanje stranica), bez obzira na „stvari“ na stranici.

Pododeljci u nastavku pokazuju primere kako to uraditi.

Prikačiti za određeni '#type' (za sve instance)

Da biste prikačili biblioteku određenom postojećem '#type' za sve njegove instance, koristite hook_element_info_alter():

function yourmodule_element_info_alter(array &$types) {
  if (isset($types['table'])) {
    $types['table']['#attached']['library'][] = 'your_module/library_name';
  }
}

Zatim očistite keš da Drupal zna za novi hook koji ste dodali.

Prikačiti na niz za renderovanje

Da biste prikačili biblioteku na niz za renderovanje (možda za određenu instancu '#type'), morate imati pristup tom nizu. Možda ga definišete, možda menjate u hook-u. U svakom slučaju to izgleda ovako:

$build['the_element_that_needs_the_asset_library']['#attached']['library'][] = 'your_module/library_name';

Uvek koristite numeričke ključeve!
Možda želite pomoći Drupalu i ne stvarati duplikate biblioteka tako što ćete koristiti nenumeričke ključeve:

$build['the_element_that_needs_the_asset_library']['#attached']['library']['your_module/library_name'] = 'your_module/library_name';

Nemojte to raditi. Način spajanja nizova u Drupalu će dovesti do neispravnog ugnježdenog niza, i dobićete greške kao:

Warning: explode() expects parameter 2 to be string, array given in Drupal\Core\Asset\LibraryDependencyResolver->doGetDependencies()
Notice: Array to string conversion in system_js_settings_alter()
Notice: Array to string conversion in Drupal\Core\Asset\AttachedAssets->setLibraries()

Prikačiti na niz renderovanja blok plugina

Još jedan primer prikačivanja biblioteke na niz renderovanja: ako pravite blok plugin u svom modulu, možete prikačiti biblioteke u build() funkciji klase koja nasleđuje BlockBase (od Drupal 8 beta 6):

    return [
      '#theme' => 'your_module_theme_id',
      '#someVariable' => $some_variable,
      '#attached' => [
        'library' => [
          'your_module/library_name',
        ],
      ],
    ];

Prikačiti biblioteku na formu

Pošto su forme takođe nizovi za renderovanje, prikačivanje biblioteke funkcioniše isto:

/**
 * Implements hook_form_alter().
 */
function yourmodule_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  /* @var Drupal\Core\Entity\FieldableEntityInterface $entity */
  $formObject = $form_state->getFormObject();
  if ($formObject instanceof \Drupal\Core\Entity\EntityFormInterface) {
    $entity = $formObject->getEntity();
    if (
      $entity->getEntityTypeId() === 'node'
      && in_array($entity->bundle(), ['organisation', 'location', 'event', 'article'])
    ) {
      $form['#attached']['library'][] = 'yourmodule/yourlibrary';
    }
  }
}

Prikačiti biblioteku na sve (ili podskup) stranica

U nekim slučajevima biblioteka resursa nije vezana za deo stranice, već za celu stranicu. Za ovaj slučaj postoji hook_page_attachments(). Dobar primer je u modulu „Contextual Links“:

// From core/modules/contextual/contextual.module.
function contextual_page_attachments(array &$page) {
  if (!\Drupal::currentUser()->hasPermission('access contextual links')) {
    return;
  }

  $page['#attached']['library'][] = 'contextual/drupal.contextual-links';
}

Prikačiti biblioteku u funkciji za preprocess

Možete prikačiti biblioteku u preprocess funkciji koristeći specijalan ključ '#attached':

function yourmodule_preprocess_maintenance_page(&$variables) {
  $variables['#attached']['library'][] =  'your_module/library_name';
}

Prikačiti biblioteku u twig šablonu

Takođe možete prikačiti biblioteku u twig šablonu pomoću funkcije attach_library(). Na primer u bilo kom *.html.twig:

{{ attach_library('your_module/library_name') }}
Some markup {{ message }}

Prikačiti biblioteku prilikom zamene tokena

Takođe možete prikačiti biblioteku ako se vaš token pojavljuje u filtriranom tekstu tako što ćete dodati biblioteku u objekat BubbleableMetadata tokom zamene u hook_tokens():

/**
 * Implements hook_tokens().
 */
function your_module_tokens($type, $tokens, array $data, array $options, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {
    $replacements = [];
    if ($type == 'your_module') {
        foreach ($tokens as $name => $original) {
            switch ($name) {
                case 'your-token':
                    $your_render_array = your_module_build_your_renderable_thing();
                    $replacements[$original] =  \Drupal::service('renderer')->render($your_render_array);
                    // PAŽNJA! MOŽEMO TAKOĐE DODATI BIBLIOTEKE!
                    $bubbleable_metadata->addAttachments(['library' => ['your_module/library_name'] ]);
                break;
            }
        }
    }

    return $replacements;
}

Napomena: primer prikazuje samo kako dodati biblioteku tokom zamene – da biste u potpunosti implementirali korisnički token, morate takođe implementirati hook_token_info().

Prikačiti biblioteku u filter plugin

Ako modul pruža tekstualni filter, može koristiti metodu setAttachments() ili addAttachments() klase FilterProcessResult. Na primer, filter filter_caption radi ovo:

    if (...) { ...
      $result->setProcessedText(Html::serialize($dom))
        ->addAttachments([
          'library' => [
            'filter/caption',
          ],
        ]);
    }

    return $result;

Dodavanje prilagođenog JavaScript-a

U nekim slučajevima možete želeti da dodate JavaScript na stranicu koji zavisi od nekih izračunatih PHP podataka. To možete učiniti sa drupalSettings (naslednikom Drupal 7 Drupal.settings), nizom podešavanja definisanim u vašem PHP skriptu, koji je dostupan kao objekat podešavanja u vašem JavaScript-u.

Da biste koristili drupalSettings u biblioteci, prvo morate deklarisati zavisnost od core/drupalSettings u definiciji biblioteke.

Definicija biblioteke iz prethodnog primera:

cuddly-slider:
  version: 1.x
  js:
    js/cuddly-slider.js: {}
  dependencies:
    - core/jquery
    - core/drupalSettings

Sada u našim PHP fajlovima možemo proslediti potrebna drupalSettings zajedno sa našom bibliotekom. Po konvenciji koristimo ime modula u lowerCamelCase kao ključ za podešavanja i ime biblioteke u lowerCamelCase kao dodatni ključ.

Ako želimo da prosledimo izračunate vrednosti 'foo' i 'baz' iz PHP-a u JavaScript našeg primera, možemo uraditi:

$computed_settings = [
  'foo' => 'bar',
  'baz' => 'qux',
];

$build['#attached']['library'][] = 'your_module/library_name';
$build['#attached']['drupalSettings']['fluffiness']['cuddlySlider'] = $computed_settings;

Tada cuddly-slider.js može pristupiti drupalSettings.fluffiness.cuddlySlider.foo i drupalSettings.fluffiness.cuddlySlider.baz, koje će imati vrednosti „bar“ i „qux“ respektivno.

Nizovi za renderovanje se keširaju. U zavisnosti od prirode vaših izračunatih vrednosti i komponente kojoj prikačujete drupalSettings, možda ćete morati da podesite metapodatke za keširanje u skladu sa tim.

Dodavanje atributa u script tagove

Ako želite da dodate atribute u script tag, morate dodati ključ atributa u JSON nakon URL-a skripte. Unutar objekta iza ključa atributa, dodajte ime atributa koji želite da se pojavi u skripti kao novi ključ. Vrednost za taj ključ biće vrednost atributa. Ako je vrednost postavljena na true, atribut će biti prikazan sam za sebe, bez vrednosti elementa.

Na primer:

 https://maps.googleapis.com/maps/api/js?key=myownapikey&signed_in=true&libraries=drawing&callback=initMap: {type: external, attributes: { defer: true, async: true, data-test: map-link } }

Ovo će proizvesti sledeći markup:

<script src="https://maps.googleapis.com/maps/api/js?key=myownapikey&signed_in=true&libraries=drawing&callback=initMap" async defer data-test="map-link"></script>

Isključivanje agregacije

Podrazumevano, više lokalnih fajlova će biti objedinjeno gde je moguće. Da biste isključili ovo za fajl, podesite njegov 'preprocess' flag na false.

cuddly-slider:
  version: 1.x
  js:
    js/cuddly-slider.js: {preprocess: false}
  dependencies:
    - core/jquery
    - core/drupalSettings

CDN / spoljne biblioteke

Moguće je koristiti JavaScript koji se nalazi na CDN-u (Content Delivery Network) radi bržeg učitavanja stranice. To se može uraditi deklarisanjem biblioteke kao „eksterne“. Takođe je korisno uključiti dodatne informacije o spoljnjoj biblioteci u definiciju.

angular.angularjs:
  remote: https://github.com/angular/angular.js
  version: 1.4.4
  license:
    name: MIT
    url: https://github.com/angular/angular.js/blob/master/LICENSE
    gpl-compatible: true
  js:
    https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js: { type: external, minified: true }

Inline JavaScript

Inline JavaScript se toplo ne preporučuje. Preporučuje se da stavite JavaScript u fajl koji želite da koristite inline, jer to omogućava keširanje JavaScript-a na strani klijenta. Takođe omogućava da JavaScript kod bude pregledan i napisan. Inline JS takođe može biti u sukobu sa politikom bezbednosti sadržaja na mnogim sajtovima i čini vaš modul nepodobnim za upotrebu na njima.

Inline JavaScript koji generiše markup

Ovo nije preporučljivo. Stavite JavaScript u fajl umesto toga. Primeri su reklame, dugmad za deljenje na društvenim mrežama, vidžeti lista društvenih mreža. Oni koriste inline JavaScript. Ali to je jednostavno specifična vrsta sadržaja/markup-a jer nisu namenjeni da ukrase sadržaj sajta ili interaktivnost, već da izvuku spoljašnji sadržaj preko JavaScript-a.

Želite da ih stavite u korisnički blok ili čak direktno u Twig šablon.

Na primer:

<script type="text/javascript"><!--
ad_client_id = "some identifier"
ad_width = 160;
ad_height = 90;
//--></script>
<script type="text/javascript" src="http://adserver.com/ad.js"></script>
<a class="twitter-timeline" href="https://twitter.com/wimleers" data-widget-id="307116909013368833">Tweets by @wimleers</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

Inline JavaScript koji utiče na celu stranicu

Inline JavaScript se toplo ne preporučuje. Primeri inline JavaScript-a koji utiču na celu stranicu su analitika (npr. Google Analytics) i usluge hostovanih fontova. Inline JavaScript koji utiče na celu stranicu može biti dve vrste: front-end/stilizacija ili logika. Većina ovih slučajeva može se zadovoljiti fiksnim JavaScript-om u fajlu plus dodatnim podešavanjima.

Za spoljašnji interfejs / stil (npr. hostovane usluge fontova) to spada pod temu, pa pogledajte „Dodavanje stilskih tabela (CSS) i JavaScript (JS) u Drupal 8 temu“.

U drugom slučaju JS pripada modulu. U odgovarajućem hook-u - najverovatnije hook_page_attachments() - definišite dodatke HTML koristeći ključ 'html_head' u svojstvu #attached:

function fluffiness_page_attachments(array &$attachments) {
  $attachments['#attached']['html_head'][] = [
    // Podaci.
    [
      '#type' => 'html_tag',
      // HTML tag koji dodajemo, u ovom slučaju 

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.