Drupal 8 թեմայում ոճային աղյուսակների (CSS) և JavaScript (JS) ավելացում
Այս փաստաթուղթը նախատեսված է թեմաների համար։ Մոդուլների մասին տեղեկությունները կարող եք գտնել «Drupal 8-ում CSS և JavaScript-ի ավելացում մոդուլում» բաժնում։
Drupal 8-ում CSS և JavaScript ֆայլերը բեռնվում են նույն համակարգով՝ մոդուլների (կոդի) և թեմաների համար՝ օգտագործելով ռեսուրսների գրադարաններ։
Հստակեցման համար՝ այս հրահանգները նախատեսված են ԱՊԱՀԱՏԵԼԻ միայն թեմաների համար և չեն կիրառվում մոդուլներում։
Drupal-ը գործում է բարձր մակարդակի սկզբունքով՝ ռեսուրսները (CSS կամ JS) բեռնվում են միայն այն ժամանակ, երբ դուք հայտնում եք Drupal-ին, որ դրանք պետք է բեռնվեն։ Drupal-ը չի բեռնում բոլոր ռեսուրսները յուրաքանչյուր էջում, քանի որ դա կնվազեցնի ինտերֆեյսի արագությունը։
Տարբերությունները Drupal 7-ից
Կարևոր 6 տարբերություն Drupal 7-ի համեմատ.
- THEME.info.yml ֆայլը փոխարինել է THEME.info ֆայլը (այսինքն՝ տվյալները նույնն են)։
- stylesheets հատկությունը (CSS ավելացնելու համար) THEME.info-ից հանվել և փոխարինվել է *.libraries.yml ֆայելով, որտեղ *-ը թեմայի կամ մոդուլի անունն է։
- scripts հատկությունը (JS ավելացնելու համար) THEME.info-ից հանվել է և նույնպես փոխարինվել *.libraries.yml ֆայելով։
- Բեռնվում են միայն CSS և JS ֆայլերը, որոնք պահանջվում են տվյալ էջում։ Օրինակ՝ jQuery-ն այլևս ավտոմատ չի բեռնվում, եթե այն հստակորեն չի հայտարարված *.libraries.yml-ում։ Եթե ձեր թեման կարիք ունի jQuery-ի կամ այլ ռեսուրսների, որոնք ցանկանում եք բեռնել բոլոր էջերում, դրանք պետք է ավելացվեն *.libraries.yml-ում և միացվեն THEME.info.yml-ում։
- Drupal 7-ում գրադարանները սահմանվում էին hook_library_info()-ով։ Այն փոխարինվել է *.libraries.yml ֆայլով։
- Drupal 8-ում drupal_add_css(), drupal_add_js() և drupal_add_library() հանվել են և փոխարինվել #attached մեխանիզմով։
Գործընթաց
CSS կամ JS ռեսուրսներ բեռնելու համար.
- Պահպանեք CSS կամ JS ֆայլերը՝ օգտագործելով համապատասխան անվանման և ֆայլերի կազմակերպման կանոնակարգերը։
- Սահմանեք «գրադարան», որը գրանցում է այդ CSS/JS ֆայլերը ձեր թեմայում։
- Միացրեք գրադարանները բոլոր էջերին, վատ Twig կաղապարներին կամ նախապատրաստման ֆունկցիաներում հատուկ էջերին։
Գրադարանի սահմանում
Սահմանեք ձեր բոլոր ռեսուրսային գրադարանները *.libraries.yml ֆայլում՝ ձեր թեմայի ֆոլդերում։ Եթե ձեր թեման կոչվում է fluffiness, ֆայլի անունը պետք է լինի fluffiness.libraries.yml։ Յուրաքանչյուր «գրադարան» ֆայլում մանրամասն նկարագրում է CSS և JS ֆայլերը, օրինակ՝
# fluffiness.libraries.yml
cuddly-slider:
version: 1.x
css:
theme:
css/cuddly-slider.css: {}
js:
js/cuddly-slider.js: {}
Այս օրինակով cuddly-slider.js և cuddly-slider.css ֆայլերը տեղակայված են համապատասխանաբար js և css թղթապանակներում։
Նշեք, որ սա ցուցադրում է միայն մեկ CSS և մեկ JS ֆայլի ավելացում։ Գրադարանների սահմանման բազմաթիվ տարբերակներ հասանելի են «Գրադարանների սահմանում. տարբերակներ և մանրամասներ» բաժնում։
jQuery-ի միացում ձեր գրադարանում
Նշեք, որ Drupal 8-ը այլևս չի բեռնում jQuery-ն բոլոր էջերում։ Եթե cuddly-slider գրադարանին անհրաժեշտ է jQuery, ապա պետք է հայտարարեք կախվածություն core/jquery գրադարանից։ Մոդուլները և թեմաները սահմանում են իրենց կախվածությունները ձևով «մոդուլ/գրադարան»։ Օրինակ՝
# fluffiness.libraries.yml
cuddly-slider:
version: 1.x
css:
theme:
css/cuddly-slider.css: {}
js:
js/cuddly-slider.js: {}
dependencies:
- core/jquery
Կախվածությունների հայտարարում
Կախվածություն հայտարարելու համար գրացեք ռեսուրս/գրադարանի ձևով։ Օրինակ՝ եթե new_library-ն կախված է core/jquery-ից, my_library-ը, սահմանված my_theme-ում, և my_library-ը, սահմանված my_module-ում, ապա դրանք պետք է նշվեն՝
# fluffiness.libraries.yml
new_library:
js:
js/new_library.js: {}
dependencies:
- core/jquery
- my_module/my_library
- my_theme/my_library
Մոդուլների և թեմաների անունները ապահովում են անունների տարածք գրադարանների համար՝ նույնանուն գրադարանները տարբերելու համար։
Գրադարանի միացում բոլոր էջերին
Շատ թեմաներ ունեն global-styling գրադարան՝ CSS ֆայլերի համար, որոնք պետք է բեռնվեն յուրաքանչյուր էջում։ Նույնը հնարավոր է անել JS ֆայլերի համար՝ global-scripts գրադարանով։
# fluffiness.libraries.yml
global-styling:
version: 1.x
css:
theme:
css/layout.css: {}
css/style.css: {}
css/colors.css: {}
global-scripts:
version: 1.x
js:
js/navmenu.js: {}
Նրանք պետք է ավելացվեն ձեր թեմայի info.yml ֆայլում (օրինակ՝ fluffiness.info.yml)՝ հասանելի լինելու համար բոլոր էջերում։
# fluffiness.info.yml name: Fluffiness type: theme description: 'A cuddly theme that offers extra fluffiness.' core: 8.x libraries: - fluffiness/global-styling - fluffiness/global-scripts base theme: classy regions: header: Header content: Content sidebar_first: 'Sidebar first' footer: Footer
Գրադարանի միացում Twig կաղապարում
Գրադարան կարող եք միացնել Twig կաղապարում՝ օգտագործելով attach_library() ֆունկցիան *.html.twig ֆայլում, օրինակ՝
{{ attach_library('fluffiness/cuddly-slider') }}
Some fluffy markup {{ message }}
Գրադարանի միացում որոշակի էջերին
Եթե ցանկանում եք գրադարանն ակտիվOnlyել որոշակի էջերում, օրինակ՝ որոշակի բլոկում կամ որոշակի տեսակի հանգույցի դիտման ժամանակ, կարող եք դա անել THEME_preprocess_HOOK() ֆունկցիայի միջոցով ձեր .theme ֆայլում՝ փոխարինելով THEME-ն ձեր թեմայի անունով, իսկ HOOK-ը՝ համապատասխան hook-ի անվամբ։
Օրինակ, JavaScript միացնելու համար սպասարկման էջին, օգտագործեք «maintenance_page» hook-ը՝ այսպես.
function fluffiness_preprocess_maintenance_page(&$variables) {
$variables['#attached']['library'][] = 'fluffiness/cuddly-slider';
}
Կարող եք նման բան անել ցանկացած այլ hook-ի համար, նաև կիրառել լոգիկա՝ օրինակ՝ որոշել, թե որ բլոկն է նախապատրաստվում կամ հանգույցի տեսակը։
Կարևոր նշում․ Այս դեպքում պետք է ապահովեք համապատասխան cache metadata՝ համապատասխան ձեր պայմաններին։ Վերը նշված օրինակը միշտ ավելացնում է գրադարան, ուստի cache metadata-ի անհրաժեշտություն չունի։ Եթե ցանկանում եք ավելացնել գրադարան կոնկրետ երթուղու վրա, օգտագործեք՝
function fluffiness_preprocess_page(&$variables) {
$variables['page']['#cache']['contexts'][] = 'route';
$route = "entity.node.preview";
if (\Drupal::routeMatch()->getRouteName() === $route) {
$variables['#attached']['library'][] = 'fluffiness/node-preview';
}
}
Գրադարանների սահմանում՝ տարբերակներ և մանրամասներ
CSS/JS ակտիվների համար հատկությունների ավելացում
Յուրաքանչյուր CSS/JS ֆայլին հնարավոր է հատկություններ ավելացնել՝ THEMENAME.libraries.yml ֆայլում ֆայլի անվան հետևում ավելացնելով JSON օբյեկտ։
CSS հատկություններ
| attributes | Ընտրովի հատկություններ։ Օրինակ՝ Bootstrap CDN-ի համար օգտագործվում է crossorigin ատտրիբուտը։ |
{ attributes: { crossorigin: anonymous } }
|
| browsers | Բեռնվում է պայմանով՝ ըստ բրաուզերի։ Այս մեթոդը օգտագործում է հատուկ մեկնաբանություններ, որոնք չեն աշխատում IE10 և բարձր վարկածներում։ |
{ browsers: { IE: 'lte IE 9', '!IE': false } }
|
| group | Ակտիվները խմբավորվում են SMACSS խմբերի մեջ։ Փորձնական հատկություն է։ |
Չափազանց քիչ է օգտագործվում |
| media | Մեդիա տեսակ (օրինակ՝ print) |
{ media: print }
|
| minified | Ակտիվը նախօրոք կրճատված է։ Պահանջվում է նշում։ |
{ type: external, minified: true }
|
| preprocess | Ակտիվները պետք է միավորվեն (աքսցեպտացվեն)։ Սովորաբար true է։ |
{ preprocess: false }
|
| type | Ակտիվի աղբյուր։ Սովորաբար ֆայլ է։ |
{ type: external, minified: true }
|
| weight | Պահանջվում է կարգավորել ակտիվների բեռնման հերթականությունը։ Թվային արժեք՝ -50-ից մինչև +50։ |
{ weight: 1 }
|
JS հատկություններ
| attributes | Ավելացվող JavaScript տարրերի ատտրիբուտներ։ |
{ type: external, attributes: { async: true } }
|
| browsers | Բեռնվում է պայմանով՝ ըստ բրաուզերի, ինչպես CSS-ում է։ |
{ browsers: { IE: 'lte IE 9', '!IE': false } }
|
| preprocess | Ակտիվների միավորումը։ Սովորաբար true է։ |
{ preprocess: false }
|
| type | Ակտիվի աղբյուր։ Սովորաբար ֆայլ է։ |
{ type: external, minified: true }
|
| weight | Խորհուրդ չի տրվում օգտագործել, կարգավորում է բեռնման հերթականությունը, պետք է լինի բացասական թիվ։ |
{ weight: -1 }
|
Գրադարանների վերաօգտագործում և ընդլայնում
*.info.yml ֆայլում կարող եք վերագրել *.libraries.yml-ում սահմանված գրադարանները՝ օգտագործելով libraries-override կամ libraries-extend մեխանիզմները։ Վերագրման մեջ նշված գրադարանները ժառանգվում են ենթաթեմերով։
stylesheets-remove հատկությունը *.info.yml-ում հնացած է և կհանվի Drupal 9.0.x-ում։ stylesheets-override-ը արդեն հեռացված է։
libraries-override
Վերագրումների դեպքում պետք է օգտագործել հետևյալ տրամաբանությունը՝
- Օգտագործեք մոդուլի (կամ կորի) անվան տարածքը գրադարանի անվան համար։
- Օգտագործեք վերջին վերագրումն իրականացնողի ճանապարհը որպես բանալին։
- Այն պետք է լինի ֆայլային համակարգի լիարժեք ուղի։
Օրինակ՝
libraries-override:
contextual/drupal.contextual-links:
css:
component:
/core/themes/stable/css/contextual/contextual.module.css: false
Այստեղ contextual/drupal.contextual-links-ը բազային գրադարանի անունն է, իսկ /core/themes/stable/css/contextual/contextual.module.css-ը վերջին վերագրումը ներկայացնող ֆայլի ամբողջական ճանապարհը։ Այս դեպքում ֆայլը անջատվում է՝ նշելով false։
Նշեք, որ միայն վերջին մասն է ֆայլային համակարգի ուղի, մնացածը անունների տարածքներ են։ css: և component: տողերը արտացոլում են գրադարանի կառուցվածքը։
Ֆայլային համակարգի ուղիղ կախվածությունները վատ փորձ են, քանի որ ֆայլերի տեղաշարժը կկոտրի դրանք։ Սրա փոխարինման համար առաջարկվում են հոսքային փաթեթավորողներ։
Ահա որոշ այլ օրինակներ libraries-override-ի օգտագործման՝ CSS կամ JS ֆայլերի կամ ամբողջ գրադարանների հեռացման կամ փոխարինման համար՝ թեմայի ժառանգած գրադարաններից․
libraries-override:
# Ամբողջ գրադարանի փոխարինում։
core/drupal.collapse: mytheme/collapse
# Փոխարինում ֆայլի։
subtheme/library:
css:
theme:
css/layout.css: css/my-layout.css
# Փոխարինում stable թեմայի ֆայլի։
contextual/drupal.contextual-toolbar:
css:
component:
core/themes/stable/css/contextual/contextual.toolbar.css: css/contextual.toolbar.css
# Փոխարինում Drupal-ի JS ֆայլի։
toolbar/toolbar:
js:
js/views/BodyVisualView.js: js/views/BodyVisualView.js
# Հեռացում ֆայլի։
drupal/dialog:
css:
theme:
dialog.theme.css: false
# Հեռացում ամբողջ գրադարանի։
core/modernizr: false
# Փոխարինում կոնկրետ ֆայլերի։
webform/webform.element.location.places:
css:
component:
css/webform.element.location.places.css: css/my-themes-replacement-file.css
js:
js/webform.element.location.places.js: js/my-themes-replacement-file.js
libraries-extend
libraries-extend-ը թույլ է տալիս թեմաներին ընդլայնել գրադարանները՝ ավելացնելով լրացուցիչ կախված գրադարաններ յուրաքանչյուր միացման ժամանակ։
Դա հարմար է որոշ կոմպոնենտների տարբեր կերպ ձևավորելու համար՝ առանց դա անելու գլոբալ CSS-ում, այսինքն՝ ձևավորել կոմպոնենտը առանց CSS բեռնելու յուրաքանչյուր էջում։
# Մեծացնելու drupal.user գրադարանը՝ ավելացնելով classy-ի օգտատերերի գրադարանները։
libraries-extend:
core/drupal.user:
- classy/user1
- classy/user2
Javascript-ի լրացուցիչ կարգավորում
Ակտիվների բեռնման հերթականություն
Ֆայլերը բեռնվում են նույն հերթականությամբ, ինչպես նշված են։ Սովորաբար բոլոր JS ֆայլերը բեռնվում են էջի ստորին մասում։ Եթե որոշ UI կոմպոնենտների համար JS-ի առկայությունը կենթադրենք կրիտիկական է և դրանք պետք է բեռնվեն հեդերում, ապա կարող եք օգտագործել հետևյալ ձևաչափը՝
js-header:
header: true
js:
header.js: {}
js-footer:
js:
footer.js: {}
header հատկության true արժեքը ցույց է տալիս, որ տվյալ JS ֆայլերը և նրանց կախված գրադարանները պետք է բեռնվեն հեդերում, ինչը նշանակում է, որ դրանք առաջնահերթ են բեռնման հարցում։
JavaScript-ի միացում
Երբեմն անհրաժեշտ է միացնել JavaScript, որը կախված է որոշ հաշվարկված PHP տվյալներից։ Այս դեպքում ստեղծեք JS ֆայլ, սահմանեք գրադարան և միացրեք այն, ինչպես նախկինում, բայց նաև միացրեք JS կարգավորումներ՝ օգտագործելով drupalSettings (որն այլընտրանք է Drupal 7-ի Drupal.settings-ին):
Օրինակ՝
cuddly-slider:
version: 1.x
js:
js/cuddly-slider.js: {}
dependencies:
- core/jquery
- core/drupalSettings
և
function fluffiness_page_attachments_alter(&$page) {
$page['#attached']['library'][] = 'fluffiness/cuddly-slider';
$page['#attached']['drupalSettings']['fluffiness']['cuddlySlider']['foo'] = 'bar';
}
որտեղ 'bar'ը որոշ հաշվարկված արժեք է։ (Ուշադրություն, այստեղ նույնպես անհրաժեշտ է cache metadata):
Դրանից հետո cuddly-slider.js կկարողանա կարդալ settings.fluffiness.cuddlySlider.foo, որը կլինի 'bar'։
(function ($, Drupal, drupalSettings) {
'use strict';
Drupal.behaviors.mybehavior = {
attach: function (context, settings) {
console.log(settings.fluffiness.cuddlySlider.foo);
}
};
})(jQuery, Drupal, drupalSettings);
Սցրիպտ տարրերի ատտրիբուտների ավելացում
Եթե ցանկանում եք ավելացնել ատտրիբուտներ script թեգին, պետք է ավելացնեք attributes բանալին JSON-ում JS ֆայլի URL-ի հետևում։
Օրինակ՝
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
Եվ դա կծառայի հետևյալ HTML-ին՝
Ներառյալ JavaScript
Ներառյալ JavaScript-ը շատ խորհուրդ չի տրվում։ Բարի կլինի այն տեղադրել առանձին JS ֆայլերում, ինչը թույլ է տալիս կլիենտի կողմից կեշավորել և հեշտ դիտարկել/խմբագրել կոդը։
Ներառյալ JS, որն ստեղծում է նշագծում սովորաբար պետք չէ։ Կարգավորեք JavaScript-ը ֆայլերում։ Օրինակ՝ գովազդներ, սոցիալական կոճակներ և տեսանյութերի վիջեթներ օգտագործում են ներառյալ JS, բայց դրանք պարզապես հատուկ տեսակի բովանդակություն են։
Կարելի է դրանք տեղավորել user block-ում կամ ուղղակի Twig կաղապարում։
Օրինակ՝
Tweets by @wimleers
JS, որն ազդում է ամբողջ էջի վրա
Ցանկացած նման JS օգտագործումը նույնպես խորհուրդ չի տրվում։ Օրինակ՝ Google Analytics-ը և ֆոնտերի սպասարկման ծառայությունները։
Եթե դա ինտերֆեյսի կամ ոճավորման համար է (օրինակ՝ ֆոնտեր), ապա JS-ը պետք է լինի թեմայի մաս, որը տեղադրվում է html.html.twig-ում, որպեսզի խուսափեք FOUT (Flash Of Unstyled Text) երևույթից՝ ապահովելով ֆոնտի նախաբեռնման արագությունը։
Եթե դա մոդուլային է, ապա նայեք «Drupal 8-ում CSS և JavaScript-ի ավելացում մոդուլում»։
Ներառյալ JS մոդուլային ինտեգրումում
Կտրականապես խորհուրդ չի տրվում օգտագործել ներառյալ JS։ Եթե հնարավոր է, օգտագործեք վերոնշյալ մեթոդները։
Եթե ունեք դաշտ, որն ընդունում է ներառյալ JS, ապա՝
- Դաշտը կամ ձևը պետք է ունենա համապատասխան թույլտվություն (permission)։ Օրինակ՝ MODULE.routing.yml-ում՝
MODULE.settings:
path: /admin/config/services/MODULE
defaults:
_title: 'MODULE settings'
_form: \Drupal\MODULE\Form\MODULESettings
requirements:
_permission: 'administer site configuration'
- Եթե արժեքը պահվում է կոնֆիգի մեջ, ապա պետք է նշեք CacheableMetadata, որպեսզի փոփոխության դեպքում կեշը թարմանա։ Օրինակ MODULE.module-ում՝
Markup::create($settings->get('js_code')),
'#cache' => [
'contexts' => ['user'],
'tags' => ['user:' . $user->id()],
],
];
// Add config settings cacheability metadata.
/** @var Drupal\Core\Render\Renderer $renderer */
$renderer = \Drupal::service('renderer');
$renderer->addCacheableDependency($page_bottom['MODULE'], $settings);
}
CDN / Արտաքին գրադարաններ
Որոշ դեպքերում կարող եք ցանկանալ օգտագործել JavaScript, որը գտնվում է CDN-ում (առաքման ցանց)՝ օրինակ՝ վեբ ֆոնտեր, որոնք հաճախ հասանելի են միայն արտաքին URL-ներով։ Դա արվում է հայտարարելով գրադարանը որպես արտաքին՝ նշելով type: external։ Հարմար է նաև ներառել տեղեկատվություն գրադարանի մասին։
(Կամ այն լավ պրակտիկա չէ գրադարաններ բեռնել CDN-ից, քանի որ ավելացնում է բազմանդամ վտանգներ՝ անվտանգություն, կատարողական և TCP/IP միացումների քանակ։ Այնուամենայնիվ, կողմնորոշիչ գրադարանները չպետք է պահվեն Drupal.org-ում ձեր ռեպոյում։ Սովորեք Drupal.org-ում արտաքին գրադարանների քաղաքականությունը։)
angular.angularjs:
remote: https://github.com/angular
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 }
Եթե ցանկանում եք, որ ձեր արտաքին ֆայլը բեռնվի նույն արձանագրությամբ, ինչ էջը, ապա օգտագործեք հարաբերական արձանագրության URL՝
js:
//ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js: { type: external, minified: true }
Կամ եթե ցանկանում եք ավելացնել CSS, օրինակ՝ Font Awesome ինտեգրում՝
font-awesome:
remote: https://fortawesome.github.io/Font-Awesome/
version: 4.5.0
license:
name: MIT
url: https://fortawesome.github.io/Font-Awesome/license/
gpl-compatible: true
css:
theme:
https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css: { type: external, minified: true }
Bootstrap CDN CSS-ի օրինակ՝ օգտատերային ատտրիբուտներով
bootstrap-cdn:
remote: getbootstrap.com
version: 4.0
license:
name: MIT
url: https://github.com/twbs/bootstrap/blob/master/LICENSE
css:
theme:
'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css':
type: external
minified: true
attributes:
crossorigin: anonymous
integrity: "sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"